Compare commits

...
Author SHA1 Message Date
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>morluto
a56f7bb668 chore(main): release rea-agents 6.4.0 (#1399)
* chore(main): release rea-agents 6.4.0

* docs(release): write contributor-aware 6.4.0 changelog

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 11:57:29 +08:00
morluto ee46323b49 fix(windows): preserve drive-root private runtime paths
Join the admitted parent and generated child name without duplicating a drive-root separator. Reuse that name for handle-relative creation and path provenance.

Add native snapshot, readback, and cleanup coverage through the Ghidra dot-prefixed temp fallback, plus a session-root contract regression.

Fixes #1690
2026-10-11 11:51:39 +08:00
morluto a99857df23 test(release): keep credits attached to their contribution 2026-10-11 11:51:17 +08:00
morluto 6b043dc3de fix(release): avoid duplicated contributor thanks 2026-10-11 11:49:49 +08:00
morluto 4003151ec1 fix(ci): allow browser runtime action transport latency 2026-10-11 11:45:46 +08:00
92dac97102 docs(website): add beginner help to the native analysis guide (#1689)
Add a short glossary, an analysis-tool chooser linked to native setup,
a note that REA does not include DX-Ball, and help for copying a file's
full path.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:43:06 -07:00
YsopwnableandGitHub 89ea2cad19 perf(domain): reuse canonical JSON key encodings
Reuse exact JSON key encodings within the existing 8,192-code-unit digest-buffer quantum and avoid ordinary member value frames. Preserve canonical bytes and cooperative yielding; resume objects when a pending property is omitted.

Flameox paired experiments establish a local digest-workload improvement, with complete-result/EvidenceID oracles unchanged. Full CLI acceleration and billed token reductions are not claimed.

Refs #1065.
2026-10-11 11:40:47 +08:00
ea06264a56 docs(website): list the setup guide first on the Guides page (#1688)
Move the "Set up REA" entry ahead of the native, JavaScript and browser
guides so new readers see setup before the worked examples.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:33:30 -07:00
morluto 59b4a3c319 test(windows): verify native addon in a renamed Node host 2026-10-11 11:32:07 +08:00
xeropresenceandGitHub ea1c164e5e fix(windows): load native controls in Node-API hosts not named node.exe (#1531)
fix(windows): resolve Node-API imports from the host executable

Delay-load the Node-API import library and bind "node.exe" to the running
process, matching node-gyp's win_delay_load_hook. The addon now loads under
any Node-API host (Node.js, Bun) regardless of its executable file name.
2026-10-11 11:30:41 +08:00
dc676b4d85 docs(website): add beginner help to the Get started page (#1684)
Add collapsible help sections for installing Node.js, choosing a coding
agent, opening a terminal, restarting a client, copying a folder's full
path and finding an Electron app's .asar file.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:27:12 +08:00
ad3e41d46e fix(browser): resolve XLink and SVG prefixes in XHTML dom_urls (#1683)
* fix(browser): resolve XLink and SVG prefixes in XHTML dom_urls

DOMSnapshot has no namespace URI. HTML documents still use the parser's
local names. In XHTML and other XML documents, resolve in-scope xmlns
declarations so an element is SVG only in the SVG namespace, and report
any XLink href as href when plain href is absent.

Refs #1586

* fix(browser): bound XML namespace resolution and reject cyclic ancestry

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 11:26:26 +08:00
YsopwnableandGitHub 17f704050f feat(evidence): discover retained records without full payloads (#1682)
* feat(evidence): discover retained records without full payloads

* fix(evidence): guide oversized results to retained discovery

* style(tests): format retained discovery recovery assertion
2026-10-11 11:18:26 +08:00
c8820e03db fix(apple): decode binary app Info.plist files without plutil (#1476)
* fix(apple): decode binary app Info.plist files without plutil

* test(apple): use Windows-legal names in the binary plist bundle test

* fix(apple): ignore __proto__ entries in binary app Info.plist files

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 11:14:15 +08:00
morluto ab80ec640a fix(ci): report package verifier stage progress 2026-10-11 11:11:38 +08:00
morluto 9ce6ef895e test: reuse stdio MCP server in acceptance file 2026-10-11 11:11:38 +08:00
morluto b3e977e6d0 fix(browser): bound screenshot comparison memory 2026-10-11 11:11:38 +08:00
morlutoandYou Wish a99b2fd3b5 test: retain focused CommonJS export regressions
Keep uncovered assignment and binding regressions in the shared CLI and MCP runtime oracle, with a POSIX escaped-path fixture.

Co-authored-by: You Wish <29498139+Y0UW1SH@users.noreply.github.com>
2026-10-11 11:07:15 +08:00
Rudy Celekliandmorluto 4e4b15b825 fix(browser): validate PNG chunks and preserve unsupported encodings
Validate chunk checksums, type bytes, ordering and end boundaries before pixel comparison. Distinguish malformed PNGs and corrupt DEFLATE streams from recognized unsupported encodings through CLI and MCP error projection.

Adapted from #1375 with additional decoder and public boundary regressions. Eighteen decoder tests and six compiled CLI/MCP cases passed.

Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 11:07:15 +08:00
morluto 21dbcf7a14 perf(cli): defer binary provider composition 2026-10-11 11:07:15 +08:00
Kaoru0822andmorluto 76296c5a38 fix(native): bind NativeAOT metadata to declared PE section extents
Section headers distinguish the declared virtual extent from the on-disk raw extent, which may include alignment padding. Resource RVA ownership and overlap use VirtualSize, falling back to SizeOfRawData when VirtualSize is zero, and payload reads still require file-backed bytes.

The NativeAOT snapshot reader applies the same range rule to RVA reads, metadata scans, executable targets, and derived overlay bounds. Page-rounded loader mappings may expose tail bytes, but those bytes lie outside the declared section range used by these parsers.
2026-10-11 11:07:15 +08:00
morlutoandYou Wish e38550462e test(native): stabilize resource-limited binary layout controls
Keep the configured launcher alive while its limited Python child runs so ownership checks retain the admitted executable identity. Trigger memory exhaustion with one oversized ELF zero-fill tail rather than racing section traversal against a timeout.

Adapted from #1357. JavaScript syntax, strict C syntax compilation, formatting, and static checks passed. The Linux pwntools verification lane was not run on this macOS host.

Co-authored-by: You Wish <29498139+Y0UW1SH@users.noreply.github.com>
2026-10-11 11:06:10 +08:00
morlutoandYou Wish 80896a1d64 fix(process): settle launcher exit without dropping descendant lineage
Refresh a mismatched launcher snapshot only when a new live process table proves its PID absent. Preserve uncertainty for detached descendants and continue checking ownership of surviving group members before signaling. Index retained lineage membership instead of rescanning it for each refreshed process.

Adapted from #1357. Validation: 71 source tests passed, one Linux-only identity case skipped; 32 real process-boundary tests passed on macOS.

Co-authored-by: You Wish <29498139+Y0UW1SH@users.noreply.github.com>
2026-10-11 11:06:10 +08:00
morluto e5bc4e85ec fix(ci): close speculative browser fixture connections 2026-10-11 11:05:08 +08:00
38221cb12e fix(native): bound PE resource RVAs by section virtual size (#1678)
The PE resource reader treated each section as covering
`max(VirtualSize, SizeOfRawData)` bytes, the mapping #1596 removed from
managed RVA reads. A resource payload in the raw alignment padding past
VirtualSize was reported with a hash of bytes the image loader never maps.
A later section whose virtual range starts inside that padding was refused
as an overlapping mapping.

Containment and overlap now use the loader's virtual extent: VirtualSize,
or SizeOfRawData when VirtualSize is zero. Ranges must still be file-backed.

Refs #1596

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:01:45 -07:00
3749ccec47 feat(ghidra): recover signed AArch64 relative jump tables (#1592)
* feat(ghidra): recover signed AArch64 relative jump tables

Generalise the AArch64 relative-table matcher to signed byte/halfword entries, UXTW indexes, byte or LSL #2 offsets, B.CS/B.HS bounds and a CBZ route for zero entries. Cross-check it against Ghidra's own load table when one exists, and add a fixture modelled on the RenderScript blend kernel.

Refs #487

* fix(ghidra): preserve typed labels for normalized switch selectors

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 10:45:35 +08:00
a67dbf6a48 fix: reject directory paths for the Wakaru limiter and mitmdump
`REA_JAVASCRIPT_PRLIMIT_COMMAND` and `REA_MITMDUMP_COMMAND` were admitted
after an access check alone, which a searchable directory passes. Admission
then succeeded, and the failure surfaced later as a launch-time adapter
error instead of the capability refusal that names the configured path.

Require a regular file, as #751 did for the firmware engine and limiter.
Linux-only tests mirror that change; both checks only run on Linux hosts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:43:48 +08:00
morlutoandClaude Opus 5.5 bd3a9bbbaf fix(native): classify PE resource input failures
Report missing and non-file selections as input issues, malformed PE images as format errors, and unstable reads as artifact changes. Keep existing limit, permission, cancellation, and other I/O classifications.

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

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:43:48 +08:00
morlutoandClaude Opus 5.5 74050978be fix(javascript): keep dependency manifests out of application roots
Select the shallowest inventoried nondependency manifest and retain dependency package evidence without assigning Electron entry roles. Keep the artifact root when no application manifest is observed.

Adapted from PR #1392, with compiled CLI and stdio MCP regressions for root selection and dependency-only inputs.

Co-authored-by: Marnix Pluim <marnixpluim@users.noreply.github.com>

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:43:48 +08:00
b212e92f9b ci: select semantic tests and fixture lanes for their guarded inputs (#1675)
Edits to `release.yml` or `real-ghidra-windows.yml` selected only the
workflow lane, so the shards holding releaseWorkflow, releaseCheckpoint
and realGhidraWindowsWorkflow tests were skipped. Actionlint checks
syntax only, so a PR could drop the package-before-publish gate, the
registry canary or the default-branch-only self-hosted runner restriction
without CI noticing.

Conformance fixture sources under tests/ set only the code lane, so the
conformance-fixtures and reconstruction-readiness jobs, the only callers
of `verify:fixtures` and `verify:readiness`, never ran for them. Route
the directories that build-conformance-fixtures.mjs compiles to both
lanes, and readiness applications to the readiness lane.

Both were raised by the Codex review of #1660 after it merged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:41:40 -07:00
morluto 990e1ad8c1 fix(browser): clear losing storage verifier timers 2026-10-11 10:35:42 +08:00
morluto 76d8f68cb9 feat(ghidra): inspect NativeAOT PE metadata read-only 2026-10-11 10:31:49 +08:00
fe574c0c9f fix(javascript): recover Electron APIs through default imports and optional calls (#1673)
`import electron from "electron"` bound the module with a leading `default`
export segment, so `electron.ipcMain.handle(...)`, `new
electron.BrowserWindow(...)` and destructuring from that binding matched no
Electron API. Electron's CommonJS exports define no `default` member, so the
segment can only denote the module object; drop it when classifying
Electron bindings.

The binding classifier already recorded optional-call roots, but the IPC,
context-bridge, utility-process and sender-validation visitors accepted only
plain calls. `ipcMain?.handle(...)`, `contextBridge?.exposeInMainWorld(...)`
and the common `event.senderFrame?.url.startsWith(...)` check were dropped
without a limitation.

Refs #1656

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:31:08 +08:00
3a7a3074e3 feat(javascript): recognize tRPC procedures and GraphQL operations (#1670)
* feat(javascript): recognize tRPC procedures and GraphQL operations

Record RPC client syntax as network endpoint candidates in both
analyze_javascript_application and analyze_web_bundle, distinguished by
mechanism:

- trpc:procedure:<method> keeps the static member path of
  root.<path>.<method>(...), which tRPC proxies preserve through
  identifier minification. React hooks and TanStack option factories are
  recognized directly. Vanilla query/mutate need a root bound to
  createTRPCClient/createTRPCProxyClient, or a tRPC source marker with a
  router path of at least two segments; subscribe needs the marker and a
  tRPC observer argument. `this` roots, browser globals and RTK Query
  `endpoints` chains are never procedures; cache-key helpers are excluded.
- trpc🔗<link> records the literal url of documented HTTP links.
- graphql:<type> records named operations from string and cooked template
  literals with a valid operation header, and from precompiled
  OperationDefinition objects; a graphql-tag loc.source.body copy is not
  reported twice.

Method, callback and factory names follow @trpc/client and React/TanStack
integration sources and documentation for 11.19. Carrier segments before
the router path, useUtils helpers and minifier-renamed links remain
documented limitations.

Validation: typecheck; domain tests for recognition and false positives
(Apollo, RxJS, stores, RTK Query, browser globals, prose); web bundle
analyzer test; end-to-end analysis of a minified fixture through the
built MCP server on Windows 11.

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

* fix(javascript): preserve RPC binding identity and bundled calls

* style(reference-source): fix CI formatting

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 10:28:52 +08:00
morluto 83e52559b8 style(reference-source): format loader binding changes 2026-10-11 10:20:04 +08:00
morluto 824ecf109d feat(release): add contributor-aware release notes workflow 2026-10-11 10:19:16 +08:00
morlutoandLucien 8b4c3de3b3 fix(browser): seed storage by browser partition
Co-authored-by: Lucien <1428823446@qq.com>
2026-10-11 10:17:53 +08:00
morlutoandRudy Celekli f998fcb1cc fix(reference-source): respect require bindings
Reuse lexical ownership to exclude shadowed require calls while retaining native CommonJS and direct createRequire bindings. Preserve candidate edges when JavaScript or TypeScript runtime mode is unknown.

Co-authored-by: Rudy Celekli <rudy@gradiahq.com>
2026-10-11 10:10:59 +08:00
morluto f88c99021b fix(ghidra): normalize Mach-O imported symbol names 2026-10-11 09:59:27 +08:00
You Wishandmorluto 49e6f00ed0 fix(ghidra): recover returning import callers 2026-10-11 09:59:27 +08:00
af88184eee feat(ghidra): configurable import language and analysis seeds (#1667)
* feat(ghidra): configurable import language and analysis seeds

REA_GHIDRA_LANGUAGE_ID and REA_GHIDRA_COMPILER_SPEC_ID set the import
language when the header cannot identify the compiler (for example,
Borland C++ PE images).

REA_GHIDRA_SEED_FILE seeds functions, code and labels before
auto-analysis, for code reached only through computed jumps or data.

Both are validated before launch, recorded in the analysis profile and
verified in the bridge handshake.

* fix(ghidra): parse language XML and preserve seed ordering

* test(ghidra): use explicit platform paths for seed launch checks

* fix(javascript): retain cleanup failure reason in error causes

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 09:57:38 +08:00
c1efa6467d feat(process): bound a finalization interval before forced capture timeout
Add optional finalization_ms to keep observing a captured root after SIGTERM, record the actual finalizer exit and each signal attempt, and escalate once when needed. Bind the initial root identity to captured ownership and preserve observations through cleanup uncertainty.

Fixes #1253.

Co-authored-by: Mykola Dementiev <16836724+nikolay-dementiev@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-11 09:55:43 +08:00
morluto 1e51c732bb fix(javascript): preserve CommonJS assignment result and receiver uncertainty
Resolve values returned by simple assignment chains at the export boundary. Suppress property links proven to target a detached receiver; retain unresolved links when reassignment may preserve receiver identity. Identify root assignments from their AST target rather than the displayed export name.

Validation: 25 semantic tests, seven targeted compiled CLI/MCP scenarios with Node runtime controls, build, and check:fast passed. Existing full acceptance suite passed before receiver refinements; the final changes were checked with targeted scenarios rather than repeating its 130-second run.
2026-10-11 09:47:41 +08:00
morluto 7956934965 fix(javascript): preserve getter receiver mutation aliases
Resolve this, private fields and super reads through receiver-aware references. Separate instance fields from prototype descriptors, preserve alternative inheritance branches and allow finite repeated getter paths.

Add domain precision regressions and compiled CLI/MCP coverage for the four reported getter shapes.

Fixes #1665
2026-10-11 09:46:53 +08:00
morluto db4e360846 fix(browser)!: preserve WebSocket connections and comparable payload coverage
Retain source URLs, empty connections, and ordered frame streams. Compare same-URL streams without relying on transient request IDs, and compare selected shapes and byte counts only through common known coverage. Malformed binary frames retain known metadata with an unknown byte count.

BREAKING CHANGE: inspect_web_page network.websocket_events is replaced by network.websocket_connections, whose records contain request_id, url, and events. Frame payload_bytes is nullable when decoding cannot establish its size. No legacy alias is retained.

Validation: 78 domain/browser/MCP focused tests, check:fast, docs:check, and real Chrome 154 CDP capture passed. Real capture retained six connections and twelve frames with source URLs and selected shapes. Full browser verifier was interrupted during an unrelated slow scenario stage; its assertions were exercised by the bounded capture proof.
2026-10-11 09:43:25 +08:00
morluto 7bb4ac219c fix(ghidra): reject conflicting address aliases in batches 2026-10-11 09:35:22 +08:00
morluto 3df67c640a fix(ghidra): isolate optional nativeaot script sources 2026-10-11 09:35:22 +08:00
morluto 044aa34ce6 perf(native): index call-binding parameter and return nodes
Build ordered per-procedure indices from admitted nodes instead of scanning every node twice for each call binding. Preserve edge order, capacity limits, omitted-parameter unknowns, and surviving return bindings.

Validation: five focused service tests and check:fast passed. Four paired Flameox blocks at 4096 call sites passed all eight full-result digest oracles. Median paired reduction was 183.02 ms (71.4%) on this synthetic fan-out workload; real-provider performance is unverified.

Flameox evidence: 5a4c98ed7d224587c10a0f4596c8680d3a0330eb112a629014448ff1ea4634e7.
2026-10-11 09:33:36 +08:00
morluto 31bfff6fdf perf(domain): order JSON shapes through their structural tree
Traverse sorted siblings instead of comparing complete shared path prefixes. Return the typed producer result directly while preserving independent path segments and schema validation at unknown-input boundaries.

Validation: 12 domain/CDP boundary tests, build, and check:fast passed. Six paired Flameox blocks retained identical full-output digests across deep, mixed, Unicode, and wide controls. Depth-512 inference median fell from 10.78 ms to 1.51 ms (120 samples per variant); whole harness median fell from 518.6 ms to 327.5 ms.

Flameox evidence: f4a93424f34e5bfea254ada4ef278dc9bbb6c21047c977e20da130e11a8899e9. Timings describe this bounded workload only.
2026-10-11 09:30:05 +08:00
morluto 026126eafe fix(artifacts): serialize ASAR snapshot ownership
Serialize preparation and close for each reader so concurrent callers share one owned snapshot. Preserve per-call cancellation and expected digest checks, cleanup retry ownership, and reuse after close.

Validation: 34 ASAR boundary tests, one fork-isolated snapshot race regression, test discovery, and check:fast passed.
2026-10-11 09:28:28 +08:00
YsopwnableandGitHub 29cc1b8746 fix(javascript): exclude overwritten Electron API identities (#1664)
* fix(javascript): exclude overwritten Electron API identities

* test(javascript): bind Electron in file-base path fixture

* test(electron): bind BrowserWindow in preload override fixtures

* test(mcp): allow cold catalog validation in runtime probe

* test(electron): bind APIs in option reconstruction fixtures
2026-10-11 09:25:32 +08:00
LuisandGitHub ad41afa2b5 fix(setup): recognize Omarchy as an Arch-based host (#1662) 2026-10-11 09:23:39 +08:00
morluto 69a8b3a954 fix(ghidra): expose terminal-call boundary assumptions
Preserve observed terminal-call sites and callee flags across function views, raw bridge responses, Evidence, and snapshot replay. Version analysis profiles so older unqualified results cannot be reused.

Qualify Ghidra function extents without changing external no-return flags or claiming recovery of excluded code.

Validation: 76 focused tests, check:fast, docs:check, formatting, and the full Ghidra 12.1.4 host lane pass. Real CLI and all five stdio MCP function views retain the terminal-call evidence; returning puts calls remain unflagged. The reported stripped Rust ELF and Windows host remain unverified.

Fixes #1658
2026-10-11 09:08:01 +08:00
morluto 4733fc810a fix(ghidra): qualify defined-string search coverage
Carry defined-data scope through list and search Evidence and bind it into the analysis profile so older snapshots cannot replay unqualified results. Clarify the tool contract and document known-address byte/reference inspection.

Validation: 36 focused tests, check:fast, docs:check, and real Ghidra 12.1.4 CLI/stdio MCP on macOS arm64. The Rust Mach-O fixture contains the phrase and Ghidra defines it; the reported Linux ELF omission was not reproduced.

Fixes #1659
2026-10-11 08:51:02 +08:00
morluto d21132fc97 fix(ci): format Electron IPC verification assertion 2026-10-11 08:34:22 +08:00
morlutoandGitHub 66c344e289 ci: scope provider and native verification by changed inputs (#1660) 2026-10-11 08:31:27 +08:00
morluto 28bd0d990a test(electron): verify aliased APIs against a real IPC round trip
Extend the existing real Electron public-tool fixture with assignment aliases for BrowserWindow, contextBridge, ipcMain, and ipcRenderer. Assert exact static recovery counts and observe the handler invocation after a real click.

Verified the public CLI/stdio MCP fixture, IPC invocation, cancellation, and owned-process cleanup against checksum-verified Electron 43.3.0 on macOS ARM64. Build and check:fast pass. The separate readiness reload/crash scenario still fails on a destroyed execution context; this commit does not claim the full verify:electron lane passes.
2026-10-11 08:30:09 +08:00
morluto 2612e474b6 fix(javascript): recover Electron API identity through aliases
Reuse semantic module provenance for aliases and keep property path segments intact through Electron matching. Reject shadowed names and nested or dotted lookalikes. Reassigned and conditionally initialized module origins remain ambiguous, with their source origins retained.

Add a compiled CLI/stdio MCP regression for windows, preloads, context bridges, IPC operations, pairing, and source ranges. Validate 771 JavaScript domain tests, seven composition tests, the public acceptance workflow, build, and check:fast.

Fixes #1656
2026-10-11 08:27:46 +08:00
morluto a11fbc0df9 fix(ci): format JavaScript getter mutation regressions 2026-10-11 08:20:39 +08:00
morluto 639b73097b fix(javascript): preserve getter results on direct property writes
Replacing or deleting a class getter property does not mutate the object it would return. Apply the existing object-accessor write boundary to instance and static getters.

Validation: source mutation regressions and compiled CLI/stdio MCP acceptance preserve literal 1 for all four assignment/deletion cases; check:fast passes.
2026-10-11 08:15:47 +08:00
morluto bb074d84cb perf(javascript): reuse cycle sets during semantic evaluation
Track active bindings with per-evaluation push/pop instead of copying ancestor sets on every alias. Restore membership in finally so cycles and sibling branches keep their existing semantics.

Validation: 173 domain tests, compiled CLI/stdio MCP returned-reference acceptance, and check:fast pass. A randomized six-block Flameox experiment retained identical complete semantic output and reduced the bounded 112-alias analyzer median from 36.33 ms to 17.00 ms.
2026-10-11 08:14:45 +08:00
morluto 204e2c42a1 fix(ci): register Termux browser verifier as Knip entry point 2026-10-11 08:13:41 +08:00
tyloryangGitHubtyloryang <[邮箱]>morluto
87edf14940 fix(browser): support Termux Android scenarios (#1655)
* fix(browser): support Termux Android scenarios

* fix(build): lock Termux artifact generation

* ci(android): add manual Termux browser smoke verification

---------

Co-authored-by: tyloryang <[邮箱]>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 08:10:06 +08:00
YsopwnableandGitHub 890dfa49f6 fix(javascript): preserve cleanup failures during preparation cancellation (#1654) 2026-10-11 08:05:08 +08:00
morluto bc7846db91 fix(javascript): track references returned by getters
Follow object, instance, and static getter results when invalidating shared values. Respect descriptor replacement, known spread overrides, inheritance alternatives, and unresolved computed keys. Preserve conservative uncertainty for fresh getter results and verify shared mutations through CLI and MCP.

Fixes #1494
2026-10-11 08:03:17 +08:00
morluto 5485483f7d fix(javascript): preserve exact CommonJS export keys
Retain literal property keys as member segments, omit unresolved computed keys, and distinguish nested writes from dotted export names. Preserve empty keys and omit object-literal prototype setters. Verify bundler observations through Node, CLI, and MCP consumers.
2026-10-11 07:59:47 +08:00
morluto c916850852 fix(process): release terminals after observation failures
Keep queued observation failures available through frames while allowing the resource owner to release xterm and its owned addons. Catch write-callback failures so cleanup cannot hang, and retain actual disposal failures for retry.
2026-10-11 07:47:33 +08:00
morluto 26038912f6 fix(javascript): preserve cancellation during worker preparation 2026-10-11 07:36:39 +08:00
morluto aa7c5b7b5e fix(ghidra): reject address names owned by another symbol
Check function and label ownership in the existing namespace before renaming. Keep same-address renames idempotent and reject duplicate batch members inside their individual transactions. Extend real-provider namespace checks for single and batch collisions without conflating function and label fixture names.

Validation: real Ghidra 12.1.4 host-native verification passed on macOS ARM64 with JDK 21.0.12.1, including public CLI/stdIO MCP, qualified-name round trips, rollback, source-byte immutability, and complete cleanup. Windows mutation authority remains unchanged.

Fixes #1649
2026-10-11 07:35:48 +08:00
morluto 095fad9406 Merge remote-tracking branch 'origin/main' 2026-10-11 07:32:50 +08:00
morluto 8b2f8514c5 fix(javascript): ignore bare CommonJS exports rebinding
Assigning a new value to the exports alias does not replace module.exports. Stop inventing a default export link and definite return-shape changes for that assignment.

Validation: 22 semantic structure source tests and 49 compiled CLI/MCP acceptance tests passed. The new regression checks Node require returns an empty export object for both versions and both adapters report missing defaults without definite changes.
2026-10-11 07:30:52 +08:00
morluto c57e759ae6 fix(browser): bypass desktop keyrings in verification fixtures
Use password-store=basic for owned raw Chrome verification processes and document the same option for dedicated caller-owned Linux investigation profiles. Locked keyrings can stall navigation and leave placeholder frame URLs; keep the existing committed-URL authorization boundary.

Validation: real Chrome 154 CLI and stdio MCP browser verifier passed on macOS ARM64, plus docs freshness and check:fast. The locked Linux desktop keyring environment was not reproduced locally.
2026-10-11 07:30:25 +08:00
morluto 7b25a73ac4 fix(browser): bound CDP messages by the shared budget
Apply the 64 MiB protocol message limit when connect callers omit an override. Reject invalid explicit limits, including values that wrap through ws signed 32-bit coercion and disable enforcement. Preserve the typed payload_limit reason through disconnect and later commands.

Validation: 16 transport boundary tests passed, including UTF-8 exact/+1 limits and an oversized frame header without allocating its body. Real Chrome 154 CLI/MCP browser verification and check:fast passed. This caps message bytes, not decoded JSON heap size.
2026-10-11 07:30:14 +08:00
morluto aa257ea4b1 fix(browser): decode source-map response framing
Share the ECMA-426 JSON parse view across fetched maps and local point tracing while retaining exact response text, bytes, and digest. Handle BOM and HTTP newline variants without treating unterminated prefixes as valid JSON.

Validation: 89 source-map tests passed; source/runtime build and check:fast passed. Real Chrome 154 CLI and stdio MCP browser verification passed on macOS ARM64.
2026-10-11 07:29:51 +08:00
YsopwnableandGitHub 4999e4be2c fix(javascript): isolate source analysis and retain bounded partial evidence (#1651)
* refactor(javascript): validate transferable file projections

* test(javascript): consume decoded module and static facts

* fix(javascript): isolate source analysis and retain bounded partial evidence

* test(javascript): verify cleanup retention and repeated source paths
2026-10-11 07:22:50 +08:00
morluto 92cc0edd8e docs(setup): identify Qwen and OpenCode release gaps
Document the npm 6.3.0 boundary beside Qwen registration and OpenCode configuration override workflows. Registry metadata still identifies 6.3.0 as latest; source support requires publication and actual registry-package verification before issue closure.

Refs #1650.
2026-10-11 07:10:46 +08:00
morluto 573598c632 fix(artifacts): reject Windows stream paths before extraction
Validate Windows destination representability at the writer before registering or creating any entry. Preserve literal logical names in inventory and POSIX output. Refuse NTFS alternate stream syntax with typed path evidence and roll back prior extracted files.

Return producer path diagnostics directly, removing the presentation layer English-prefix classifier. Verify stream leaf/parent syntax, input stream cleanup, extraction rollback, inventory fidelity, POSIX materialization, and error projection: 63 passed, one platform-specific skip. Native Windows execution remains unverified here.

Fixes #1574. Adapted from and supersedes #1575.
2026-10-11 07:10:45 +08:00
morluto 8d3cfef753 fix(plist): disclose binary prototype-key omissions
Reuse the bounded binary preflight to observe dictionary keys before the pinned decoder drops them. Keyed archive results disclose the omission and Interface Builder marks archive decoding partial. XML keeps its existing exact counts; binary reporting deliberately leaves the count unknown because overwritten subtrees and decoder projection can change visibility.

Remove the superseded size-only preflight contract. Cover ASCII, UTF-16 and extended lengths, shared references, nested and shadowed dictionaries, and the value-only negative control. Synthetic plist and filesystem fixtures; no plutil or ibtool verification.

Fixes #1594. Supersedes #1593.
2026-10-11 07:02:39 +08:00
morluto 975dff2e25 fix(dotnet): bound RVA reads by section virtual size
Use the shared resolver for virtual containment, overlap checks, and file-backed extent. Raw alignment padding no longer supplies method bytes or shadows a later virtual section. Preserve malformed body coverage and suppress CIL hashes outside the admitted range.

Verify zero, exact-end, truncated-body, padding, and true-overlap cases through compiled CLI and MCP consumers. Synthetic PE fixtures only; no Windows loader or real managed-provider verification.

Fixes #1596. Supersedes #1595.
2026-10-11 07:02:16 +08:00
morluto 1b527f4898 fix(ci): share runtime fixtures and allow modest duplication headroom 2026-10-11 06:53:20 +08:00
YsopwnableandGitHub b09dd333ab fix(tests): separate Copilot model IDs from wire models (#1647)
* fix(tests): separate Copilot model IDs from wire models

* fix(tests): inspect parsed reference import diagnostics
2026-10-11 06:52:45 +08:00
morluto 60fbb2f06e fix(install): share arguments between the plan and npm execution
Include the Linux user prefix in the planned command. Build the install
arguments once and shell-escape the printed arguments so paths with spaces
or metacharacters remain reusable. Cover dry-run admission, exact argument
round-trip and the unprefixed macOS command with native Bash 3.2.

Refs: #1417
2026-10-11 06:41:51 +08:00
morlutoandFazmin 8b4c96e6c6 fix(cli): preserve native option descriptions in help
Keep the optional address description visible to incur and describe the actual
bundle plist default and absolute-path support. Extend the existing command
help sweep instead of traversing the inventory a second time.

Refs: #1418
Co-authored-by: Fazmin <fazmin.nizam@gmail.com>
2026-10-11 06:41:46 +08:00
morluto 95a77b6e25 fix(web)!: retain capture read cleanup through export
BREAKING CHANGE: WebScriptExportError accepts error context and residual paths in an options object.
2026-10-11 06:30:56 +08:00
morluto 67966c69a5 fix(setup): retain client configuration cleanup owners 2026-10-11 06:30:56 +08:00
morluto 279c942fe1 refactor(reference): consolidate Git metadata cleanup 2026-10-11 06:30:56 +08:00
morlutoandGitHub 54e2890b30 fix(ci): check decoded reference paths and restore formatting (#1648)
* style(browser): format cached SVG ancestry check

* fix(tests): assert decoded reference-source error paths
2026-10-11 06:29:26 +08:00
0f605bca09 fix(browser): report SVG xlink:href links in dom_urls (#1602)
* fix(browser): report SVG xlink:href links in dom_urls

DOM snapshots have no namespace URI, so SVG context is an svg ancestor
outside foreignObject. When href is missing, report xlink:href as href
with the same base URL and origin policy.

Fixes #1586

* fix(browser): cache SVG ancestry during DOM capture

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 06:23:07 +08:00
Immanuel TikhonovandGitHub 423b11c8ef fix(javascript): preserve trailing slash in package directory requests (#1615) 2026-10-11 06:23:05 +08:00
FengandGitHub 52331ab637 fix(setup): preserve configured MCP server environment (#1607)
* fix(setup): preserve configured MCP server environment

* fix(setup): validate retained server environment before writes
2026-10-11 06:23:02 +08:00
akushonkamenandGitHub 3e931a7e35 fix(browser): fold loopback spellings into one attach admission key (#1604)
A CDP endpoint serves every loopback stack on one port, but the attach
admission key was built from the endpoint origin string, so scenarios
attaching through http://127.0.0.1:PORT and http://[::1]:PORT produced
two lease keys, passed admission in parallel and the browser rejected
the second client. Collapse literal loopback hostnames to one identity
in the lease key (port and target still partition it) without touching
endpoint validation.

Validation: npx vitest run src/browser/PlaywrightScenarioBrowser.test.ts (9 passed; the two new loopback tests failed before the fix), npx vitest run src/browser src/domain (1745 passed, 2 failed, both failing on pristine main), npm run test:fast (3896 passed, 12 failed, 7 skipped; the failure set is identical on pristine main at 3894 passed), plus typecheck, oxlint, oxfmt and resolved module-boundary verification.
2026-10-11 06:22:59 +08:00
AdolaniumandGitHub 6edd5cf045 fix(browser): keep declared scenario secrets out of redacted evidence (#1590)
A redaction marker such as [REDACTED:password] can contain the secret it replaced, and the byte replacer never scanned the marker it inserted. Cookie names, domains, paths, and storage keys were also stored raw. Choose a marker that does not contain a declared spelling, drop the result when a spelling remains, and redact storage identity fields.
2026-10-11 06:22:57 +08:00
1a6ccec636 fix(browser): skip Windows Electron signals without verified lineage (#1588)
capture_electron_scenario called taskkill on the recorded leader PID before lineage could be verified. On Windows the process table is empty, so that proof never arrives and the signal still ran. Refuse the cleanup without signaling. A verified lineage still terminates the leader and its descendants.

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 06:22:54 +08:00
Luis ArayaandGitHub afc9d819aa test(android): preserve reason in JADX cleanup-failure teardown poll (#1639) 2026-10-11 06:22:51 +08:00
Luis ArayaandGitHub 7b3011b41e fix(tests): bind HOME in native client and deepseek verifiers (#1638) 2026-10-11 06:22:48 +08:00
6849ecf70a docs(installation): clarify that npm 6.3.0 excludes automatic pi and hermes setup (#1637)
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 06:22:37 +08:00
morluto 926c2d6ba7 test(ghidra): preserve metadata in interior-label fixture
Place the imported control label inside a valid multi-byte NOP instead of suppressing Mach-O function-start metadata. Encode the supported ARM64 and x86-64 instructions explicitly and retain the load dependency so the control remains past the function entry. Assert that Ghidra imports a label and no procedure at the control address before checking name rejection and address containment.

Two real arm64 Ghidra 12.1.4 imports confirmed both fixture strategies produce labels; only default linking retains LC_FUNCTION_STARTS. The full native-value CLI/MCP verifier passed with 349 successful and 52 expected rejected boundary calls, including imported aliases, complete exports, and startup cancellation cleanup. Host ARM64 and Apple x86-64 fixture compilation passed; x86 provider execution remains unverified.
2026-10-11 06:10:10 +08:00
morluto c7345512ea perf(native): index admitted value-trace nodes
Replace a graph-wide node scan for each parameter use with membership in the set of admitted node IDs. Preserve node-budget omission, pagination, and existing ID-collision behavior.

Flameox profiles identify the eliminated scan. Six-run medians on a bounded synthetic four-procedure workload improved from 2538.17 ms to 220.32 ms (11.52x); full JSON responses have identical SHA-256 4071fc7ec17be01e6a23d53814a47b3b1bb0ebd80099d21ef8431da487801725. This measures production trace composition with a synthetic provider, not real Ghidra target speed.

External design research through DeepWiki was checked against Ghidra 12.1.4 DataGraph: https://github.com/NationalSecurityAgency/ghidra/blob/8b6bbb857accdfa20dc5b2f5dea471178c2e9fbc/Ghidra/Features/CodeCompare/src/main/java/ghidra/features/codecompare/graphanalysis/DataGraph.java
2026-10-11 06:10:10 +08:00
morluto 53e7fadbd0 fix(reference)!: retain source and metadata cleanup owners
Require a caller-owned artifact resource scope for source traversal and Git metadata reads. Preserve cancellation, filesystem reasons, partial entries and bytes, and cleanup observations through import and the CLI. Transfer exact failed file owners at regular-file admission and close boundaries, including multiple failures encountered by Git reference resolution.

Validation: 169 focused tests passed across 26 files; two Windows-only cases skipped. Build, typecheck, lint, formatting, knip, architecture guards, discovery and docs checks passed.

BREAKING CHANGE: Reference source readers and imports require an ArtifactResourceScope. VCS metadata reads return Result, and CLI import failures include observed details and partial evidence.
2026-10-11 06:10:10 +08:00
morluto 215001a1ce refactor(filesystem): share directory cleanup ownership
Reuse the existing directory close state machine for artifact and reference readers. ArtifactResourceScope can retain the exact directory owner when cleanup fails.
2026-10-11 06:10:10 +08:00
YsopwnableandGitHub 9515d2fcd3 fix(tests): verify Qwen skills through an isolated native home (#1646) 2026-10-11 06:05:57 +08:00
YsopwnableandGitHub ac9677bd6c fix(test): preserve Ghidra interior-label controls on Mach-O (#1640)
* fix(test): preserve Ghidra interior-label controls on Mach-O

* test: preserve selector semantics and accept signaled fixture exits

* test(javascript): exercise deep returns through the public CLI
2026-10-11 05:45:00 +08:00
morluto 69fe5b6010 perf(javascript): index structured observations by path
Build package, JSON-module and source-map indexes once instead of rescanning every observation list per file. Preserve first-observation lookup semantics when paths repeat and share each JSON lookup with the file projection.

Validation: duplicate-observation consumer regression and reconstruction suites. Flameox captured before/after CPU profiles on 3,000 JSON files; the complete CLI output stayed byte-identical. Exploratory samples do not establish an end-to-end timing improvement.
2026-10-11 05:33:21 +08:00
morluto 684199ba0b fix(javascript)!: retain nested artifact readers in caller scopes
Require the caller artifact resource scope when reading JavaScript artifacts. Transfer failed nested ASAR cleanup to that scope so later work retries the same owner before admission. Preserve traversal failures and attempt every remaining iterator during unwind.

Validation: reconstruction, integrity, content identity, cancellation and nested-reader cleanup boundary checks.

BREAKING CHANGE: readJavaScriptArtifactFiles now requires ArtifactResourceScope as its third argument; the optional abort signal is fourth.
2026-10-11 05:33:15 +08:00
morluto a17e257f43 fix(artifacts): preserve failures while unwinding nested traversals
Finish every remaining iterator from inner to outer, retaining cleanup observations without replacing the original traversal failure. A real nested ASAR regression reproduces the previous integrity-error masking.
2026-10-11 05:33:14 +08:00
morluto 5502ca9c97 fix(artifacts): retain reader owners after cleanup failures
Keep directory handles under explicit close ownership and retain ZIP and Mach-O admission owners when initialization or cleanup fails. Preserve cancellation and primary failure details, and avoid false successful release after native handle invalidation.

Validation: filesystem ownership, FIFO, archive and reconstruction boundary checks; static and architecture checks; real macOS CLI/MCP bundle workflows. Windows native behavior was not verified.
2026-10-11 05:33:05 +08:00
morluto be75ed5e4b fix(publication)!: retain cleanup owners across export workflows
Require an ArtifactResourceScope for web script exports and share its lifetime with CLI or MCP shutdown. Retain setup-failed output trees in firmware and Wakaru providers. Preserve completed publications when descriptor cleanup fails, returning the full result after a successful retry or as a partial observation while cleanup remains unresolved.
2026-10-11 05:17:10 +08:00
morluto 3f8c51e9b5 fix(artifacts): retain output ownership through publication failures 2026-10-11 05:17:10 +08:00
morluto e0e49e9dd5 fix(artifacts)!: keep streamed reads within descriptor ownership
Use bounded positional reads for unpacked ASAR members and borrowed Mach-O slices so destroying a stream cannot bypass its descriptor owner. Retain uncertain ASAR closes and preserve borrowed sources after cancellation.

BREAKING CHANGE: Injected ASAR unpacked handles expose fd and read instead of createReadStream.
2026-10-11 05:17:10 +08:00
morluto be6272f261 fix(artifacts)!: preserve descriptor cleanup authority
Keep rejected closes unresolved after descriptor invalidation and share concurrent close attempts. Preserve primary admission failures and transfer the exact failed handle owner into inventory scopes.

BREAKING CHANGE: ArtifactResourceScope file-handle owners require OwnedFileHandle. Root inventory sources retain their single cleanup owner.
2026-10-11 05:17:10 +08:00
clydeandGitHub 32d13c431e test(javascript): retain resource ownership in deep-return fixture (#1644) 2026-10-11 05:16:03 +08:00
morluto 0fa0b04628 fix(electron): check Windows lineage before process cleanup
Return an unverified cleanup failure before invoking numeric process-tree termination when owned lineage is unavailable. Preserve the partial capture and existing cleanup diagnostics.

Exercise the provider capture boundary with stable application-state observations; assert no Windows cleanup call and retained partial Evidence. Source tests pass; native Windows behavior was not verified.
2026-10-11 04:43:02 +08:00
morluto ffe0574e17 fix(artifacts)!: retain cleanup owners through client shutdown
Keep failed reader, root descriptor, and output-tree cleanup with the caller. Drain admitted work before close, retry the same retained owners, and block new resource work while cleanup is incomplete. Preserve primary failures and complete inventory observations.

Thread ownership through JavaScript reconstruction, the CLI's one-shot scope, MCP server shutdown, verifier scripts, and test fixtures. Remove redundant ownership flags and the unused validated test wrapper.

Validate with 850 passing focused tests across 90 suites (two skipped), targeted classification and cleanup retries, static and unused-code checks, and real macOS CLI/MCP directory, ZIP, and DMG workflows. Native Windows and deep-analysis providers were not verified.

BREAKING CHANGE: Direct artifact inventory/extraction and JavaScript analysis APIs require an explicit caller-owned ArtifactResourceScope. CLI and MCP input contracts are unchanged.
2026-10-11 04:43:02 +08:00
morluto 87d5ec93d5 perf(javascript): index native Evidence links by observed digest
Build each side's digest-to-Evidence index once instead of scanning native observations for every comparison item. Retain every exact match and avoid linking subjectless Evidence to nodes lacking content identity.

Comparison and relationship regressions pass. Isolated alternating unprofiled runs at 2,000 nodes and observations per side have conventional medians 379.924 ms before and 246.466 ms after; the complete 4,000-item outputs match byte-for-byte. Timings are bounded workload evidence, not whole-suite performance.

Flameox profile: flameox://evidence/7dca714833dc3d254a75704670a81de656b4b31d4b77a72236eecb82459b3d86
2026-10-11 04:43:02 +08:00
morluto f1c58cc53f fix(reference): reject FIFO replacements without blocking
Use the shared nonblocking, no-follow regular-file opener at the source-read boundary and report a nonregular replacement as changed. Keep descriptor identity and extent checks.

The compiled subprocess regression timed out on the baseline and completes without a FIFO writer after this change. Reference reader failure, capacity, cancellation, and import checks pass.
2026-10-11 04:43:02 +08:00
morluto 6636045c9c fix(reference): match exclusions against observed entry kinds
Inspect each entry without following links before applying directory-only patterns. Retain the winning rule and original entry path while pruning excluded directories before reading their children.

Validate directory exclusions, negation, symlinks, explicit secret rules, and compiled CLI provenance alongside reference reader failure and cancellation coverage.
2026-10-11 04:43:02 +08:00
YsopwnableandGitHub b74d9a1bb2 fix(onboarding): isolate client homes and clarify npm release support (#1627)
Bind HOME and USERPROFILE in disposable native client verifiers, exercise default personal skill discovery, and clarify automatic Pi/Hermes setup availability in the checked npm release.

Validation: integrated build/static/docs checks, repeated native client workflows, real Codex-backed client trials and two independent cold-npx Codex installs. All 19 CI checks passed on a7ba07ba. Other model providers, platforms and deep-analysis engines retain their explicit verification TODOs.
2026-10-11 04:37:31 +08:00
6e0d5d64d3 feat(ghidra): admit set_address_name and set_addresses_names (#1635)
* feat(ghidra): admit set_address_name and set_addresses_names

Ghidra sessions rejected the existing naming tools with "operation is not declared by this provider", so agents had to use annotate_native_function, which returns a complete function dossier per rename and cannot name data addresses.

The Java bridge now names a local function entry (namespace-aware, like annotate_native_function) or creates/renames the primary label at any other mapped address, verifying readback. set_addresses_names applies each address in its own transaction and reports per-address booleans. Both are mutating capabilities: excluded from read-only (Windows P0) handshakes and from snapshot replay.

* fix(ghidra): normalize qualified symbol names and reject empty leaves

Share namespace-aware leaf normalization across functions and primary labels. Invalid qualified leaves now return false for naming operations without marking the provider unavailable; function annotations retain typed invalid-input errors.

Extend real CLI/MCP namespace verification with namespaced globals, readback replay, failed-name rollback, mixed batches, and capability checks.

Validation: 75 focused tests and npm run check pass. Ghidra 12.1.4/JDK 21 namespace verification passes on macOS arm64 with unchanged source bytes and complete cleanup. The full host lane passes this workflow before the existing entry-alias fixture fails because the compiler places its interior label at the function entry.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-11 04:35:38 +08:00
YsopwnableandGitHub d6f698d8af fix(ghidra): admit carved MIPS ELF with incomplete section tables (#1629)
* fix(ghidra): inspect carved MIPS ABI declarations without missing sections

* test: share filesystem fixtures and cleanup assertions
2026-10-11 04:33:05 +08:00
morluto bbd01923e9 fix(artifacts): own DMG readers before attachment
Make inventory reader construction synchronous and DMG attachment lazy, so the inventory registers its reader before native operations start. Share initialization, reject work after close, wait for an in-flight attach before cleanup, and preserve retryable close state.

Cover failed-attach inventory cleanup, concurrent initialization, close-before-use, and close-during-attach alongside existing ownership, cancellation, and integrity cases. Session-level retention after inventory cleanup failure remains a separate concern.
2026-10-11 04:15:26 +08:00
morluto 5a77a962ec perf(reference): size read buffers from admitted file lengths
Use the descriptor size to bound each allocation, with a one-byte EOF probe, and stop on observed growth. Retain short-read, cancellation, and final identity validation.

A 2,001-file benchmark requests 4,200,307 bytes instead of 266,469,376 with the same captured-byte digest. Flameox shows filesystem waits dominate, so this is an allocation reduction without a CPU speedup claim.
2026-10-11 04:15:26 +08:00
morluto 6585293c56 fix(reference)!: preserve exclusion rule provenance
Record the exact matching pattern and distinguish project, default, caller, and configured-sensitive exclusions without changing ignore ordering. Include that provenance in graph commitments and validate the contract through compiled CLI and MCP consumers.

BREAKING CHANGE: Pattern-based reference graph exclusions require pattern and distinguish project-ignored and default-ignored reasons. Re-import saved graphs that omit matching patterns.
2026-10-11 04:15:26 +08:00
YsopwnableandGitHub be44b5098e test(javascript): share semantic graph fixtures (#1631) 2026-10-11 04:05:35 +08:00
morluto 6db97d5162 perf(javascript): remove duplicate workflow Evidence snapshots
Pass typed workflow results directly to createEvidence, which validates generic JSON and takes the owned snapshot. Remove the extra generic parse and full result clone from all five workflow helpers; domain producers retain their specific schema validation.

Flameox confirmed JSON validation and copying costs. Alternating warm runs creating Evidence for a valid 2,001-node trace reduced median boundary time from 15.94 ms to 11.20 ms over 120 samples per variant, with identical output digests and independent mutable-input snapshots. This does not measure end-to-end workflow latency.

Validation: 39 focused CLI, SDK MCP and filesystem workflow tests and 17 Evidence tests passed; build, static and documentation checks passed. No deep analysis providers were exercised for this change.
2026-10-11 03:56:59 +08:00
morluto 39da0b150b fix(artifacts): bind member reads to emitted metadata
Reject Mach-O and ZIP entries whose metadata no longer matches the reader inventory, preventing a sibling adapter key from selecting bytes under another entry. Reuse the existing ASAR metadata snapshot and equality rules and read Mach-O ranges from owned records.

Move the real system-lipo test to the provider boundary suite, release its reader, and derive slice expectations from the host FAT table.

Validation: 68 focused artifact, ASAR and MCP tests plus ZIP cancellation passed. Real macOS lipo was exercised against /bin/ls; Ghidra, IDA and other deep providers were not run. Static, docs, architecture and test discovery checks passed.
2026-10-11 03:53:50 +08:00
morluto 3967cfa43e fix(reference): distinguish root access failures from invalid input
Share root filesystem failure classification between import preflight and traversal. Missing roots remain invalid selections; permission and I/O errors retain their reason and reach the CLI as execution failures. Preserve cancellation priority and expose unexpected exceptions.

Validation: compiled CLI permission regression, direct reader error details, import/traversal and unreadable-directory boundaries passed. Windows-only cases were skipped on macOS; static, architecture and documentation checks passed.
2026-10-11 03:53:50 +08:00
morluto 2014ee7d68 perf(javascript): compare scalar semantic query seeds directly
Avoid repeatedly canonicalizing scalar seeds for every literal node. Valid literal metadata without a scalar value now remains unmatched instead of throwing.

Flameox identified canonicalization as the hotspot. Alternating warm query benchmarks over 2,002 nodes reduced the 35.5 KB seed median from 36.34 ms to 0.158 ms; a short seed improved from 0.304 ms to 0.128 ms with identical result digests. These measurements cover the query function, not end-to-end analysis.

Validation: 38 domain query/traversal tests and focused compiled CLI/MCP consumers; static, architecture and documentation checks passed.
2026-10-11 03:53:50 +08:00
YsopwnableandGitHub 5100a1a1a5 test(clients): verify Copilot compact schema workflows (#1624) 2026-10-11 03:43:24 +08:00
morluto de0d341524 fix(artifacts): retain unpacked ASAR handles after close failures
Own unpacked FileHandles until closure succeeds, deduplicate in-flight closure, and retain cleanup resources for retry without replacing the original read or identity failure. Attempt handle and snapshot cleanup independently and retain failed snapshots.

Consolidate unpacked admission, identity checking, cancellation and stream setup, removing the redundant same-handle stat. Cover stat and identity failures, post-stat cancellation, combined cleanup failure/retry, and stream completion/cancellation with real file descriptors.

Validation: 32 ASAR boundary tests, artifact extraction and SDK MCP consumers, check:fast. Native Windows descriptor inspection and real-provider workflows were not verified.
2026-10-11 03:36:36 +08:00
morluto d1f04512af refactor(javascript): remove redundant semantic query passes
Use resolved seeds directly, retain one list of relevant unknowns, and stop sorting adjacency used only for complete reachability. Preserve canonical graph-array output order and candidate coverage scans.

Validation: 37 query and traversal tests, public JavaScript reconstruction and invalid-Evidence consumers, check:fast. No real-browser or deep-provider workflow verified.
2026-10-11 03:36:35 +08:00
morluto 514df0918c fix(analysis-view): preserve inline Evidence error paths
Project authenticated inline Evidence failures at source.evidence while retaining their reasons and messages. Supply the matching request root to input issue projection so nested values remain identifiable.

Validation: both service entrypoints and SDK MCP integrity regressions, advertised-schema consumer suite, check:fast and architecture guards. No real-provider verification.
2026-10-11 03:36:35 +08:00
morluto 8fb79c67ee perf(evidence): remove disposable ledger work from standalone import
Count already-validated records and unknown revisions without reimporting, sealing, and exporting a temporary empty ledger. Keep canonical integrity checks at the file boundary and verify counts and malformed bundles through the compiled CLI.

Validation: Evidence file and CLI consumer suites; check:fast; Flameox CPU profiles and alternating 3.8 MB import benchmark (315.8 ms to 102.5 ms warm median, identical result digests). No real-provider workflow changed or verified.
2026-10-11 03:36:35 +08:00
clydeandGitHub 6a41a29963 fix(apple): preserve directory requirements in dylib paths (#1623) 2026-10-11 03:30:27 +08:00
YsopwnableandGitHub c12a532b9c perf(evm): avoid repeated cleanup diagnostics (#1622)
Retain the original owned-command cleanup failure and one captured-output copy while preserving cleanup resources, truncation and retry semantics.

Verify socket release after cancelled CDP cleanup while retaining the independent detach regression.

Validation: 167 tests across 13 files, all eight local gates, real small Chrome/EVM CLI and pinned-SDK MCP controls, and 20/20 exact-head CI checks.
2026-10-11 03:28:16 +08:00
YsopwnableandGitHub b28c0337fc perf(javascript): reduce retained semantic analysis allocations (#1601)
Reduce retained semantic allocations and memoize lexical scope ancestry while preserving semantic identities. Refs #1065 and #1563; the complete-directory memory failure remains open.
2026-10-11 03:20:05 +08:00
morluto f4e437e544 refactor(artifacts): remove unused extraction inventory indexes
Derive needed artifact IDs directly from selected occurrences. Keep the node lookup local to selection, drop the unread occurrence map and collector helpers, and pass only manifest and selected integrity metadata to materialization.

Validation: existing extraction completeness, identity, unsupported-format, packed/unpacked ASAR, and public MCP workflows pass. Nested archive selection and equal-content occurrence coverage remain intact. This is a structural simplification; no throughput improvement is claimed.
2026-10-11 03:19:29 +08:00
morluto 8ba0a887ff refactor(javascript): bind application links only at graph finish
Remove the empty application-node index from incremental projection state. The completed application graph now owns the only binding pass, and indexing returns the map directly instead of a wrapper.

Validation: 76 builder/composition tests and 19 filesystem, CLI-output, and SDK MCP trace boundary tests pass. Identity budgets and streaming/full-projection parity remain covered; no throughput improvement is claimed.
2026-10-11 03:19:29 +08:00
morluto f9ea9a9268 fix(process)!: bound terminal buffers before capture
Validate columns × (rows + scrollback) against a 1,000,000-cell xterm working-buffer budget, including every resize with the selected scrollback. Document the budget in the advertised MCP input and process-capture guide; never clamp caller dimensions.

Validation: default/exact-boundary schema cases, prelaunch MCP rejection, compiled CLI capture, terminal rendering, normalization, cancellation, and lifecycle checks pass on macOS. This is resource admission, not a measured serializer throughput improvement; Linux-only and real deep-analysis providers were not exercised.

BREAKING CHANGE: process scenarios whose initial or resized terminal exceeds 1,000,000 combined visible-plus-scrollback cells are now rejected before launch.
2026-10-11 03:19:29 +08:00
morluto 78778d91a4 fix(artifacts): retain output identity through cleanup retries
Track created directory and file identities before materializing or removing output. Refuse displaced paths and untracked entries, preserve completed cleanup work across permission failures, and prevent publication once rollback starts. Group cleanup files once per attempt instead of rescanning them for every directory.

Validation: root, nested-parent, and file symlink replacement; untracked-entry retention; real POSIX permission failure and retry; extraction integrity and CLI/MCP consumers pass. Path identity revalidation cannot eliminate syscall-boundary pathname races in portable Node. Windows behavior was simulated; native Windows and Linux-only publication providers were not exercised.
2026-10-11 03:19:29 +08:00
morluto d510f3e928 perf(browser): share JSON shape paths across repeated array rows
Accumulate observations once per structural path instead of allocating and serializing a path for every payload value. Remove the CDP body-shape wrapper and retain primitive, empty-array, and literal-property semantics.

Validation: CDP capture/comparison regressions and CLI/MCP boundary checks pass; 1,507 differential cases match the previous implementation. A 2.5 MB repeated-row workload improves from 105.0 ms to 14.6 ms warm median across alternating runs. Real browser providers were not exercised.
2026-10-11 03:19:29 +08:00
YsopwnableandGitHub 043fd2579d fix(firmware): recover after workspace removal failures (#1616) 2026-10-11 03:16:34 +08:00
YsopwnableandGitHub a761981897 test: remove module and timestamp assumptions from boundary fixtures (#1621) 2026-10-11 03:15:44 +08:00
YsopwnableandGitHub 2653b194b6 feat(skills)!: improve Codex onboarding and task recovery (#1613)
Guide task-centered recovery from observed client, registration, PATH and
provider blockers. Install the recovery reference, document exact JavaScript
module selectors, and require clarification before searching for an unnamed
app. Validate public setup in isolated Codex accounts and preserve failed
or unrecognized tool outcomes in the existing evaluator.

Refs: #1587

BREAKING CHANGE: Optional verify:agent reports now use schemaVersion 4.
Consumers must accept expectedFirstTool: null and targetClarificationPassed
for missing-target scenarios. Production CLI/MCP contracts are unchanged.
2026-10-11 03:13:56 +08:00
YsopwnableandGitHub 16d9c5adef fix(ci): preserve cleanup boundaries and bounded failure assertions (#1618)
Interrupt optional CDP domain shutdown on caller cancellation while preserving an independent bounded detach attempt. Retain original overflow and cleanup failures, verify workspace recovery, preserve user skill files, and reject another unverified firmware worker.

Validation: 149 integrated tests; repeated 64 affected boundary tests; full local check. Standalone CI includes real Chrome CLI/stdio MCP and real Web runtime checks.

Refs #1613
2026-10-11 02:54:12 +08:00
morluto b582b6ecb4 fix(managed): enforce module identity before joining token facts
Validate declared artifact and MVID scopes at managed Evidence admission, and reject conflicting known module declarations across graph inputs. Join boundary tokens to members only under matching known MVID scopes; preserve facts and report partial coverage when scope is unknown.

Prefer an observed MVID-bearing declaration with its supplying Evidence. Normalize GUID casing for module node identity while preserving original strings in observations.

Validation: 285 tests across 34 focused suites passed, followed by the final 12-test managed graph suite and managed CLI/MCP regressions. check:fast and architecture guards passed; no real native providers were run.
2026-10-11 02:52:11 +08:00
morluto ba056e08a4 fix(providers): bound launcher diagnostics without losing byte counts
Give Ghidra and Hopper an 8 MiB aggregate retained-output budget while continuing to drain their process pipes. Expose total observed bytes at the supervisor boundary and retained bytes plus explicit truncation in provider diagnostics.

Redact known transport tokens even when the retained prefix ends inside one, preserving adjacent caller path/query evidence. Existing partial-launch and cleanup ownership remain intact.

Validation: 285 tests across 34 focused suites passed; the final cutoff-fixture refinement passed all 31 Ghidra/Hopper diagnostic tests. check:fast and architecture guards passed. Provider fixtures use real child processes; real Ghidra/Hopper applications were not verified.
2026-10-11 02:50:06 +08:00
morluto cb13a27bfa perf(artifacts): reuse the admitted ASAR header size
Use the header size already validated against the owned archive snapshot instead of asking the ASAR SDK to read and allocate its raw header again.

Validation: ASAR freshness, containment, streaming-allocation, and MCP extraction suites passed within the 285-test focused run. check:fast and architecture guards passed.
2026-10-11 02:49:05 +08:00
morluto 3d79903fb1 perf(browser): normalize precise coverage once by script identity
Pass validated coverage into normalization and index retained sources by script ID instead of scanning them for every script. Preserve source revalidation, UTF-16 bounds, nested counts, and unavailable-source uncertainty.

Validation: 285 tests across 34 focused suites, check:fast, and architecture guards passed. Flameox-guided 8,000-script normalization benchmark improved from 101.6 ms to 5.5 ms median with identical full-result digests; this is normalization CPU, not end-to-end browser timing.
2026-10-11 02:48:59 +08:00
morluto dce81ca400 perf(javascript): count candidate relevance without a second adjacency
Scan eligible candidate relations directly for query ambiguity instead of allocating and sorting another traversal index. Preserve direction, relation filters and cycle handling.

Semantic graph and builder suites plus public application workflow CLI tests passed. Full query outputs matched on a generated 20000-node graph; the single repeated-query timing run is indicative only.
2026-10-11 02:32:11 +08:00
morluto bb764d26bd perf(artifacts): stop parsing parent paths after a missing branch
Walk delimiter-terminated parent segments lazily instead of splitting full paths before discovering that no deeper observed parent exists. Preserve canonical paths and observed ancestry.

Verified real ZIP inventory with multiple 30000-component siblings and the full entry-order suite. A 96-member deep ZIP benchmark retained an identical full inventory digest and reduced median scan time from 517.5 to 464.5 ms across five measured inventories.
2026-10-11 02:32:04 +08:00
morluto acd8d86898 perf(android): validate prerequisites once per retained JADX session
Resolve current paths and JVM options and rehash source identities for each request. Probe Java modules and engine capabilities only when creating a new session; remove the superseded full configuration resolver.

Focused configuration, session retirement, cancellation, cleanup and Android MCP boundaries passed. The 34-operation retained session now performs one prerequisite probe. Protocol fixtures do not establish real JADX or JDK performance.
2026-10-11 02:31:57 +08:00
morluto e6d0b3993d perf(process): batch liveness rechecks within ownership phases
Recheck unreadable token and identity observations against one fresh live process snapshot per phase. Preserve token mismatches, fail closed on inspection errors, and retain liveness failure diagnostics.

Validated with focused process ownership, native capture, CLI and MCP boundaries. An eight-member injected-unreadable workload using native ps reduced snapshots from nine to two with equivalent failures; real permission-denied provider behavior was not exercised.
2026-10-11 02:31:07 +08:00
morluto 92a901e0db perf(process): share settlement probes across captured groups 2026-10-11 02:21:50 +08:00
morluto cef6d6d3c4 perf(artifacts): reuse trie membership for case-folded siblings 2026-10-11 02:21:40 +08:00
morluto bd972bf80b perf(javascript): reuse capture completeness during load classification 2026-10-11 02:21:35 +08:00
morluto ac9709a80a perf(reconstruction): index semantic evidence contexts per derivation 2026-10-11 02:21:28 +08:00
morluto d1e6fe2eca test(artifacts): close owned Mach-O readers after each case 2026-10-11 02:11:13 +08:00
morluto a147ecd4b4 perf(artifacts): index observed parents for deep archive paths 2026-10-11 02:10:50 +08:00
morluto 22fdcb8ab7 perf(process): share batched token observation across ownership checks 2026-10-11 02:10:44 +08:00
morluto b22d817073 perf(process): batch ownership tokens during rooted cleanup
Use the host bulk token reader for each cleanup validation while preserving identity checks before and after token reads. Fall back for unsupported readers or omitted rows, retain explicit unavailable observations, and preserve batch and individual failures. Source ownership regressions and real owned-process boundary tests pass; a warm Darwin validation probe reduced median time from 90 ms to 52 ms.
2026-10-11 01:59:30 +08:00
morluto 3d876c5c1a perf(javascript): validate semantic factory inputs once
Construct typed semantic records directly from cloned, normalized input and derived commitments instead of reparsing the same fields. Keep full graph integrity validation and verify caller mutation isolation. Four alternating cold runs preserved complete result digests while median projection time fell about 8 percent and 17 percent for the two 20,000-node capacity workloads.
2026-10-11 01:54:46 +08:00
morluto cf346368c4 perf(javascript): reuse graph buckets and query indexes
Append overlapping observations to node buckets instead of recopying groups, and share one node index across semantic seed admission and traversal. Preserve merged provenance and absent-seed behavior.
2026-10-11 01:54:36 +08:00
morluto e52c0a72c5 fix(browser): retain incomplete WebMCP replay coverage
Mark malformed WebMCP event envelopes, tool lists and entries as invalid protocol values while preserving valid siblings and out-of-scope classifications. Verify toolsAdded and toolsRemoved replay uncertainty through CDP discovery and capture comparison.
2026-10-11 01:54:26 +08:00
morluto 999e3e2098 fix(android): cancel admitted snapshot copies with their operation
Forward caller and timeout cancellation through engine and APK snapshots, release stream handles before removing partial output, and retain the existing root cleanup authority. Verify cancellation after destination bytes appear with a sparse filesystem fixture.
2026-10-11 01:54:20 +08:00
dakjdakdandYsopwnable c1217e711b fix(javascript): retain runtime scope in bundled module relationships 2026-10-11 01:36:12 +08:00
morluto 0d89978333 fix(android): release snapshot streams before closing file handles
Retain both non-auto-closing copy streams and destroy them after verification, before awaiting their FileHandle closure. This releases stream-held descriptor references on success and failure instead of deadlocking Android snapshot cleanup.

Validation: all 33 JADX subprocess integration tests passed on macOS with Node 24.18.0; check:fast and formatting passed. No real JADX provider execution or Linux/Windows verification was performed locally.
2026-10-11 01:12:48 +08:00
morluto 11e3fae697 fix(ci): repair boundary regressions and evidence assertions
Detach cancelled CDP sessions within the cleanup budget and retain event-finalization failures across retries. Honor Git filesystem encodings and exclude the promise-API probe from source-read failures.

Align existing integration regressions with retained process resources, filesystem-order-independent truncation, owned skill files, explicit native access facts and streamed JSON errors.

Validation: 132 acceptance tests passed (2 skipped), 83 affected boundary tests passed, Git/JSON/CLI boundary regressions passed, check:ci, docs:check and test discovery passed. Local verification used Node 24.18.0 on macOS; cross-platform CI remains pending.
2026-10-11 01:00:30 +08:00
morluto 603d04ee3a fix(ci): repair format gate and pin maintenance skill destinations
format:check failed on ApktoolProvider; existingMaintenanceScope now
returns skillDestinations (consumed by maintenance planning), so pin
the field in the exact-shape scope assertions.
2026-10-11 00:33:36 +08:00
morluto 472f313232 refactor(native): match UI controls by explicit object identity 2026-10-11 00:28:39 +08:00
morluto 1f7e279aa2 fix(adb): retain rollback ownership and cancelled acquisition facts 2026-10-11 00:28:39 +08:00
morluto db8ccaa251 fix(android): bind JADX snapshots and hashes to admitted sources 2026-10-11 00:28:25 +08:00
morluto 5daff4d67e fix(artifacts): retain Mach-O source identity through inventory 2026-10-11 00:28:25 +08:00
morluto a9fd1aecae fix(application): verify configuration and reference input reads 2026-10-11 00:28:24 +08:00
morluto abb8e81d3a fix(filesystem): bound and verify admitted file and JSON reads 2026-10-11 00:28:24 +08:00
YsopwnableandGitHub 6d8f95e38d fix(clients): preserve portable MCP schemas in native workflows (#1580)
* test(clients): verify native Command Code workflows

* docs: synchronize Italian provider guide links

* fix(contracts): make ADB identifier patterns portable

* fix(contracts): preserve portable ADB patterns after formatting
2026-10-11 00:09:43 +08:00
morluto c1b5ccf0a4 refactor(server): admit complete evidence workflows and share handlers
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:24 +08:00
morluto 5f30ea6ff2 fix(engines): serialize JEB acquisition and respect IDA cancellation
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:23 +08:00
morluto d438675677 fix(process): retain capture resources and bound filesystem snapshots
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:23 +08:00
morluto a84dea5500 fix(apktool): join active work and retain cleanup authority
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:22 +08:00
morluto 2a66ec9094 fix(browser): retain startup owners and coordinate retryable close
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:22 +08:00
morluto d1235fadc9 fix(providers): retain worker cleanup owners through shutdown
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:21 +08:00
morluto a01148553e fix(setup): preserve recovery backups and retain installer cleanup
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:21 +08:00
morluto a6f76f5da9 fix(graphs): separate source identities from display representations
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:20 +08:00
morluto 2ca3ad2386 fix(reference): preserve exact paths and unify symlink lookup
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:20 +08:00
morluto 5d0a883605 fix(native): bound metadata projection and compact Mach-O bind runs
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:19 +08:00
morluto 0f0d6e4d43 fix(managed): budget decoding before representation expansion
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:19 +08:00
morluto 6d4cefc4f7 fix(artifacts): admit bounded reads and preserve source identity
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:18 +08:00
morluto 2a0b58e440 refactor(cleanup): share failure composition and retain native UI owners
Validation: integrated changes passed formatting, typecheck, lint, resolved module-boundary verification and git diff --check. Tests and real-provider workflows were not run.
2026-10-11 00:03:18 +08:00
morluto 6543405252 fix(adb): escape portable patterns for unicodeSets consumers 2026-10-10 23:40:37 +08:00
morluto cca7bf0022 fix(ci): repair option alias, pattern portability, and Italian doc links 2026-10-10 23:34:57 +08:00
morluto bb742110a4 fix(ghidra): build bridge script paths with the target platform syntax 2026-10-10 23:22:44 +08:00
morluto a97bd5ed29 fix(ci): share provider workflows to restore static gates 2026-10-10 23:15:02 +08:00
Jay-Alexander ElliotGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
bddddccdee feat(native): admit bounded MIPS ELF analysis through Ghidra (#1362)
* feat(native): admit bounded MIPS ELF analysis through Ghidra

Retain MIPS ELF identity and interpretation through Evidence and snapshots.
Keep provider admission bounded to ELF32 ET_EXEC o32 MIPS32r2, without
implicitly widening Hopper, IDA or Windows P0 coverage. Add source-owned
fixtures and an optional real-provider verifier; real Ghidra verification
remains pending in this contribution environment.

Refs #718

* fix(ghidra): bound MIPS floating-point mode admission

Reject explicit EF_MIPS_FP64 and EF_MIPS_NAN2008 declarations until their
semantics have a real-provider verification lane. Add PSP PRX/Allegrex,
o64/EABI and floating-point-mode refusal regressions. Document that the
header gate is not a full .MIPS.abiflags check and advance the profile lane
identity to invalidate older interpretation bindings.

Validation: 24 standalone checks against the transpiled production profile
module passed; the two new flag cases failed before this change. Clang 17
and LLD compiled the source-owned fixture for both endian targets. The
complete Vitest/typecheck suite and real Ghidra verification remain pending.

Refs morluto/rea#718; PSP support remains follow-up morluto/rea#1330.

* fix(native): validate MIPS ABI records before Ghidra admission

Read bounded ELF32 PT_MIPS_ABIFLAGS and SHT_MIPS_ABIFLAGS records through
the already-open target handle. Preserve declared ABI fields, reject
conflicting/duplicate/truncated records, and keep missing records unknown.
Wire inspection into target resolution before provider selection. Require
compatible declarations for the deliberately narrow Ghidra lane and bind
all ABI fields into profile identity (v3) for snapshot invalidation.

Clang 17 produced eight source-owned fixtures spanning both byte orders
and FPXX/FP32/FP64/soft-float modes with identical ELF header flags. The
new reader and policy distinguish them. 24 focused regression test bodies
passed after TypeScript transpilation using node:test in place of Vitest;
strict isolated TypeScript checking of the reader and target/result types
passed. These are limited checks, not full Vitest/project typechecking or
real-Ghidra verification, which remain pending.

Advances morluto/rea#718. PSP/Allegrex remains morluto/rea#1330 follow-up.

* fix(native): repair MIPS integration boundaries and test resolver behavior

Keep ELF targets out of Hopper Mach-O preparation and scope existing PE fixture types correctly. Move ABI tests into the filesystem boundary lane, use shared cleanup, add resolver regressions, apply the pinned formatter, and register the real MIPS verifier through the existing package-command pattern. Validated with repository-pinned Node/npm, check:ci, actual focused Vitest, discovery and docs:check. Real Ghidra conformance remains pending.

* fix(test): honor caller-selected JDK in real MIPS verification

* test(native): strengthen MIPS Ghidra conformance

Cross-check the source-owned fixture with bounded GNU readelf inspection, compare production ELF/ABI interpretation and independent symbol addresses, and verify effective Ghidra language/compiler identity through existing public operations. Add a source-owned fixed-encoding probe for immediate and conditional branch checks plus global/string byte assertions.

Add 16 assertion/producer-boundary regression cases without widening production admission, changing provider contracts, or introducing proprietary dependencies. Local focused suite: 99 passed, one existing root-permission test skipped. Typecheck, lint/module boundaries, formatting and 700-file discovery pass; full hosted checks and real Ghidra verification remain pending for this checkpoint.

* fix(ghidra): preserve native-tool architecture checks after MIPS integration

The conflict-free upstream merge failed TypeScript compilation because includes on the union of MIPS-only and other architecture arrays requires never. Use equality-based membership without casts or changing accepted native hosts. Extend the existing native-decompiler rejection table with a MIPS executable at a Linux x64 tool path; retain upstream FAT and unknown-header behavior. Hosted verification follows this commit; no success is claimed yet.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-10 23:04:27 +08:00
96fd98cce0 feat(apktool): decode Android resource tables through a caller-supplied launcher (#1556)
* feat(apktool): decode Android resource tables through a caller-supplied launcher

Add an Apktool family with two operations over the caller's apktool
launcher (REA_APKTOOL_COMMAND, absolute, or apktool on PATH):

- inspect_apktool_client: resolved launcher, selection source, and
  version; decodes nothing.
- decode_android_resources: apktool d --no-src in a provider-owned
  workspace that is removed before the result returns. Projects the
  decoded AndroidManifest.xml (bounded at 512 KiB), apktool.yml version
  and SDK facts exactly as printed, string resources verbatim (default or
  one locale, bounded at 2000 entries, nested-markup entries counted as
  unparsed), available string locales, and the decoded file count with a
  hard cap. The target APK is digested with SHA-256 before decoding so
  Evidence binds the observation to the exact input.

Smali production is skipped by design: Java-source recovery belongs to
the JADX family. Workspace cleanup happens before results return; an
unremovable workspace is named in the limitations instead of abandoned.

Verified against apktool 2.7.0-dirty (Debian packaging) on Linux with
OpenJDK 25 against a signed aapt2-built probe APK with two resource
locales: launcher version, on-disk digest agreement, metadata projection,
manifest package agreement, and both string tables (default and de).
Parser goldens come from the same decode. READMEs carry the new
'Android resources' row in every supported language.

* fix(apktool): own snapshots and bound decoded resource reads

* docs(apktool): describe owned resources and bounded projection

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:04:12 +08:00
749e58772a feat(jeb): add JEB engine provider over its MCP interface (#1536)
* feat(jeb): add JEB engine provider over its MCP interface

Add a bring-your-own JEB provider that serves project, unit, and
decompilation inspection from a caller-started JEB client speaking MCP
(streamable HTTP, selected with REA_JEB_MCP_URL). Expose four provider-neutral
operations through shared CLI/MCP workflows: inspect_jeb_client,
open_jeb_project, list_jeb_units, and decompile_jeb_item, each returning
Evidence with engine identity, endpoint, and preserved refusal reasons.

The adapter keeps JEB's envelope semantics: success fields are parsed
format-aware at the boundary, message-only refusals become unsupported-target
errors with the engine's own reason, transport failures become availability
failures with recovery guidance, and unit pagination derives coverage from the
engine's 100-item page cap. Explicit unknowns (implicitly selected unit,
omitted filters) are reported instead of guessed.

Verified against a real JEB 5.48.0 licensed build serving jeb-mcp-server 1.3.0
headless: client inspection, unit listing, and method decompilation were
exercised through the CLI, MCP boundary, and scripts/verify-jeb.mjs.
JEB 5.48.0 headless instances do not advertise open_project; the refusal is
preserved and documented.

* fix(jeb): verify against a real signed APK and fix CLI option surface

Verify the provider against a locally built, v1/v2/v3-signed probe APK
(binary manifest, classes.dex with a launcher activity) on JEB 5.48.0: the
full unit tree (apk, manifest, three certificate units, dex bytecode,
decompiler), wildcard-filtered and paginated unit listing with derived
coverage, parent-restricted listing, and launcher-activity method
decompilation through both CLI and MCP, including dexdec's inline
constant folding of the probe's obfuscated tag.

Move list-jeb-units filter/pagination and decompile-jeb-item unit selection
from positional arguments to options; the MCP schemas are unchanged.

* fix(jeb): preserve engine refusals through the real MCP boundary

Testing against the published Signal 8.30.3 universal APK exposed a boundary
bug the scripted provider tests missed: decodeJebToolResult raised a protocol
error for isError results before the provider could map JEB's
{success:false, message} envelope, so real engine refusals surfaced as
unreadable output instead of the engine's own reason. Decode refusal
envelopes like any structured result and let the provider preserve the
reason; cover the decoder directly, including contentless and unparseable
results.

Signal verification: full 109 MB R8/Kotlin/Compose APK with four signature
schemes and native arm64 ELF units parsed; MainActivity.onCreate and R8
synthetic lambdas decompiled through CLI and MCP; paginated, filtered, and
parent-restricted unit listing; refusal path confirmed on the live engine.

* docs(jeb): record Flutter Gallery verification on the real-engine lane

Verify the provider against the official Flutter Gallery 2.9.2 release APK
(112 MB): per-ABI libapp.so Dart AOT snapshot images analyzed as native code
with 75k methods on arm64, snapshot internals and wrapper methods decompiled
through both CLI and MCP with explicit unit selection, decoded manifest, and
filtered native-library unit discovery. Note that JEB 5.48.0 headless does
not expose the dedicated Dart snapshot processor or run_script; both remain
GUI-only engine surfaces.

* docs(jeb): translate the README JEB row for every supported language

The JEB row was inserted in English across all translated READMEs; each now
carries its own label, capability summary, requirements, and guide link
following that language's Android-row conventions.

* fix(jeb): enforce local endpoints and preserve cancellation

* fix(jeb): refuse redirects across the local MCP boundary

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:03:27 +08:00
ded59689ce fix(javascript): accept the Wakaru 1.x release line and verify 1.14.0 (#1540)
* fix(javascript): accept the Wakaru 1.x release line and verify 1.14.0

Exact --version equality rejected every Wakaru build except 1.13.0, and
strict report schemas rejected any added field, so each upstream release
broke recovery until REA re-pinned. Wakaru now documents that --version,
--json and provenance.json change only by addition within a major version.

Admit ^1.13.0 with the verified/compatible split used for Binwalk and
Unblob, report the observed version instead of the pinned constant, and
add a limitation for unverified releases. Parse reports with loose
objects and keep the reported module status as a string; path, identity,
range and file-set checks stay exact.

Move the audited pin, submodule, CI binary and verifier to 1.14.0, and
document where to get the binary from the refusal message.

* fix(javascript): project known Wakaru warning fields

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:02:15 +08:00
0363e5a8e1 fix(reference): join internal symlink targets with the inventory NFC normalizer (#1535)
* fix(reference): join internal symlink targets with the inventory NFC normalizer

checkSymlinks resolved an internal symlink target with bare
posix.normalize and looked the result up in the inventoried path set.
A target that a filesystem reports in NFD (macOS readlink commonly
does) joined to an NFD spelling while the inventory holds NFC, so
validation reported "Internal symlink target must resolve to an
inventoried entry" for a target the inventory actually contains.

Route the join through normalizeJoinedLogicalPath, the same inventory
identity normalizer #1513 applied to the runtime, HTML/module, and
import joins from #1488. The feature-seed NFKC query fold stays a
query.

Refs #1488

* fix(reference): preserve source spelling during symlink lookup

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:02:10 +08:00
905e4866c4 feat(artifacts): inspect PE resource identities and payload ranges (#1482)
* feat(artifacts): inspect PE resource identities and payload ranges

* fix(artifacts): reject header payloads overlapping PE sections

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:02:06 +08:00
f6009d0077 fix(browser): keep the first DOM attribute when the name is repeated (#1516)
* fix(browser): keep the first DOM attribute when the name is repeated

When an element in a captured DOM tree carries duplicate attribute
declarations (e.g. repeated href, action, or src), domMetadata folded
the attributes into a Map using pairs.set(), overwriting earlier
declarations with the last one.

HTML specifies that the first declaration is kept when an attribute
name is repeated. This aligns domMetadata and attribute_names to retain
the first occurrence case-insensitively, matching HTML and ensuring that
attribute_names and dom_urls reflect the same attributes.

Fixes #1496

* fix(browser): preserve case-sensitive DOM attribute names

* test(browser): align repeated attribute coverage with deduplication

---------

Co-authored-by: taljeri <318237806+taljeri@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:02:00 +08:00
4d8d76b253 fix(electron): support packaged app.asar pages and rewritten unpacked companions (#1400)
* fix(electron): resolve pages served from inside app.asar

Packaged Electron applications load their renderer pages from file URLs
inside app.asar. The host filesystem cannot stat those paths, so
list_electron_targets excluded every such page as unsupported_url and
inspect_electron_page could not select it.

Resolve these URLs the way Electron's file protocol does: the first .asar
path component that is a regular file is the archive, and the remainder
must name a regular file in its header. Directories, links, and missing
members stay rejected. Parsed headers are cached by archive identity.

* fix(artifacts): extract and explain rewritten ASAR unpacked companions

Packaging tools commonly sign or strip .asar.unpacked native binaries after
writing the archive header, so their declared hashes no longer match.
analyze_javascript_application already accepts integrity_policy, but
extract_artifact did not, and inspect_artifact and extract_artifact still
told callers to "get a fresh copy", which cannot help for a shipped app.

- Accept integrity_policy on extract_artifact (MCP and CLI). The default
  still fails closed; record-and-continue writes the observed bytes and
  returns the extracted files' integrity_contradictions records.
- Name the unpacked entry and the post-packaging cause in integrity
  failures, and point every operation that accepts integrity_policy at
  record-and-continue.
- Report an active unpacked entry whose companion file is absent as
  unavailable with its logical path instead of a format failure.
- Share one integrity_policy schema across the inventory, extraction, and
  JavaScript application inputs.

* fix(electron): bound ASAR headers before allocation

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:01:54 +08:00
162f9bf7ff fix(ghidra): clear wrong no-return flags before serving a session (#1419)
* fix(ghidra): clear wrong no-return flags before serving a session

Auto-analysis can flag ordinary functions as no-return (stream readers,
__cxa_guard_acquire, ...). Their callers then end at the call and the
decompiler truncates them. Run a postScript before the bridge that clears the
flag on functions containing a real RET and re-disassembles the call sites that
were terminators.

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

* fix(ghidra): refit in place and scope no-return call-site repair

Keep function types by refitting the owning functions with fixupFunctionBody
instead of removing and recreating them. Only redo call sites whose callee was
actually cleared (including thunks to it), skip sites followed by a function
start or x86 padding so real end calls do not run on, and always log the result.

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

* fix(ghidra): constrain no-return repair to admitted return evidence

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:01:50 +08:00
fef6f73064 feat(adb): complete ADB device support for Android reverse engineering (#1552)
* feat(adb): acquire installed APK sets from connected Android devices

Add a read-only ADB device-acquisition family over the caller's adb binary:
inspect_adb_client, list_adb_devices, inspect_adb_device, list_adb_packages,
and pull_adb_package, exposed through the CLI and MCP with shared admission,
Evidence provenance (binary, version, serial, transport), and fixed argv
vectors that never reach a shell.

pull_adb_package acquires the complete split set reported by pm path into a
package-named directory that must not exist, digesting every file with
SHA-256 and keeping per-file failure reasons and partial coverage. Device
kind is reported as an inference with its basis; getprop whitelisting keeps
build identity bounded. REA installs nothing and never manages devices or
emulators; the first device query may start the caller's local adb server,
recorded when observed.

Verified against adb 34.0.5 on Linux with an Android 14 (API 34) x86_64
emulator: full 224-package inventory, a real two-APK split set pulled with
byte-exact digests, and a 73.9 MB system-package pull. npm run verify:adb
records the lane; parser goldens come from the same device. READMEs carry
the new row in every supported language.

* feat(adb): complete the adb surface with observation, transfer, and lifecycle tools

Extend the ADB family from five to twenty-four operations, all through
fixed adb argument vectors with no shell exposure:

Observation: read_adb_logcat (bounded dump, count/buffer/pid), inspect_adb_package
(dumpsys package projection), list_adb_processes (ps -A), list_adb_directory
(ls -la with kinds and symlink targets), list_adb_features (hex GL versions),
list_adb_services (AIDL slash-suffixed names), inspect_adb_display (wm size and
density), inspect_adb_window (focus declarations), read_adb_setting (device-side
nulls reported as such), capture_adb_screen (exec-out screencap with PNG
dimensions), collect_adb_bugreport (digested device archive).

Transfer and search: pull_adb_file and push_adb_file (device-side sha256sum
verification, explicit overwrite authority), resolve_adb_packages (substring
package search with exact-match flag — the find step of an easy get).

Lifecycle for dynamic analysis, each declaring mutatesTarget:
install_adb_package and uninstall_adb_package preserving the device's
Success/Failure verdict, start_adb_app (resolve-activity then am start -W),
start_adb_activity (typed extras as --es/--ez/--ei/--el/--ef), and stop_adb_app
(am force-stop).

Verified end-to-end against adb 34.0.5 on Linux with an Android 14 (API 34)
x86_64 emulator: 287 services, 92 features, split-set pulls with byte-exact
digests, verified push/pull roundtrip, sized screen capture, and the full
install → resolve → start → observe-in-ps → force-stop → uninstall lifecycle.
Fixed a v-mode regex incompatibility in the settings key pattern and added
argument descriptions required by the CLI catalog audit.

* fix(adb): quote remote shell operands and protect captured output

* test(adb): cover bugreport destinations containing spaces

---------

Co-authored-by: REA Contributor <contributor@rea.tools>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 23:01:24 +08:00
YsopwnableandGitHub efd81f9776 test(clients): verify native Grok Build workflows (#1571) 2026-10-10 22:59:43 +08:00
5156ba44c5 feat(native): return a retained summary view of binary layouts on request (#1570)
inspect_binary_layout accepts the same optional detail input as
analyze_javascript_application. The default complete delivery is
unchanged; detail "summary" retains the complete layout Evidence in the
session and returns its inspect_analysis_view summary, whose
parent_evidence_id selects sections, symbols, mitigations or linkage
later. Both tools share one detail schema and output projection.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:57:42 -07:00
c19e15a2b3 feat(javascript): return a retained summary view on request (#1568)
analyze_javascript_application returns the complete application graph
inline, which repeats tens of kilobytes even for a few source lines and
exceeds the default 10 MiB MCP frame for a 300-function source file.

The new optional detail input keeps complete delivery by default. With
detail "summary" the server records the complete analysis Evidence in
the session and returns its inspect_analysis_view summary, whose
parent_evidence_id lets callers page modules, select items, or pass the
retained reference to application workflows. A server without Evidence
retention refuses summary detail with capability_unavailable rather
than returning a summary whose analysis cannot be reached.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:37:37 -07:00
ClaudeandYsopwnable 649661dc8b fix(javascript): stop reading media preload attributes as Electron preloads
HTML audio and video elements have their own `preload` attribute ("none",
"metadata", "auto"). A React renderer compiles `<audio preload="metadata">`
to `jsx("audio", { preload: "metadata" })`, and the `property:preload`
heuristic reported it as an Electron preload script named `metadata`.

Skip `preload` properties in the props object of a call whose first
argument is the static tag `audio` or `video`. The callee is not checked,
because minified element factories have arbitrary names.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPY2GmufMNGQKoEgRUx1pd
2026-10-10 22:12:56 +08:00
YsopwnableandGitHub e4cc0f09de fix(setup): reject invalid OMP profiles before fallback writes (#1562) 2026-10-10 22:11:14 +08:00
a53689c55d fix(mcp): stop advertising complete Evidence in input examples (#1560)
Hosts forward every tool's input schema to the model on each request.
Seventeen tools advertised a canonical example that embedded a complete
producer Evidence record, up to 22 KB each, accounting for 116 KB of the
450 KB of advertised input schemas.

Advertised examples now show an embedded Evidence record as its exact
retained-evidence reference when the canonical input accepts one, and
omit an example that can only carry inline Evidence. Canonical contract
examples, their executable tests, and validation are unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 07:10:38 -07:00
morluto 2d426c924c fix(native): format runtime convention guard 2026-10-10 21:50:55 +08:00
a929c9f714 fix(mobile): bound framework conventions to path segments (#1506)
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 21:42:03 +08:00
YsopwnableandGitHub 8c47a9ce4b fix(javascript): yield during receiver and reference classification (#1557) 2026-10-10 21:40:16 +08:00
de619bd334 fix(ida): canonicalize the headless workspace root before opening (#1481)
On macOS the default workspace root is os.tmpdir() under /var/folders,
and /var is a symlink to /private/var. idalib-mcp reports the canonical
input path from idb_open/idb_list, while REA compared it against the
uncanonicalized private copy with normalize(), so every headless IDA
analysis failed its identity check (surfacing as unreadable_output) and
the spawned idalib worker was never released.

Resolve the workspace root with realpath() when allocating the private
workspace so the input path REA sends already matches what upstream
reports.

Co-authored-by: Xingchuan Ma <xingchuan.ma@msn.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:39:33 +08:00
24d9337649 fix(native): preserve compact reference provenance (#1438)
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 21:39:28 +08:00
2ec93ba166 docs: celebrate 60,000 GitHub stars 🎉 (#1559)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:31:58 -07:00
afdaf98117 fix(hopper): treat a directory launcher path as missing (#1426)
`HOPPER_LAUNCHER_PATH` availability was decided by an `X_OK` access check
alone, which a searchable directory also passes. Pointing it at the
`Hopper Disassembler.app` bundle instead of its launcher made `rea providers`
report Hopper as available and `rea doctor` report it healthy, while analysis
then failed with an unrelated `version_unresolved` rejection.

Require a regular file in both the provider availability probe and the
doctor executable probe, matching the Ghidra launcher check. A directory now
reports `executable_missing`, and doctor reports `config_drift` with its
existing HOPPER_LAUNCHER_PATH remediation.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:31:26 +08:00
944981d8d5 docs: correct stale logging, Ghidra host, and example path statements (#1420)
- CONTRIBUTING: CLI logs go to stderr, not stdout. `createLogger` writes every
  mode to fd 2 so protocol and `--json` stdout stay parseable.
- Get started: Ghidra supports Linux arm64 (`GhidraInstallation` maps
  `linux.arm64`), as installation.md already states.
- Browser guide: drop the caption claiming the hosted request path carries a
  `/rea/` prefix. The guide now targets rea.tools, where the example is served
  at `/examples/notes-web/`, as the evidence table above it shows.
- JavaScript workflows: six CLI commands accept inline JSON or a JSON file,
  not five; `inspect-analysis-view` was added after the sentence was written.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 21:29:31 +08:00
b32a11e1a7 docs: correct host requirements in the README analysis tables (#1422)
- EVM bytecode and recorded crashes: state the Linux x64 host requirement.
  `EvmoleInterfaceProvider` and `PwntoolsDecoder` refuse every other host
  with `capability_unavailable`, but only the neighbouring offline ELF layout
  row said so.
- Translations: Android analysis has supported Windows x64 since 6.2.0
  (#1276), which updated only the English table; 16 translations still said
  Linux/macOS.

Translated cells reuse each README's own wording: the recorded-crash cell
copies that file's ELF-row pwntools phrase, and the EVM and Android cells
follow the construction the same table already uses for host platforms.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:29:03 +08:00
0e19db9fce fix(javascript): unify package resolution and resolve exact exports subpaths (#1424)
* fix(javascript): resolve exact package export subpaths

Bare module specifiers with subpaths now resolve against the selected
package's exports map instead of staying external. An exact subpath key
selects its target through the existing condition, array, and null
semantics, and the selected target resolves as one exact file with no
extension or index fallback. A declared exports map encapsulates every
other subpath lookup, and packages without an exports map keep legacy
file and directory-index resolution.

Package-private import aliases remain external pending a separate
increment (#1365).

Verification: npm run check:fast; focused and full
src/application/javascript source tests on Windows;
verify:test-discovery; docs:check. Four pre-existing failures in
JavaScriptFileUrlPaths and JavaScriptModuleSpecifierPaths reproduce on
unmodified main on Windows because their fixtures write file names
containing '?'.

* fix(javascript): unify package path resolution

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 21:26:02 +08:00
YsopwnableandGitHub 66a9ad58fc test(clients): verify native GitHub Copilot CLI integration (#1555) 2026-10-10 21:23:11 +08:00
4b985e5021 fix(artifacts): take nested container families from bytes (#1553)
Inventory gave nested members a ZIP or ASAR family from their path
suffix. Byte classification replaced it only for ZIP magic, so text named
`.apk` or `.asar` stayed a container, and encrypted entries and symlinks
kept the suffix guess. A filesystem `.asar` without an ASAR header failed
the whole inventory as a malformed archive.

Nested ZIP families now follow ZIP magic and ASAR follows its header
pickle, shared with root classification. An unread member named like a
container has an unknown format and a limitation naming the suffix. ASAR
expansion requires the header.

The Android projection adds a limitation when no root AndroidManifest.xml
was observed, and its rejection names the observed root format.

Fixes #1491

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 06:17:40 -07:00
Rudy CelekliandYsopwnable c8fd2f152b fix(apple): scope keyed archive traversal to the selection
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 21:17:35 +08:00
morluto 02ef2b1c41 docs(zh): rename title to 逆向一切 2026-10-10 21:10:30 +08:00
morluto 961471205c fix(docs): format Italian README tables 2026-10-10 21:08:41 +08:00
a6d6e595f3 docs: add Italian (it) README translation (#1455)
* docs: add Italian (it) README translation

Adds README_it.md (full Italian translation of the English README) and updates the language nav bar in all existing READMEs to include the new [Italiano] link, appended at the end of the bar (after Bahasa Indonesia) to match the repository's convention for adding new languages.

Rebuilt on top of current main to resolve the merge conflict caused by the recently added Bahasa Indonesia (README_id.md) translation.

Closes #1453

* docs: fix Italian README showcase anchors

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 21:03:39 +08:00
N0zoM1z0 9ffc6210a4 test(javascript): remove duplicate escaped-receiver cases 2026-10-10 20:53:47 +08:00
GeekwolfandYsopwnable b973b1b1ec test(javascript): cover returned object scaling 2026-10-10 20:53:47 +08:00
GeekwolfandYsopwnable 47947eb01c perf(javascript): index returned object targets 2026-10-10 20:53:47 +08:00
YsopwnableandGitHub 2d99e1e3b2 test(ghidra): preserve Node heap options in adapter verification (#1550) 2026-10-10 20:27:45 +08:00
5d6eeb22fb fix(javascript): yield during the largest AST traversals (#1545)
After #1542 the longest event-loop blocks on large bundles were single AST
traversals inside one analyzer: member-mutation collection with its
fixpoint, static source analysis, and function fingerprints, each about
one second on Obsidian's 3.7 MB app.js.

- traverseJavaScriptAstSteps yields every 1,024 visited nodes with the
  same visit order; traverseJavaScriptAst drains it, so every existing
  caller is unchanged.
- Member mutations, static analysis and fingerprints run as steps. The
  member-mutation fixpoint yields every 64 references, and fingerprints
  yield between callables.
- The now-unused synchronous member-mutation and fingerprint wrappers are
  removed.

Graph IDs and complete result digests match main on three inputs,
including obsidian.asar. Over two runs there, the longest block falls
from about 920 ms to 740 ms, the second from 860 to 595 ms, and blocks
over 250 ms from 27 to 18, with total time within 1.5%.

Refs #1462

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 20:27:41 +08:00
N0zoM1z0 e964a06b83 fix(website): preserve template-owned HTML formatting 2026-10-10 20:27:01 +08:00
N0zoM1z0 5aa30b8b86 chore(website): simplify maintenance and detect documentation drift 2026-10-10 20:27:01 +08:00
YsopwnableandGitHub 8c7569aca7 test(clients): verify native Claude Code integration (#1549) 2026-10-10 20:16:41 +08:00
YsopwnableandGitHub 539a0f95b5 test(clients): verify native OpenCode integration (#1546) 2026-10-10 19:51:30 +08:00
N0zoM1z0 c73cf0ab76 fix(verification): reuse shared output schemas in Electron checks 2026-10-10 19:29:16 +08:00
PeterandYsopwnable aa7008f8a5 fix: reuse validators for identical output schemas 2026-10-10 19:29:16 +08:00
PeterandYsopwnable 1887e1120e fix: reuse validators for identical output schemas 2026-10-10 19:29:16 +08:00
ca7ef69c0c fix(javascript): yield inside semantic analysis and large projection passes (#1542)
* fix(javascript): yield inside semantic analysis and large projection passes

After #1525 the longest event-loop blocks were single stages on very large
files: semantic analysis of Obsidian's 3.7 MB app.js ran 5.8 s in one piece,
and its object projection 1.8 s.

- analyzeParsedJavaScriptSemanticsSteps yields between the analysis phases
  and between the eight derived collectors; the synchronous function drains
  it, so results are unchanged.
- Per-file analysis yields between open-receiver classification and static
  analysis and drives the semantic steps.
- Semantic node creation, definitions and references, and the object and
  frontier passes yield every 64 items. Node creation keeps source order,
  which the per-file node budget depends on.

On obsidian.asar the longest block falls from 5,355 ms to 907 ms with the
same total time (40.6 s to 39.5 s). Graph IDs and complete result digests
match main on five inputs. Remaining blocks up to about 0.9 s are single
AST traversal passes inside the analyzers.

Refs #1462

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

* refactor(javascript): drop the unused synchronous derived-semantics wrapper

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 04:20:50 -07:00
YsopwnableandGitHub b9c439831d test(clients): verify native Gemini CLI integration (#1541) 2026-10-10 19:17:55 +08:00
YsopwnableandGitHub bace2c5a4f fix(javascript): avoid argument limits when expanding escaped receivers 2026-10-10 19:11:00 +08:00
N0zoM1z0 3cd80cbb88 test(process): prepare SDK validation before cancellation timing 2026-10-10 18:54:57 +08:00
N0zoM1z0 6cd5ea0fb2 fix(process): coalesce delayed capture progress
Retain one pending intermediate observation and drop stale live status before terminal cleanup. Preserve monotonic counts and final delivery while an observer is slow or rejects an update.

Verify the send rate at its controlled-clock owner and lifecycle notification density at the CLI/MCP boundary, where receive timestamps include buffering and scheduling.
2026-10-10 18:54:57 +08:00
Cursor AgentandYsopwnable 706bba6e13 feat(process): report live capture progress through CLI and MCP
Long captures emitted only a final result, so a quiet child looked idle.
Pass the shared rate-limited progress reporter through the capture lifecycle
and report the observed phase, elapsed time, and collected-unit counts.
CLI writes those lines to stderr; MCP forwards them only when the client
supplied a progress token. Final Evidence on stdout keeps its shape.
2026-10-10 18:54:57 +08:00
YsopwnableandGitHub 9964af6b79 fix(ci): synchronize browser fixture events before inspection (#1534) 2026-10-10 18:44:49 +08:00
YsopwnableandGitHub 3059d8a40f test(clients): verify native DeepSeek Harness integration (#1524)
* test(clients): verify native DeepSeek Harness integration

* fix(ci): avoid load-sensitive escape regression timing
2026-10-10 18:29:00 +08:00
86b223b33e fix(setup): follow and validate Hermes sticky profiles (#1528)
* fix: follow Hermes sticky profile for setup paths

* test: cover Hermes sticky profile paths

* fix: honor Hermes profiles with home overrides

* style: format Hermes profile lookup

* style: format Hermes profile tests

* fix(ci): avoid load-sensitive escape regression timing

* fix(setup): validate Hermes sticky profile identity

---------

Co-authored-by: N0zoM1z0 <1705004398@qq.com>
2026-10-10 18:19:51 +08:00
92741187ec docs: list all supported clients in the REA skill (#1523)
docs: include all supported clients in the REA skill

Co-authored-by: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 18:18:26 +08:00
5fdb0636b4 fix(javascript): yield during per-file projection and graph construction (#1525)
analyze_javascript_application ran several long phases with no event-loop
turn, so MCP ping and cancellation waited: each file's parse, analysis and
semantic projection; building every application node and relationship
before the application graph's first sealing step; and whole-graph schema
parses inside both immutable graph factories.

- Each file runs as steps (parse, static analysis, semantic analysis, then
  each projection pass), driven by the existing time-sliced checkpoint.
- Application graph input construction yields between phases, per module
  link and per file of findings.
- The pipeline transfers its privately built graph inputs to new sealing
  steps that validate the graph's own fields synchronously and elements,
  content checks and the digest in steps. The public copying factories
  keep their synchronous capture.

Results are unchanged: graph IDs and the complete result digest match main
on five inputs including Obsidian's 23 MB obsidian.asar. On the issue's
1,200-function fixture the longest event-loop block falls from about
290 ms to 90 ms, and ping after abort from up to 286 ms to at most 56 ms.
On obsidian.asar it falls from 10.9 s to 5.4 s; the rest is one analyzer
stage of a single very large file.

Refs #1462

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 03:14:37 -07:00
N0zoM1z0 72b3209f3a docs(website): explain autonomy and oracle lessons in Touhou reconstruction 2026-10-10 18:09:13 +08:00
YsopwnableandGitHub f9ce32b474 test(javascript): verify escaped receivers through CLI and MCP 2026-10-10 17:50:36 +08:00
46c9cba03a fix(javascript): expand an escaped receiver's methods once (#1495) (#1517)
Since #1471, escaping an object also escapes every method's results. Each
call through the object escapes it as the receiver, and each escape
re-expanded all of its methods. N methods returning one shared object,
each called once, did N times N work: 2,000 calls took 3.0 s of semantic
analysis and 4,000 took 12 s.

Expansion below references depends only on syntax, so escapes now reuse
it per expression and path. Identifiers that resolve to the same binding
and path collapse to one, because the escape walk treats them alike.
Every escape site is still recorded. The semantic IR is byte-identical
on 50 sources, and the issue's case takes 253 ms at 2,000 and 638 ms at
4,000.

Closes #1495

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 02:16:30 -07:00
b4db35f092 fix: bind identity and coverage to the producing rule (#1513)
* fix: bind identity and coverage to the producing rule

Logical paths, container families, examined bytes, path-segment conventions, destination collisions, file-id leases, Mach-O CPU selection, and firmware cleanup now follow the observation that owns each rule.

* fix: fail unmatched Mach-O slices and keep firmware roots independent

A fat target whose architecture lipo did not list now stops before slice tools run. Chained fixups still count unread LC_DYLD_INFO rebase bytes, and a firmware cleanup failure no longer blocks the next workspace.

* test: cover path identity and runtime families at the projection boundary

NFC joins and segment conventions are now asserted by the path resolver, the Apple projection, and a real APK inventory instead of helper unit tests.

* test: expect unread dyld rebase bytes in the Apple dispatch fixture

The legacy LC_DYLD_INFO fixture keeps a rebase range this reader does not decode, so the public CLI and MCP check now requires that partial coverage beside the bind opcodes.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-10 17:14:47 +08:00
7a56fe6260 fix(setup): honor active client configuration and skill roots (#1504)
* refactor(setup): resolve skill destinations per client

* fix(setup): honor active client configuration and skill roots

* fix(setup): validate effective client scopes and Gemini trust

* fix(setup): treat empty OpenCode overrides as unset

An empty OPENCODE_CONFIG_DIR now stays on the XDG directory, and doctor
and setup inspect global OpenCode files when a custom directory is absent.
Uninstall reports one status per client so a missing earlier layer does
not hide a removed registration.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-10 17:03:43 +08:00
YsopwnableandGitHub b25922e4e8 test(clients): verify native Qwen Pi and Hermes workflows (#1511) 2026-10-10 16:59:32 +08:00
b6ad1f2c3d feat(mcp): compact input schema profile for size-capped providers (kimi-cli/Moonshot) (#1514)
* feat(mcp): add compact input schema profile for size-capped providers

Moonshot's function-calling API rejects a request while any single tool
parameters schema exceeds its literal serialized size cap, so clients
such as kimi-cli fail every request while the default catalog is
attached (#1484).

Add an opt-in REA_MCP_INPUT_SCHEMA_PROFILE=compact server presentation.
Each advertised input schema is rendered within a 13,312-byte budget,
measured to sit below the observed provider cap: annotation prose
(nested descriptions, examples, defaults, titles) is dropped, repeated
annotation-free subschemas are shared through schema-local $defs/$ref
references the provider validates without expansion, and the three
structurally oversized schemas are advertised in a documented reduced
form. The canonical catalog, tool set, output schemas, and server-side
canonical validation are unchanged; the default full profile is
byte-identical to today's advertisement.

Boundary tests pin every compact schema to the budget, keep them valid
JSON Schema that still accepts every canonical example, hold reduced
presentations at three or fewer, and verify canonical rejection still
guards a permissive advertisement. Verified against the real Moonshot
API through kimi-cli: prompts succeed with the compact catalog attached
where the default catalog fails every request with 400.

* fix(mcp): preserve compact schemas through Kimi conversion

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 16:58:43 +08:00
N0zoM1z0 2b6f14f528 fix(process)!: version literal scenario replacement semantics
Keep caller-selected replacement text literal with a callback, preserving
empty-search positions instead of changing their split/join behavior.
Commit the replacement interpretation for captures using custom patterns so
legacy records cannot report this producer correction as a target change.

BREAKING CHANGE: Captures with custom normalization patterns use
literal-replacements-v1 and cannot be compared with legacy unversioned
pattern captures. Capture both sides with the same replacement semantics;
legacy captures remain readable and captures without patterns are unaffected.
2026-10-10 16:57:06 +08:00
openhandsandYsopwnable f51503ef1c fix(process): normalize scenario replacements literally
capture_process_scenario declares normalization patterns as literal text, but\nreplaceAll expands \$&\, \$\`, and \$1\ in the replacement as a replacement\npattern. A caller normalizing text that contains a dollar sign silently gets\nduplicated, spliced, or dropped content in the recorded Evidence instead of\nthe requested literal replacement.\n\nUse split/join, which is literal on both sides and is already the idiom used\nfor exact-literal scenario rules in browserScenarioNormalization.ts.
2026-10-10 16:57:06 +08:00
2bf812772d fix(apple): bound binary plist expansion before decoding keyed archives (#1515)
inspect_keyed_archive passed caller-selected binary plists straight to
plist.parseBinary, which recurses on every object reference and copies
shared containers. A 484-byte archive of forty nested [next, next] arrays
grew the process past 4 GB until it died with no result, which would also
end an MCP server. A 125-byte self-referencing array overflowed the stack
and was reported as an artifact too large to process.

The iterative reference walk that already guards decode_interface_builder
now runs first, with an 8x keyed-archive decode budget. Over-budget depth
or expansion is a limit; a reference cycle is a malformed archive. Its
"decoder" bounds admit the same layouts plist.parseBinary reads, so
accepted archives stay accepted. Interface Builder behavior is unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:44:46 -07:00
a936303723 fix(json): name a leading byte-order mark in rejected JSON input (#1510)
Strict JSON file inputs reject a leading UTF-8 byte-order mark, but the
diagnostic was the parser's own message, which quotes the invisible U+FEFF
as the unexpected token: Unexpected token '', "{"invento"... is not
valid JSON. Editors such as Windows PowerShell 5.1 write that mark by
default, and nothing in the message showed it.

CLI JSON files (whole and streamed), Evidence and snapshot JSON files, and
process scenario files now report that the input begins with a UTF-8
byte-order mark and how to save it. Acceptance is unchanged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:37:41 -07:00
93ca276921 fix(browser): accept HAR files that begin with a byte-order mark (#1509)
HAR 1.2 lets writers emit a UTF-8 byte-order mark and requires readers to
ignore it. The decoder passed ignoreBOM: true to TextDecoder, which keeps
the mark in the decoded text, so a BOM-prefixed export failed as "HAR is
malformed JSON." Decoding now uses the default, which skips one leading
mark. The artifact digest still covers the selected file bytes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:31:31 -07:00
911323c5dd fix(native): page every retained function dossier collection (#1507)
inspect_analysis_view is the recovery path when an analyze_function
dossier exceeds the MCP response budget, but its native facets covered
only procedure, pseudocode, assembly, callers/callees, references, and
value flow. Basic blocks, comments, unresolved calls, referenced strings
and names, and the native API record could not be read from retained
Evidence at all; basic blocks grow with the function just like assembly.

These are now facets: collections page by rows, and native_api is a
singleton. A dossier without an unresolved_calls record reports "not
recorded" rather than the value-flow failure reason.

Refs #1247 and #1065.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:31:15 -07:00
f63f12d8ff docs: align the Indonesian README with the other translations (#1512)
Keep the Bahasa Indonesia onboarding text from #1508, and fix the formatting
that left it outside the shared README layout: drop the leading space, point
in-page links at the translated headings, align the analysis table, and link
Bahasa Indonesia from every language selector.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Dev Cee <24010110166@universitasbumigora.ac.id>
2026-10-10 16:26:52 +08:00
983b070d4d fix(artifacts): record each case collision once at its diverging segment (#1505)
Inventory paired every path under one case spelling with every path under
each other spelling and listed all of them on each occurrence. An archive
with Foo/ and foo/ subtrees of N files each produced N-entry lists on 2N
occurrences: 4,000 such ZIP members yielded a 120 MB inspect_artifact
result and close to 1 GB of memory. The trie walks also recursed once per
path component, so a ZIP name with tens of thousands of components threw
RangeError.

A collision is now recorded at the segment where spellings diverge and
shared down that subtree by an iterative walk. Each occurrence names the
colliding prefix and the first other spelling, plus a count of further
spellings, each of which is its own occurrence.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:16:16 -07:00
9e22da845b feat(setup): add native Pi client support (#1376)
* feat(setup): add native Pi client support

* fix(setup): isolate invalid Pi agent directory overrides

Keep malformed Pi path evidence on its client entry so unrelated selected clients can complete setup and doctor. Preserve explicit Pi rejection and block filesystem operations rather than falling back to another directory.

* fix(setup): parse Pi configuration as strict JSON

Pi's installed MCP loader reads mcp.json with a bare JSON.parse and no
BOM tolerance, so comments, trailing commas, a BOM, or an empty existing
file yield loader errors and no servers. Parsing the Pi dialect with
objectSchema.parse(JSON.parse(text)) before the shared empty/JSONC
shortcut rejects those files at every mutation boundary instead of
reporting configured registrations Pi cannot load. A missing file still
initializes a fresh strict-JSON document, other dialects keep their
JSONC/BOM/empty tolerance, and malformed files are never rewritten.

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 16:10:39 +08:00
f970b886aa feat: add Hermes as a supported MCP client (#1403)
* feat: add Hermes as a supported MCP client

Hermes Agent reads stdio MCP servers from `mcp_servers.<name>` in
`config.yaml`. REA had no Hermes client, so setup could not register it and
Hermes users had to wire the server up by hand.

- SupportedClients: add the `hermes` format and client definition, resolving
  the config path from HERMES_HOME, else the platform default that Hermes's own
  resolver uses (LOCALAPPDATA/hermes on Windows, ~/.hermes elsewhere), including
  HERMES_DATA_DIR_SUFFIX.
- ClientConfigurationDocument: parse and serialize Hermes YAML, upserting the
  rea entry into the parsed document so user comments and unrelated settings are
  preserved; emit `enabled: true` since Hermes connects entries unless disabled.
- ClientRegistrationStatus: forward the Hermes location variables so status
  checks resolve the same path as setup.
- Tests: cover path resolution on both platforms and the register/read/uninstall
  round trip, and clear the Hermes location variables between tests.

- delilah 🌸

* docs: document the Hermes client and its config path

- delilah 🌸

* refactor(setup): resolve skill destinations per client

* fix(setup): install Hermes skills in the active profile

* fix(setup): identify each client skill action uniquely

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 16:03:25 +08:00
a0e5e9db2b perf(artifacts)!: name each edge's child through its occurrence (#1493)
Every inventory edge is created from one occurrence and copied that
occurrence's artifact_id and logical_path as child_artifact_id and
logical_path. Edges now keep the occurrence_id reference alone. Edge IDs
still hash the same child and path, read from the occurrence, so they are
unchanged; validation and artifact comparison read the occurrence too.

inspect_artifact output: Transmission.app 1.10 MB to 0.97 MB, Visual
Studio Code.app 15.37 MB to 13.48 MB.

BREAKING CHANGE: Artifact inventory edges no longer include
child_artifact_id or logical_path; read them from the occurrence named by
occurrence_id. The graph commitment changes, so inventory Evidence
recorded by earlier versions no longer validates.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:58:05 -07:00
1f692c83e2 perf(artifacts): stop repeating every artifact path as Evidence locations (#1492)
inventory_artifact, inspect_artifact, and extract_artifact copied each
occurrence or extracted file path into Evidence locations, although the
result already names every one. inspect_artifact did so twice, in its own
Evidence and in the nested inventory Evidence. Like other whole-target
Evidence, these now report no locations.

Visual Studio Code.app: inspect_artifact 15.37 MB to 13.07 MB,
extract_artifact 1.40 MB to 1.06 MB.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:47:51 -07:00
YsopwnableandGitHub 782e0147cd fix(javascript): retain returned-reference mutation uncertainty (#1471) 2026-10-10 15:46:24 +08:00
9defed9725 perf(mcp): stop advertising placeholder input descriptions (#1479)
Input schema presentation gave every undescribed property a generic
"Value for <name>." sentence. That only restates the property name, yet
it covered 1,958 properties: 70 KB of the 522 KB of advertised input
schemas that clients load into model context. Authored descriptions,
referenced descriptions, and the name-pattern sentences that add meaning
(maximums, digests, paths, Evidence IDs) remain; other properties now
advertise no description.

The schema validity test now rejects placeholder descriptions instead of
requiring a description on every property.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:32:29 -07:00
5f6bb7a5ba perf(apple): state each NIB object's class, label, and ID once (#1477)
The NIBArchive projection synthesizes customClass, label, and objectID so
its records share the ibtool dictionary parser. The parser then returned
those values as class_name, name, and the object ID, and the graph node
kept the synthesized copies in attributes as well. Attributes now omit a
key whose value its canonical field already carries; differing authored
values stay. Transmission.app decode_interface_builder output shrinks
from 6.45 MB to 6.14 MB.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:31:00 -07:00
morluto 2596f8da14 test(android): retry verified cleanup during fixture teardown 2026-10-10 15:29:42 +08:00
morluto b12d0c6361 test(artifacts): respect destination filesystem case sensitivity 2026-10-10 15:29:42 +08:00
N0zoM1z0 cbcba2902d docs(website): align Blog community links with the site 2026-10-10 15:28:13 +08:00
N0zoM1z0 07d416505c docs(website): finalize the Touhou essay for publication 2026-10-10 15:28:13 +08:00
N0zoM1z0 3ea0233342 docs(website): simplify the Blog introduction 2026-10-10 15:28:13 +08:00
N0zoM1z0 cf6957e796 feat(website): link the Blog from the homepage introduction 2026-10-10 15:28:13 +08:00
N0zoM1z0 ed200a2302 docs(website): emphasize the reconstruction essay takeaways 2026-10-10 15:28:13 +08:00
N0zoM1z0 7df2050606 docs(website): write the Touhou reconstruction essay 2026-10-10 15:28:13 +08:00
N0zoM1z0 130ffdf6bc docs(website): outline the Touhou reconstruction workflow 2026-10-10 15:28:13 +08:00
N0zoM1z0 b09d02d93c feat(website): add a blog for methods and project notes 2026-10-10 15:28:13 +08:00
1f0775684b fix(artifacts): keep case-distinct archive names in inventory (#1480)
ZIP member names are case-sensitive. Inventory was folding them with a
filesystem case rule, so shrunk APKs never became evidence for the Android
application graph. Logical registration now keeps both spellings and records
an English Unicode case-folding limitation. Extraction fails only when the
destination directory already holds the other spelling.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-10 15:21:16 +08:00
7296f2b5bf perf(javascript)!: stop repeating the semantic identifier strategy per fact (#1474)
Every semantic graph node and relation carried an identifier_strategy
object whose schema admits exactly one value per record type. The
constant made up about 9% of analyze_javascript_application output
(Obsidian app.asar: 12.04 MB to 10.96 MB), and semantic traces repeated
it on every returned fact.

The node_id and relation_id schema descriptions now state how each
identifier is derived.

BREAKING CHANGE: Semantic graph nodes and relations no longer include
identifier_strategy, and relation IDs no longer hash that constant.
Evidence recorded by earlier versions does not validate against the new
semantic graph schema.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:13:34 -07:00
3c7b176a3d perf(artifacts): deliver the inspected artifact graph once (#1473)
inspect_artifact nested the complete inventory Evidence and then restated
every artifact node and occurrence as an observation and every edge as a
derived relationship. No caller reads those copies; comparison and tests
use the nested inventory Evidence. On Transmission.app the result shrinks
from 2.46 MB to 1.10 MB.

Observations keep the root manifest and integrity findings.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 00:12:17 -07:00
aa23ec883f feat(clients): register Qwen Code during setup (#1415)
* feat(clients): register Qwen Code during setup

* fix(clients): honor Qwen home and shared skill discovery

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 15:12:09 +08:00
keemsisiandGitHub 934ffd28d1 perf(javascript): derive the application graph ID once
createJavaScriptApplicationGraph hashed the whole graph to derive its
graph_id, then parsed it with the public schema, whose invariant check
hashed the same content again to verify that ID. Validate the content
with every other invariant first, then derive graph_id once from the
validated copy. The public schema still verifies graph_id for stored
and untrusted graphs, and created graphs are unchanged.
2026-10-10 15:09:18 +08:00
79f6756239 docs(website): link the Discord community and REA on X (#1469)
Add an X link beside the GitHub and Discord header icons on every content
page, name the footer links "Join the community" and "Follow us on X", and
close the homepage with a "Join the community" section.

On narrow screens, pad the footer so the floating Top link no longer
covers its last row of links.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 15:00:09 +08:00
YsopwnableandGitHub 78e1308f49 docs(process): clarify normalized terminal line representation 2026-10-10 14:58:15 +08:00
YsopwnableandGitHub 4e3d335439 test(android): retain incomplete cleanup failure reasons (#1443)
Include the full stop disposition in the fixture assertion message, so incomplete owned teardown retains its typed reason in Vitest failure reporters. Preserve the existing cleanup requirement without retries or relaxed ownership checks.

Seven process-boundary tests, full serial typecheck/lint/duplication/format checks, and 19 final-head CI checks pass after integrating the combined-main fixture fix. A controlled failure-rendering probe verifies that the explicit message preserves the reason. The original CI cleanup failure remains unreproduced; this is diagnostic work with a synthetic JADX producer, not a root-cause or real-engine fix.

Refs #1441, #1446, #1448, #1065.
2026-10-10 14:37:49 +08:00
YsopwnableandGitHub ea92328775 fix(mcp): validate doctor probe against its discovered output contract (#1461)
Validate the target-free probe against the named definition discovered from the complete production catalog. Preserve initialized server and inventory observations when the SDK rejects the probe, and retain the schema failure reason, absolute deadline and owned-child cleanup.

The negative stdio replay regression fails on original main and passes the fix; actual production-boundary fault injection confirms rejection. Nine doctor/help tests, serial full static checks and real small-target CLI/MCP parity pass. Successful doctor reports remain byte-identical. No performance or model-token reduction is claimed.

Closes #1454. Refs #1065, #723, #1433.
2026-10-10 14:33:57 +08:00
morlutoandGitHub 28d3cb545c Merge pull request #1463 from morluto/codex/fix-skill-source-discovery
fix(skills): expose authored skill to repository discovery
2026-10-10 14:28:42 +08:00
b118f04492 perf(apple): stop repeating the archive path in Interface Builder evidence (#1460)
Every Interface Builder node and edge evidence record prefixed its
description with the archive's relative path, which artifact_path in the
same record already states. Bundles carry thousands of objects across
localized nibs, so the repeated path made up 6-10% of
decode_interface_builder output (XLD: 7.38 MB to 6.62 MB).

Descriptions now name only the decoded item, such as "object 81" or
"outlet o_quality".

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:21:24 -07:00
ef96657d6b perf(javascript): hash each semantic evidence context once (#1457)
The semantic graph's evidence-context registry canonicalized the full
provenance context three times for every node, relation, unknown and
fingerprint: once to hash its ID and twice more to compare against the
stored row. A file has only a few distinct contexts, so nearly all of
that work repeated a known answer.

Interning now keys contexts by their canonical text. Each fact
canonicalizes once, and only a new context is hashed and checked for a
digest collision. IDs and output are unchanged; Obsidian's 334 MB
Evidence is byte-identical and analysis drops from about 47.0 s to
44.4 s.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:21:07 -07:00
morluto 696fb834b8 fix(skills): expose authored skill to repository discovery 2026-10-10 14:20:22 +08:00
2781cad201 perf(process): stop padding rendered terminal lines to full width (#1450)
Rendered frames padded every visible row with trailing spaces to the
terminal width. Blank rows cost a full row each and every frame repeats
them, so the padding made up 14-39% of capture Evidence (2 KB of sparse
output produced 228 KB). The padding carried no information: columns is
recorded and serialized_state keeps the exact terminal state.

Lines are now trimmed after normalization, so line.padEnd(columns)
restores the previous value. The comparison contract commits
rendered_line_format so older padded captures do not compare as the
same contract.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 23:18:13 -07:00
YsopwnableandGitHub c89c8f5318 docs(mcp): record real Windows first-query recovery 2026-10-10 14:05:56 +08:00
1ec490f361 fix(javascript): stop replaying earlier writes for each object property write
Repeated property writes to one object made member-mutation collection
cubic. Each write evaluated its target binding to rule out a primitive,
and every evaluation folded all earlier mutation paths, copying every
slot once per path. 2,000 writes to one object took 27 s and 4,000 took
203 s.

- A recorded write always leaves a non-primitive binding value, so only
  the first write to a binding needs the primitive check.
- Apply mutation paths per slot in one pass with the same ordering
  semantics instead of one full slot copy per path.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 14:04:31 +08:00
YsopwnableandGitHub 66863b609f test(javascript): reuse comparison node fixtures
Use the established typed graph fixture constructor while retaining right-hand comparison provenance assertions. Restore the unchanged duplicate-code gate on combined main.

Closes #1446. Refs #1434, #1443, #1065.
2026-10-10 14:02:02 +08:00
morlutoandGitHub 817efaca9a Merge pull request #1391 from marnixpluim/fix/electron-import-aliases
fix(javascript): recognize Electron APIs through renamed bindings
2026-10-10 13:57:24 +08:00
morluto 0d2082d36b fix(javascript): recognize unchanged var and let Electron aliases 2026-10-10 13:56:40 +08:00
morlutoandGitHub f1231d4a2c Merge pull request #1382 from BaaRai/fix/cross-branch-multiblock-callee
fix(ghidra): keep the cross-format branch callee multi-block
2026-10-10 13:50:51 +08:00
morlutoandGitHub a957f397ad Merge pull request #1303 from kvalls/codex/windows-ghidra-native-dlls
feat(ghidra): support native PE DLLs on Windows
2026-10-10 13:50:11 +08:00
YsopwnableandGitHub e09cfe9b59 fix(javascript): invalidate references stored through property targets (#1445)
* fix(javascript): invalidate references stored through property targets

* refactor(javascript): share rest keys and return-shape fixtures
2026-10-10 13:47:15 +08:00
morluto ea1dbda1c7 test(ghidra): share result projection client setup 2026-10-10 13:47:06 +08:00
morluto 7633dd8d5d fix(ghidra): publish Windows verification success after cleanup 2026-10-10 13:43:01 +08:00
morluto 941dc425ca chore: merge main into Windows DLL support branch 2026-10-10 13:42:54 +08:00
33b9b31a6f perf(javascript): index change-graph nodes once per comparison
Resolve each compared graph node through a per-side index while preserving right-hand evidence selection and complete comparison results.

Refs #1065.

Co-authored-by: keemsisi <7439375+keemsisi@users.noreply.github.com>
2026-10-10 13:21:13 +08:00
Kaoru0822andGitHub eeb83f6581 perf(cli): defer Playwright and isomorphic-git until a command needs them
Load browser composition after CLI scenario validation and load Git support only for local reference trees with Git metadata. Preserve default outputs and actual command behavior.

Refs #1065.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-10 13:16:44 +08:00
YsopwnableandGitHub bb6fa1c6f5 docs(process): verify independent full-report hashing budgets (#1440) 2026-10-10 13:13:05 +08:00
YsopwnableandGitHub ce16f7bc95 test(native): verify macOS provenance through real CLI and MCP
Verify five native operations through the public CLI and real SDK stdio MCP using a source-built macOS fixture. Retain normalized provenance, response parity and unchanged input bytes.

Refs #1430, #1065, #723.
2026-10-10 13:05:12 +08:00
YsopwnableandGitHub 0a14ca41b4 fix(javascript): preserve effects through yielded array references (#1437) 2026-10-10 13:00:11 +08:00
YsopwnableandGitHub dc5af6d68f perf(mcp): reuse output validators across catalog refreshes (#1433)
Advertise content- and dialect-bound identities for self-contained output schemas so the SDK can reuse unchanged Ajv validators after complete tools/list refreshes. Preserve explicit IDs and relative reference bases.

Verify changed schemas, availability transitions, reconnects, numeric and selector constraints, explicit IDs, relative references, and advertised dialects through the pinned SDK boundaries.

Refs #1065, #723
2026-10-10 12:49:09 +08:00
0b9815b6e7 docs(skill): save CLI application Evidence and read a summary view (#1429)
The skill's CLI fallback printed the complete application Evidence to
stdout. A real ASAR produces hundreds of megabytes (334 MB for Obsidian),
which an agent then reads into its context. Save the Evidence to a file
and project a summary or module page with inspect-analysis-view instead.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:38:52 -07:00
6375ccaf04 perf(native): record macOS command provenance once in its Evidence (#1430)
inspect_macho, inspect_signature, inspect_plist, list_architectures and
demangle_swift already return their command provenance inside the
normalized result. The provider also copied the same array into
raw_result, so every response carried it twice. raw_result now stays
null, as docs/mcp-contracts.md describes for results without a distinct
provider representation.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:35:50 -07:00
c29931ce81 fix(javascript): scan direct returns without recursive stack growth
Use the shared AST child enumeration with an explicit stack, preserving return order and nested callable boundaries.

Refs #1065.

Co-authored-by: rudycelekli <47457359+rudycelekli@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 12:25:00 +08:00
YsopwnableandGitHub f4a0c1ce95 fix(javascript)!: avoid event payload copies in graph metadata (#1427)
Share the canonical string identity rule with endpoint projection, scope event keys to each emitter, and keep complete event/listener names in properties. Verify real CLI and stdio MCP with large names, registration/removal, distinct emitters, exact name seeds, reserved-prefix values, and unresolved dynamic names.

BREAKING CHANGE: New analyses use digest-based IDs for long or reserved-prefix event names and shorter event/listener display labels. Select IDs from the parent graph and read exact names from event_name properties. Stored graphs and their original IDs remain accepted for semantic tracing.
2026-10-10 12:20:05 +08:00
a9ee2360fd feat(native): inspect oversized retained function dossiers via bounded views
Add caller-selected native dossier facets with preserved Evidence identity, provenance, unknowns and transport recovery.

Refs #1247 and #1065.

Co-authored-by: jhuang-tw <77732008+jhuang-tw@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-10 12:18:50 +08:00
YsopwnableandGitHub 4d95f2b2e7 fix(validation): retain unmatched union correction details
Preserve actionable field paths and schema-declared variants for unknown or missing discriminators.

Closes #1421. Refs #1065.
2026-10-10 12:15:11 +08:00
28595276fa fix(javascript): bound member-mutation paths through reassignment loops
Fixes #1401. Refs #1065. Preserve exact member facts and equal-depth write effects while bounding the observed reassignment-loop expansion.

Validated with the JavaScript semantic/application suite, focused alias regressions, full static checks, real compiled CLI and SDK MCP Notion workflows, and all 20 checks on the final PR head.

Co-Authored-By: Marnix Pluim <286664873+marnixpluim@users.noreply.github.com>
Co-Authored-By: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-10 12:03:13 +08:00
YsopwnableandGitHub 98022a8352 fix(javascript)!: avoid endpoint payload copies in graph metadata (#1423)
Keep exact endpoint observations and request properties while using compact display labels and collision-safe canonical value digests for long artifact-local endpoint keys. Verify real CLI/stdio MCP tracing and version comparison without truncating evidence.

BREAKING CHANGE: New analyses use compact endpoint labels and digest-based IDs for long or reserved-prefix endpoint keys. Select IDs from the parent graph and read full values from endpoint properties. Previously stored graphs retain their original identities and remain valid workflow inputs.
2026-10-10 12:02:24 +08:00
YsopwnableandGitHub 81cdafc132 docs: celebrate 50,000 GitHub stars 🎉 2026-10-10 03:45:42 +00:00
YsopwnableandGitHub 4d8ef3f350 perf(javascript): aggregate semantic family coverage once (#1410)
Reduce repeated semantic relation and unknown family scans while preserving exact complete Evidence and coverage.
2026-10-10 11:30:42 +08:00
ca3131b36c perf(cli): write compact JSON when output is not a terminal (#1413)
`--json` / `--format json` always indented its streamed result. Agents and
scripts read REA through pipes and redirects, where indentation carries no
information: on real application results it added 16-45% model tokens
(o200k proxy) and 25-73% bytes. The skill's CLI fallback uses `--json`.

Indent only when stdout is a TTY, as `gh --json` does; piped or redirected
JSON is compact. The JSON value, `jsonl`, `--filter-output`,
`--full-output` and the token-window paths are unchanged. `jq .` restores
indentation for files.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:29:48 -07:00
YsopwnableandGitHub de8fc67195 fix(javascript): retain shorter literal metadata encodings (#1408)
Choose the shorter complete JSON or digest key and string display label.
Short values keep their existing identities and labels, while large values
retain the payload-copy reduction without an arbitrary truncation limit.
2026-10-10 11:23:47 +08:00
YsopwnableandGitHub 8550913cda fix(javascript)!: stop copying literals into semantic metadata (#1407)
Commit literal values with canonical JSON SHA-256 in semantic role keys
and use a type label for strings. Preserve complete values, provenance and
literal queries while avoiding two payload copies in each string node.

Verify real compiled CLI/default stdio MCP, typed union seeds, empty
strings and trace continuation with a large source-owned fixture.

Refs #723

BREAKING CHANGE: Newly produced semantic literal node IDs use
value-sha256 role keys, and string labels read "string literal". Read exact
values from properties.value and obtain node IDs from the selected parent
graph. Previously stored Evidence and its original IDs remain valid.
2026-10-09 20:00:53 -07:00
1f0f728c63 perf(hopper): stop repeating Hopper replies as raw_result (#1405)
HopperProvider passed the bridge reply as rawResult and, for every
operation except address_to_file_offset, the same object as the result.
Every Hopper Evidence record (decompilation, procedure and string
listings, xrefs, ...) therefore carried its complete result twice, and
an MCP response four times counting its text copy.

raw_result is now null unless REA transformed the reply, which only the
file-offset mapping does; that case keeps Hopper's original reply.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:00:35 -07:00
7623e21ff0 perf(native): record pwntools diagnostics once in their Evidence (#1404)
inspect_binary_layout and inspect_recorded_crash passed the decoded report
as both result and rawResult, so every Evidence record carried the whole
report twice (and an MCP response four times, counting its text copy).
The decoded report is the only representation, so raw_result is now null,
as for other single-representation operations.

The real pwntools verifiers asserted the duplicate; they now assert null.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 20:00:11 -07:00
499e2f54ef perf(evidence): stop copying normalized results into raw_result (#1402)
createAnalysisExecution defaulted an omitted rawResult to a second
complete copy of the result. Every caller that had no distinct provider
representation therefore doubled its Evidence: decode_interface_builder,
inspect_keyed_archive, inspect_asset_catalog, trace_dylib_resolution,
inspect_native_dispatch_metadata, observe_native_calls,
observe_native_ui/capture_native_ui_scenario (including screenshots), and
small Ghidra/IDA lifecycle records. Sibling operations of the same
providers already recorded null.

An omitted rawResult now records null. Normalized results are unchanged.
MCP responses repeat Evidence in text and structured content, so each
response and its share of the 10 MiB transport budget shrink by the same
half; e.g. trace_dylib_resolution on a real app bundle drops from
3,217,119 to 1,612,524 bytes per representation.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:52:54 -07:00
6875d4a64c fix(cli): accept JSON files for web capture and screenshot comparisons (#1397)
compare-web-captures and compare-web-screenshots parsed their arguments as
inline JSON only, unlike every other JSON-input command. Screenshot
artifacts and scenario captures embed base64 PNG bytes, so a typical
viewport screenshot exceeds the command-line length limit (128 KiB per
argument on Linux, 1 MiB total on macOS) and could not be compared from
the CLI at all, while MCP accepts it. A file path was reported as
malformed JSON, and screenshot schema failures returned no issues.

Each argument now accepts inline JSON or a JSON file path through
parseCliJsonInput; file failures keep its path diagnostics, malformed
inline JSON keeps the field issue, and screenshot validation reports
projected schema issues. The tests share one CLI JSON process fixture.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:29:42 -07:00
2b6e9ec03f fix(browser): classify selected web trace file failures by cause (#1396)
trace_web_module_imports and trace_web_source_location reported a missing
or non-file manifest, source map or import map as artifact_operation_failed
("Artifact could not be read or written" / "unsafe or conflicting internal
path"). These are caller selections: report ENOENT/ENOTDIR and non-regular
files as invalid input on the selected field, and EACCES/EPERM as a host
access denial. A missing manifest-derived source file stays an artifact fault.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:29:31 -07:00
498cec042a fix(cli): stop advertising multi-letter single-dash option aliases (#1395)
Incur's `alias` map registers one-letter short flags and already accepts
kebab-case spellings of camelCase options. Twenty options registered their
kebab-case long name as an "alias", so help and completions advertised
flags such as `-case-sensitive` and `-relative-path` that the parser reads
as stacked short flags and rejects with "Unknown flag: -c".

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:29:20 -07:00
Minghang ChamlingandGitHub 5fc4d792ca fix(javascript): handle oversized inline source maps (#1386)
* fix(javascript): handle oversized inline source maps

* fix(javascript): avoid source map directive regex overflow
2026-10-10 10:24:38 +08:00
Claude e4a8e0b728 fix(javascript): recognize Electron APIs through renamed bindings
Electron recognition matched callee spellings, so a bundler rename such as
esbuild's `import { ipcMain as ipcMain2 } from "electron"`, or a destructured
`const { contextBridge: bridge } = require("electron")`, hid every IPC
handler, BrowserWindow, contextBridge and utility process behind it.

Resolve each call and construction root lexically to its Electron import or
require origin, and classify the callee under that export's name. Shadowed
locals keep their own meaning.

On Hermes Desktop v0.21.6, whose main process is one esbuild ESM bundle,
recognized main IPC handlers rise from 1 to 204, BrowserWindow constructions
from 0 to 11, and paired renderer transmissions from 1 to 201.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XPY2GmufMNGQKoEgRUx1pd
2026-10-10 00:44:32 +00:00
GRAB Racem e17290cd2a ci: re-run the suite on the corrected main checkpoint
b8a8190b restored the guarded-mutation uncertainty the failing test
encodes, so the shard should pass against the new merge base.
2026-10-10 02:34:52 +02:00
GRAB Racem 40f632a155 ci: re-run the suite after the main-branch shard flake
The failed shard is the JavaScriptSemanticGraphBuilder short-circuit
mutation test, which also failed on main run 38003459598 at the same
base commit (08ec2bf8) before this branch started CI, and passed on
main run 38003459600 minutes later at the same commit.
2026-10-10 02:06:15 +02:00
morluto 7aa4d768eb chore(release): sync corrected 6.3 checkpoint 2026-10-10 07:57:04 +08:00
morlutoandGitHub 74cf9e1401 Merge pull request #1383 from morluto/release-please--branches--release/6.3.0--components--rea-agents
chore(release/6.3.0): release rea-agents 6.3.0
2026-10-10 07:56:11 +08:00
morluto bf58eac4ef docs(release): restore complete 6.3 migration and ancestry notes 2026-10-10 07:42:17 +08:00
github-actions[bot]andGitHub 565f2efa03 chore(release/6.3.0): release rea-agents 6.3.0 2026-10-09 23:41:35 +00:00
morluto b8a8190b2f fix(javascript): retain conditional mutation ordering uncertainty 2026-10-10 07:40:25 +08:00
GRAB Racem e10c934d5a fix(ghidra): keep the cross-format branch callee multi-block
The cross-format oracle requires a callee whose recovered control flow
has more than one basic block, and rea_cross_branch provided it through
a symmetric if/else of tail calls. Clang 21 folds that shape into a
conditional negate plus one tail branch, a single basic block, so the
lane rejected a correct Ghidra analysis of the fixture.

Give the branch a loop whose trip count depends on a volatile global:
no compiler can eliminate the backedge, and the callee stays multi-block
at every optimization level on every toolchain.
2026-10-10 01:36:11 +02:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
08ec2bf82f chore(main): release rea-agents 6.3.0 (#1341)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-10 07:14:55 +08:00
morluto 001851fde6 fix(javascript): preserve capture-time guards and ordering 2026-10-10 07:13:48 +08:00
39dabd0608 fix(mcp): advertise object roots for union input schemas (#1373)
* fix(mcp): advertise object roots for union input schemas

Anthropic tool input schemas reject anyOf, oneOf, and allOf at the root.
Since 63bf9140 removed root flattening, compare_web_captures,
inspect_web_page, inspect_electron_page, and
project_managed_application_graph advertised root unions: Claude Desktop
disabled compare_web_captures and Claude Code exposed the tools without
parameters.

Present a root union of plain-reference object branches as one strict
object with the union of properties, shared required fields, a
minProperties bound, and a description of the accepted input groups. The
canonical Zod union still validates every call, so mixed input groups are
rejected before the handler runs. Branches whose reference siblings cannot
be merged keep their root alternatives.

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

* test(browser): keep comparison input boundary within lint limits

Express advertised and runtime expectations as one case table so the
boundary test stays under the 150-line function limit.

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

* fix(mcp): preserve input group dependencies in object schemas

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 07:03:12 +08:00
BaaRaiandGitHub 73a664bc78 fix(ghidra): verify dense jump tables on an optimized fixture (#1374)
The dense jump-table oracles (inspect-native-api CLI and the
analyze_function dossier) ran against the -O0 debug fixture, which
assumes the host compiler lowers dense switches to tables at -O0. GCC 16
and later expand them as compare chains instead, so on those hosts the
lane rejected a correct provider and Ghidra build with empty
jump_tables.

Build the same inventory source once more at -O2 as a dedicated
jump-table variant, run both strict dense oracles there, and keep the
debug dossier at its complete generic shape. The dedicated switch lane
already compiles at -O2 for the same reason.
2026-10-10 06:58:29 +08:00
355a292198 fix(javascript): preserve uncertainty after references escape to calls (#1292)
* fix(javascript): preserve uncertainty after references escape to calls

* fix(javascript): track iterator root escapes and preserve static captures

* fix(javascript): scope comparison unknowns to their evidence

* fix(javascript): track parameter origins at function body entry

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 06:53:42 +08:00
Akshit KhokhaniandGitHub d0e606930a fix(javascript): honor module-sync package exports (#1361) 2026-10-10 06:49:43 +08:00
You WishandGitHub a9f5dad5a8 fix(javascript): resolve exported callables through lexical bindings (#1351)
* fix(javascript): resolve exported callables through lexical bindings

* fix(javascript): preserve export scope and hoisted writes

* test(javascript): consolidate export binding assertions

* fix(javascript): account for skipped initializers and loop binding writes

* fix(javascript): preserve parameters copied into body variables
2026-10-10 06:39:56 +08:00
You WishandGitHub 1c0cc8a675 fix(snapshot): preserve complete investigation revision histories (#1354)
Select residual unknown histories as complete units and retain referenced registry mutation Evidence regardless of the active target at edit time. Prune incompatible dependency histories atomically instead of retaining stale dispositions.

Verify public MCP save/read/reopen for verified, withdrawn, and out-of-scope resolutions, and document target scope rules.
2026-10-10 06:39:29 +08:00
f504c2a351 fix(javascript): decline source-map UNC references with an unusable host (#1372)
* fix(javascript): decline source-map UNC references with an unusable host

A source map can name a Windows share whose host a file URL cannot carry,
such as `\\bad host\share\a.js`. On the Node builds `engines` admits,
`pathToFileURL(path, { windows: true })` fails a native assertion and calls
`abort()` on Node 22.19-22.22, 24.11-24.15 and 26.0, so the process dies
with exit 134 instead of declining the reference. Node 22.23 and 24.16 raise
`ERR_INVALID_URL` instead, and older builds silently drop the host, so the
same reference resolves three different ways depending on the runtime.

Validate the UNC host before handing the path to Node. A host carrying a
forbidden host code point, a percent escape or nothing at all now resolves as
`unresolved` on every admitted build, and `npm test` passes the existing
`\\bad host\share\a.js` row everywhere. Well-formed UNC hosts and
drive-letter paths are untouched.

* fix(javascript): validate UNC hosts through IDNA before conversion

Reject Unicode source-map UNC hosts that URL/IDNA processing cannot use or normalizes to an empty hostname before calling Windows pathToFileURL. Keep the original source identity and preserve usable normalized hosts.

Exercise the built reference resolver in owned subprocesses, including U+00AD and U+200C as source names and source roots. The original PR implementation aborts under Node 22.22.2; the new regression isolates those signals from the test runner. Add this test to the existing Node 22 Windows CI step.

Validation: 64 focused tests pass on Node 22.22.2 and 24.18.0; npm run check and test discovery pass. Local verification ran on macOS; Windows verification remains with CI.

---------

Co-authored-by: Yi-111-a <yi-111-a@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-10 06:38:47 +08:00
You WishandGitHub f91f2798b4 fix(process): keep unobserved file contents unknown (#1358) 2026-10-10 06:36:35 +08:00
keemsisiandGitHub 037709a52c perf(javascript): validate the version change graph once (#1370)
compareJavaScriptApplicationVersions built the change graph with
createJavaScriptApplicationGraph, which validates it and re-derives
every node, observation, edge and graph ID, then parsed the result
with a schema that embeds the full graph schema, repeating all of
that work. Seal the change graph with the owned immutable factory and
accept that exact sealed graph in the result parse, as owned analysis
results already do. Items, coverage and the public result schema are
unchanged; output is byte-identical.
2026-10-10 06:34:21 +08:00
morluto 810107a2ad fix(cli): stream JSON results at the shared command boundary
Route ordinary CLI results through the bounded JSON writer after command registration, including managed member inspection. Remove JavaScript-specific output plumbing while preserving filters, envelopes, cancellation, and failure exits.

Measure formatted UTF-16 expansion before Incur token counting and return resource_constraint above the runtime string limit, with recovery guidance.

Validate output above the real V8 string limit by SHA-256 and exercise the compiled managed provider. Clean-worktree validation: npm run check; 76 focused tests passed, with 2 optional-provider skips; test discovery passed.

Fixes #1371.
2026-10-10 06:23:26 +08:00
morluto ecc67cab2d ci: enforce architecture guards with portable checkout paths 2026-10-10 06:20:28 +08:00
morluto 4bcea1aa76 fix(javascript): retain array identity after length mutations
Keep unknown element coverage on arrays whose length may have changed, preserving intrinsic length presence and subsequent slot mutations through semantic graph and export-return consumers.
2026-10-10 06:20:28 +08:00
morluto 4951a897c5 fix(browser)!: preserve payload shapes and WebMCP declarations
Retain primitive and nested array types with typed paths, and compare only mutually observed body shapes while preserving selected coverage uncertainty. Return full untrusted WebMCP input declarations with canonical digests, without resolving references or invoking tools.

BREAKING CHANGE: JSON shape paths now contain typed property and array-element segments. WebMCP input_schema_shape is replaced by input_schema and input_schema_sha256, retaining declared examples and defaults.
2026-10-10 06:20:28 +08:00
morluto d79317cda0 fix(artifacts): bind ASAR interpretation to owned snapshots
Verify captured container bytes against their inventoried digest before listing or reading packed members. Isolate per-reader ASAR metadata, preserve original unpacked companions, and retain complete inventories when snapshot cleanup fails.
2026-10-10 06:20:28 +08:00
BaaRaiandGitHub bf934d5592 fix(hopper): probe interior navigation from multi-byte instructions (#1285)
The real-Hopper navigation probe derived its interior coordinate as
anchor + 1, which assumes the fixture procedure's first instruction is
longer than one byte. Host toolchains without endbr64-style prologue
padding (Kali gcc 16, or any build with -fcf-protection=none) compile
rea_entry to start with the one-byte push rbp, so anchor + 1 is itself
an instruction boundary: goto_address correctly observes that boundary
and the boundary-contract run rejects a correct bridge.

Advance the probe to the first instruction followed by a coordinate gap
larger than one byte and derive the interior-coordinate assertions from
that instruction, so the probed coordinate is never an analyzed-object
boundary on either prologue encoding.
2026-10-10 06:07:01 +08:00
morluto 392f1f3107 refactor: consolidate boundary semantics and prune redundant tests
Share parser modes and collision-free composite keys, enforce architecture guards, and consolidate redundant unit assertions into filesystem, CLI, MCP, and producer-backed workflows. Preserve concurrent upstream boundary fixes and exclude legacy Objective-C class-name bookkeeping labels.

Validation: source/composition suites (3358 passing), focused canonical digest and MCP checks, typecheck/lint, Knip, formatting, architecture guards, and real Foundation archive and Apple legacy simulator CLI/MCP verification. No real Hopper, Ghidra, or IDA verification claim.
2026-10-10 05:56:01 +08:00
morluto 077d6c407b docs: correct MCP error and capture import guidance 2026-10-10 05:41:52 +08:00
morluto 7a0c800851 docs: remove retired architecture and migration artifacts 2026-10-10 05:41:45 +08:00
morluto 7738c1f6a9 docs: add repository-local REA tool design skill 2026-10-10 05:30:02 +08:00
morluto 5d79387505 docs: prune repeated contributor and tool design instructions 2026-10-10 05:28:13 +08:00
morluto ba4422296d docs: consolidate agent guidance around ownership and boundaries 2026-10-10 05:22:35 +08:00
morluto 614fb7681e fix(evidence): order canonical projections independently of locale 2026-10-10 05:13:53 +08:00
morluto 0f10499245 refactor(javascript): share Babel child traversal 2026-10-10 05:13:53 +08:00
morluto 617cd84d27 fix(browser): retain malformed redirect diagnostics 2026-10-10 05:13:53 +08:00
morluto abf5e243c4 fix(update): preserve disabled client registrations 2026-10-10 05:13:53 +08:00
morluto 5aa200285a fix(artifacts): infer legacy Mach-O simulator platforms 2026-10-10 05:13:53 +08:00
morluto 5751f5caac fix(artifacts): preserve archive facts and Unicode path identity 2026-10-10 05:13:53 +08:00
morluto 70bad53847 fix(native): distinguish symbol definitions from metadata 2026-10-10 05:13:53 +08:00
morluto 890bb66b35 fix(ida): compare admitted document paths consistently 2026-10-10 05:13:53 +08:00
YsopwnableandGitHub 53ed942a85 fix(mcp): preserve JavaScript workflow identity validation (#1366)
Preserve canonical distinct-source and unique-native-observation refinements after resolving inline or retained JavaScript workflow inputs. The shared application entry points now return structured invalid_request errors before graph parsing and computation, avoiding another complete graph capture.

Six focused tests, actual compiled CLI/SDK stdio workflows, JSON Schema dialect checks, static/document checks, and a real Notion ASAR analysis/recovery/trace/close workflow passed. All 20 final-head checks, including real JavaScript recovery, passed. Native-provider acceptance is not claimed for this provider-neutral validation change.

Fixes #1364
Refs #1065
2026-10-10 05:11:38 +08:00
YsopwnableandGitHub 6ce3288f3b fix(cli): stream JSON inputs beyond the whole-document string limit (#1360)
Stream large CLI JSON files through a strict UTF-8 decoder and standard JSON parser using the same admitted regular-file handle. Preserve native parsing for small inputs, typed malformed-input/resource/access-denied errors, cancellation, and complete Evidence.

Verified with focused public CLI regressions, a 768 MB whitespace-padded valid request, and the Windows native decoder boundary. Individual strings and the assembled object graph remain subject to native runtime limits. All 27 final-head checks passed.

Refs #1331
2026-10-10 04:53:09 +08:00
Dery FerdikaandGitHub 3728c8267b fix(ghidra): reject a native decompiler built for another host (#1280)
Reject positively identified foreign-only Ghidra decompiler binaries and non-regular native prerequisites before provider startup, while retaining unknown classifications for incomplete or unrecognized headers.

Verified with 54 focused tests and real Linux Ghidra CLI/MCP admission, decompilation, cleanup, wrong-host PE rejection, and non-blocking FIFO rejection. All 19 final-head checks passed.

Fixes #1192

Co-authored-by: Dery Ferdika <114888155+DeryFerd@users.noreply.github.com>
2026-10-10 04:52:25 +08:00
f39e71ce18 fix(skill): pin packaged commands to the shipping package version (#1346)
Fixes #1338.

Use canonical product identity for bundled command versions and keep build-cache fixtures aligned. Verified 10 focused tests, actual CLI installation/repair/uninstall scenarios and all 19 final-head CI checks.

Co-authored-by: Yi-111-a <97448247+Yi-111-a@users.noreply.github.com>
2026-10-10 04:47:10 +08:00
morluto 048b79878c test(native): retain trace diagnostics when observed hits differ 2026-10-10 04:39:17 +08:00
morluto 7ad353fa8b fix(native): retain LLDB cleanup ownership through client close 2026-10-10 04:35:03 +08:00
morluto 0bfb6e00ab test(filesystem): bound FIFO regressions at consumers 2026-10-10 04:23:03 +08:00
morluto 5291bca108 refactor(artifacts): remove unused root classifier 2026-10-10 04:16:29 +08:00
morluto 7829b1aeef fix(filesystem): reject unstable artifact targets 2026-10-10 04:14:54 +08:00
morluto 66a20a2597 test(managed): include shared dossier fixture in artifact inputs 2026-10-10 04:09:45 +08:00
morluto 5b3715ef82 docs: correct README setup and runtime guidance 2026-10-10 04:08:05 +08:00
morluto 37fcea78ce fix(cli): avoid duplicate primary cleanup diagnostics 2026-10-10 04:02:41 +08:00
morluto ac356c46ad test(javascript): share semantic graph test facts 2026-10-10 04:02:41 +08:00
morluto ca9010936a test(package): share validated native dossier fixtures 2026-10-10 04:02:40 +08:00
morluto 5d32e42529 test(cli): remove duplicate malformed JSON assertion 2026-10-10 03:53:12 +08:00
morluto 79d5b9a826 test(process): report cleanup details on cancellation failures 2026-10-10 03:52:35 +08:00
morluto 961c3c3de7 test(android): allow provider readiness under load 2026-10-10 03:52:35 +08:00
morluto d761d7358b test(ghidra): allow rollback tests to reach spawned process 2026-10-10 03:52:35 +08:00
morluto 006b295f1d refactor(javascript): parse runtime evidence into one verified owner 2026-10-10 03:52:35 +08:00
morluto 415145d04f fix(process)!: retain per-file digest open failures
BREAKING CHANGE: Filesystem digest omission entries now require system_code; budget and changed-file omissions use null, and unavailable-file omissions preserve the operating-system error code.
2026-10-10 03:52:35 +08:00
morluto f62b44971d fix(mcp): advertise primitive semantic literal seeds 2026-10-10 03:52:35 +08:00
morluto 218c13160e fix: report malformed application evidence as input errors 2026-10-10 03:52:35 +08:00
morluto 55a46f7c71 fix(javascript): resolve query-only HTML references to their document 2026-10-10 03:52:35 +08:00
morluto 08daf056cc fix(cli): classify JSON input permission denials 2026-10-10 03:52:35 +08:00
morluto a4ba8aecd5 fix(contracts)!: require observed provider output metadata
Reject omitted segment bounds, procedure classification and body facts, unresolved-call observations, dossier facets, and Ghidra parameter flow metadata. Providers emit explicit nulls for unsupported facets. Verify those unknowns in the real Hopper workflow.

BREAKING CHANGE: Provider analysis outputs must explicitly supply metadata previously repaired with defaults; unsupported nullable facets must be reported as null.
2026-10-10 03:52:13 +08:00
morluto e3bbb9ac45 refactor(javascript)!: share semantic evidence at fact construction
Intern shared provenance in a graph-scoped context registry while retaining exact locations on every fact. Semantic traces carry their referenced context subset, and portable graph validation rejects stale or dangling commitments.

BREAKING CHANGE: Semantic graph facts now store evidence context IDs and locations. Graph and semantic trace results require an inline evidence_contexts table.
2026-10-10 03:52:13 +08:00
YsopwnableandGitHub 9c4a68bc19 fix(json): preserve runtime limits across JSON file readers (#1350)
* fix(cli): preserve runtime JSON string-limit diagnostics

* test(json): check actionable oversized Evidence recovery

* fix(json): decode large UTF-8 inputs by character length

* test(json): reject truncated UTF-8 after large input decode
2026-10-09 19:39:35 +00:00
morluto 750fb65650 refactor(artifacts): test inventory changes at materialization boundary 2026-10-10 02:49:46 +08:00
morluto e36afa112f docs(contracts)!: explain canonical URL and skill metadata ownership
BREAKING CHANGE: source-map URLs now live in target observations selected by declared_url_sha256, and doctor skill identity no longer emits installed_catalog_digest. Use the documented observation join and identity.skill.state instead.
2026-10-10 02:49:46 +08:00
morluto a959a8309d test(json): remove assertions covered by CLI output consumers 2026-10-10 02:49:46 +08:00
morluto c867bcd0aa test(javascript): share primitive expansion producer fixtures 2026-10-10 02:49:46 +08:00
morluto 449d57075e refactor(javascript)!: remove obsolete scope truncation statistic
BREAKING CHANGE: remove the never-incremented truncated_scopes statistic from JavaScript application analysis results and schemas.
2026-10-10 02:49:46 +08:00
morluto b4a19193fe fix(setup): install the skill for Claude Code 2026-10-10 02:49:46 +08:00
morluto ed8fcae94b fix(javascript): store source map URLs once 2026-10-10 02:49:46 +08:00
morluto 7915ee5178 feat(javascript): record Electron integrity mismatches 2026-10-10 02:49:46 +08:00
morluto f0dc233d64 fix(setup): recognize supported Nobara hosts 2026-10-10 02:49:46 +08:00
morluto f7cf4c890d fix(cli): classify oversized JSON inputs 2026-10-10 02:49:46 +08:00
morluto db171be6e5 fix(javascript): preserve agreeing module provenance 2026-10-10 02:49:46 +08:00
2793672ee2 fix(skill): pin packaged commands to the shipping package version
The generated skill rewrote `rea-agents@latest` to the version it ships with, so a pinned install no longer needs a local edit that `doctor --skill` reports as stale.

Co-Authored-By: OpenCode <opencode@opencode.ai>
2026-10-10 02:49:46 +08:00
LucienandGitHub 1ac8389c5c test(artifacts): verify extraction races with real filesystem changes
Co-authored-by: dakjdakd <164857476+dakjdakd@users.noreply.github.com>
2026-10-10 02:38:33 +08:00
LucienandGitHub f6cfbfcc55 fix(browser): release attached viewport overrides without resizing the external page
Co-authored-by: dakjdakd <164857476+dakjdakd@users.noreply.github.com>
2026-10-10 02:33:56 +08:00
YsopwnableandGitHub 6c9161d617 docs: explain CI scope and native runner reuse (#1348) 2026-10-09 18:28:43 +00:00
YsopwnableandGitHub d5cb8aee06 fix(ci): scope verification and reuse native runners (#1344)
* fix(ci): scope documentation checks and cancel superseded runs

* ci: reuse package runners for native Inspector checks

* test(ci): share deterministic workflow Git fixtures
2026-10-09 18:22:03 +00:00
You WishandGitHub 1c123493a2 fix(hopper): allow restart after verified owned-provider shutdown
Co-authored-by: YouWish <29498139+Y0UW1SH@users.noreply.github.com>
2026-10-10 02:12:33 +08:00
keemsisiandGitHub b1e85ad711 perf(javascript): index version relationships once per comparison (#1347)
relationshipSignature rebuilt a node map and scanned every graph edge
for each side of each matched pair, so comparison cost grew as
pairs x (nodes + edges). Build node and adjacency indexes once per
graph in ItemContext; signatures, sorting and output are unchanged.
At 4000 matched modules, end-to-end compare: 5.7s -> 2.9s (2 edges
per node) and 10.4s -> 5.8s (6 edges per node); 8000: 3.3x and 2.5x.
Output JSON is byte-identical on the base commit.
2026-10-10 02:07:30 +08:00
3f59a84bd1 fix(contracts): advertise NUL with a portable hex escape
Use the equivalent hex NUL spelling in named public contracts while preserving current path and reserved-name validation. Verify converted JSON Schema and real stdio catalog consumers.

Closes #1329

Co-authored-by: Yi-111-a <97448247+Yi-111-a@users.noreply.github.com>
2026-10-10 01:54:42 +08:00
You WishandGitHub 5f16124a31 fix(files): reject nonregular capture and JSON inputs
Verify selected files through a nonblocking opened handle before reading. Preserve regular-file symlinks and return actionable CLI/MCP diagnostics without publishing output.

Co-authored-by: YouWish <29498139+Y0UW1SH@users.noreply.github.com>
2026-10-10 01:49:54 +08:00
morluto cfce91d418 fix(browser): serialize attached scenarios through cleanup settlement 2026-10-10 01:45:01 +08:00
morluto 4940a867e2 test(process): use owned CLI and workspace fixtures 2026-10-10 01:45:01 +08:00
morluto 74be52611e test(process): publish capture readiness atomically 2026-10-10 01:45:01 +08:00
morluto 377df715ea refactor(reference): simplify malformed UTF-8 handling 2026-10-10 01:45:01 +08:00
morluto 5a61562dc2 test(browser): report redirect status cases independently 2026-10-10 01:45:01 +08:00
morluto 96b2b245fd test(javascript): verify distinct module origins through reconstruction 2026-10-10 01:45:01 +08:00
morluto 41a228c1b0 fix(electron): preserve unrepresentable numeric option evidence 2026-10-10 01:45:01 +08:00
morluto 3e19875c7f fix(javascript): retain unresolved value frontiers in provenance queries 2026-10-10 01:45:01 +08:00
morluto b628bba1fa refactor(javascript): normalize erased expression syntax once 2026-10-10 01:45:01 +08:00
morluto cfb12e47dc fix(artifacts): validate only active extraction entries 2026-10-10 01:45:00 +08:00
ACandmorluto 7a4f2685d4 fix(javascript): reject invalid package exports configurations 2026-10-10 01:45:00 +08:00
ACandmorluto 2b4abbf1cc fix(javascript): distinguish prefix-only builtins from packages 2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 9367dc13bd test(browser): avoid duplicating source-map listener setup
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 82bbe74333 fix(browser): follow only HTTP redirect statuses for source maps
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto f166a2ae15 fix(reference): report malformed UTF-8 before import parsing
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 9055bd695b fix(javascript): avoid positive-zero evidence for signed zero 2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 2bd7de6f8c fix(javascript): retain distinct module provenance path components 2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto e995b19f83 fix(javascript): preserve semantic evidence through satisfies 2026-10-10 01:45:00 +08:00
Rudy Celekliandmorluto 4896adcd0f fix(javascript): parse declaration artifacts in ambient mode 2026-10-10 01:45:00 +08:00
dakjdakdandmorluto a0523b375e fix(browser): retain attached scenario emulation until cleanup 2026-10-10 01:45:00 +08:00
dakjdakdandmorluto 5e8fb531e2 fix(artifacts): reject incomplete inventoried extraction 2026-10-10 01:45:00 +08:00
YsopwnableandGitHub 3edb2172de Merge pull request #1334 from morluto/docs/celebrate-40000-stars
docs: celebrate 40,000 GitHub stars 🎉
2026-10-10 01:35:02 +08:00
YsopwnableandGitHub 8c1bec42ba chore(release): sync 6.2.0 checkpoint into main (#1340)
Preserve the published 6.2.0 tag ancestry and main's later implementation changes.
2026-10-10 01:31:46 +08:00
N0zoM1z0 0c3aa98a3e chore(release): sync 6.2.0 checkpoint into main 2026-10-09 17:13:44 +00:00
morluto 8c96baab80 refactor(catalog): import CLI metadata from its owner 2026-10-10 00:49:14 +08:00
morluto 4144e454f3 refactor: remove single-use forwarding helpers 2026-10-10 00:49:14 +08:00
morluto 070339af50 refactor(process): remove duplicate observation and trace entry points 2026-10-10 00:49:14 +08:00
morluto d1983a4576 refactor(browser): open scenario sessions without a factory wrapper 2026-10-10 00:49:14 +08:00
morluto 87f0051496 refactor(providers): use canonical artifact and managed identities 2026-10-10 00:49:14 +08:00
N0zoM1z0 5ecc98a5ea docs: celebrate 40,000 GitHub stars 🎉 2026-10-09 16:43:35 +00:00
1b73b5ab4b fix(native): refuse to list architectures of non-Mach-O targets (#1325)
list_architectures ran lipo on every admitted target. For a PE DLL, ELF
binary or plist, lipo's refusal surfaced as execution_failure with
"Retry once; if it continues, run rea doctor", which neither can fix.
Refuse non-Mach-O targets as capability_unavailable before running
lipo, as inspect_macho already does.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:41:03 -07:00
56598beb4e perf(json): encode streamed JSON iteratively (#1322)
The streamed JSON encoder delegated every token through one recursive
generator per nesting level and yielded each token separately. Writing
analyze-javascript-application output for Typora (873 MB) spent 22 of
66 s there. Encode with an explicit stack into bounded 16 KiB parts:
identical bytes, 3-6x faster encoding, and the same laziness, error
and surrogate-pair guarantees.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:40:45 -07:00
morluto d83cbd2abf test: share snapshot replay and managed graph fixtures 2026-10-10 00:35:17 +08:00
morluto a27794c246 fix(artifacts): retain DMG ownership through uncertain attachment 2026-10-10 00:35:17 +08:00
morluto 35f121f4ac fix: retain completed observations when later analysis steps fail 2026-10-10 00:35:17 +08:00
morluto e11f4d371a fix(mcp): admit composed analysis through result bookkeeping 2026-10-10 00:35:17 +08:00
morluto e64678e8f9 fix(mcp): retry failed shutdown resources and retain failure reasons 2026-10-10 00:35:17 +08:00
morluto 25711ad259 test: exercise source test selection through Git and Vitest 2026-10-10 00:35:17 +08:00
morluto f3c4a332f7 fix(targets): cancel resolution before provider admission 2026-10-10 00:35:17 +08:00
morluto 44c92f88c5 refactor: remove obsolete source exclusions and identity wrapper 2026-10-10 00:35:17 +08:00
morluto 07675f78c6 fix(ghidra): retain process ownership after failed launch rollback 2026-10-10 00:35:17 +08:00
morluto cc7b5af077 fix(managed): bind graph facts to their source Evidence 2026-10-10 00:35:17 +08:00
morluto b112d44a39 fix(native)!: preserve unknown Objective-C metadata
BREAKING CHANGE: Objective-C attribute tokens now contain only name and value. Properties report nullable atomicity and readonly facts; class flags, ivar counts, and method requirement flags are nullable when unobserved.
2026-10-10 00:35:16 +08:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>N0zoM1z0
a64851f259 chore(release/6.2.0): release rea-agents 6.2.0 (#1305)
* chore(release/6.2.0): release rea-agents 6.2.0

* docs(release): complete 6.2 breaking migration notes

* fix(dev): allow formatter-ignored staged files

* docs(release): include all unreleased mainline entries

* docs(release): note ignored-file hook repair

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <1705004398@qq.com>
2026-10-09 16:17:20 +00:00
morluto e10f1f0901 docs: keep license sections text-only 2026-10-10 00:09:46 +08:00
5d16be2a71 test: share the client registration command to restore the jscpd gate (#1317)
After #1301 merged, main's duplicated-line share rose to 2.503%, over
jscpd's 2.5% threshold, so Static checks fail on every PR. The new OMP
test repeated the dialect test's imports and npx registration command.
Export that command from the shared client test fixture instead.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:09:08 -07:00
morluto ccfbe87e98 docs: align translated README artwork and layout 2026-10-10 00:03:14 +08:00
morluto 4b8e744d90 docs: add README artwork and refine closing sections 2026-10-10 00:00:41 +08:00
8b4c359135 feat(setup): register OMP during setup (#1301)
* feat(setup): register OMP during setup

Add OMP (oh-my-pi) as a setup, doctor and uninstall client. Setup writes
a type: stdio entry to the user-level agent mcp.json that OMP reads,
following PI_CONFIG_DIR, an absolute PI_CODING_AGENT_DIR and the
OMP_PROFILE/PI_PROFILE named profile. It removes rea from OMP's
disabledServers denylist, which would otherwise hide the registration,
and doctor reports a listed registration as stale.

Closes #1257

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

* fix(setup): honor OMP's enabledServers allowlist in doctor

OMP's user enabledServers allowlist forces an entry with enabled: false
on, unless disabledServers also lists it. Doctor reported such a working
registration as stale. Also format the FAQ client list.

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

* fix(setup): keep OMP's allowlisted entry in update maintenance

rea update skipped an owned OMP entry with enabled: false even when
OMP's enabledServers allowlist runs it. Apply the same forced-enable rule
as doctor. Share the client-location environment reset across the client
tests instead of repeating it in each file.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:51:12 -07:00
morluto 24673aaae4 test(mcp): remove arbitrary schema inventory thresholds 2026-10-09 23:35:19 +08:00
morluto 765e809e36 refactor: use canonical implementations and types directly
Remove forwarding wrappers and shadow aliases, migrate callers and verification scripts to their owners, and share one exhaustive semantic resource-bound projection.
2026-10-09 23:35:19 +08:00
morluto 3283a45d09 refactor(captures)!: require canonical producer metadata
Require process retention accounting, browser network transaction identity, and all web comparison dimensions. Remove obsolete omission repairs and derive completeness from the owning producer facts.

BREAKING CHANGE: Historical captures without current producer accounting or transaction identity, and web diffs missing accessibility or storage dimensions, are rejected.
2026-10-09 23:35:19 +08:00
morluto dea3498b2b fix(inspector): retain observations after capture failures 2026-10-09 23:35:19 +08:00
YsopwnableandGitHub c267e99227 docs: explain 6.2 contract and saved-data migration (#1304) 2026-10-09 15:31:11 +00:00
YsopwnableandGitHub 4bb4c6fe6d test(apple): verify compiled Mach-O root occurrence facts (#1300)
test(artifacts): verify compiled Mach-O roles and permissions

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-09 15:24:53 +00:00
kvalls be6863e9a1 feat(ghidra): support native PE DLLs on Windows 2026-10-09 16:11:13 +01:00
You WishandGitHub 411498d45f fix(electron): resolve effective preload after option overrides (#1286) 2026-10-09 08:05:00 -07:00
Kaoru0822andGitHub c3fc6c3aed Merge pull request #1297 from morluto/fix/ghidra-session-root-stability
fix(ghidra): use dot-free private session paths
2026-10-09 07:59:06 -07:00
Kaoru0822andGitHub 1f099a6fc0 Merge pull request #1299 from morluto/fix/schema-patterns-without-lookaround
fix(mcp): advertise input patterns without look-around
2026-10-09 07:58:51 -07:00
Kaoru0822andGitHub 701d90aba4 Merge pull request #1298 from morluto/test/artifacts-direct-macho-root-kind
test(artifacts): pin per-occurrence roles for direct Mach-O roots and shared bytes
2026-10-09 07:54:24 -07:00
Kaoru0822andClaude Opus 5.5 a8701eaf48 fix(mcp): advertise input patterns without look-around
trace_dylib_resolution roots and capture_process_scenario environment
names still advertised negative look-ahead patterns. RE2 and Rust schema
validators reject look-around, so a client using one refuses the whole
tools request, as #1282 reported for the NUL escape. Spell both
constraints as equivalent look-around-free patterns and assert that no
advertised pattern uses look-around or backreferences.

Closes #1282

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:49:22 +00:00
morluto ad59531a96 refactor: remove forwarding exports and redundant aliases 2026-10-09 22:46:09 +08:00
morluto 69c3b32a21 test(mcp): read bundle failures from public error content 2026-10-09 22:46:09 +08:00
morluto 5f749c2096 fix(mcp): only recommend exporting retained evidence 2026-10-09 22:46:09 +08:00
morluto 76b214e45f fix(windows): retain unsettled jobs for cleanup retry 2026-10-09 22:46:09 +08:00
morluto 614e0c2e74 fix(browser): retain scenario observations across failures 2026-10-09 22:46:08 +08:00
morluto 73e98b2516 fix(javascript): preserve alias and container uncertainty 2026-10-09 22:46:08 +08:00
YsopwnableandGitHub 99f257bbf0 Merge pull request #1296 from morluto/feat/website-seo-metadata
feat(website): add search metadata and automatic sitemap
2026-10-09 22:43:41 +08:00
Kaoru0822andClaude Opus 5.5 b9e29c52d4 test(artifacts): pin per-occurrence roles for direct Mach-O roots and shared bytes
Both reported failures were fixed by 63bf9140, which moved kind and
executable facts from content nodes to occurrences, but neither
reproduction had a regression test. Pin the direct-file Mach-O root kind
and permission against its bundle occurrence, and the Apple JavaScript
component and runtime family next to byte-identical text resources.

Refs #1234
Refs #1235

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:39:51 +00:00
N0zoM1z0 1c3766a8bc test(ghidra): preserve selected verification resource limits 2026-10-09 14:37:06 +00:00
Kaoru0822andGitHub 098d76900e Merge pull request #1291 from morluto/fix/process-port-normalization-sentence-period
fix(process): normalize ports that end a sentence
2026-10-09 07:34:54 -07:00
Kaoru0822andGitHub 2ddd9456cd Merge pull request #1295 from morluto/fix/javascript-html-url-whitespace-admission
fix(javascript): reject encoded separators joined by HTML URL whitespace
2026-10-09 07:34:39 -07:00
N0zoM1z0 43405f9ffe Merge remote-tracking branch 'origin/main' into feat/website-seo-metadata 2026-10-09 22:33:04 +08:00
Kaoru0822andGitHub 6020a0b368 Merge pull request #1294 from morluto/test/process-contract-rejections-concurrent
test(process): check malformed capture choices concurrently
2026-10-09 07:31:08 -07:00
Kaoru0822andGitHub fe34ec2ef3 Merge pull request #1288 from morluto/fix/mcp-error-text-budget
fix(mcp): measure tool errors against their text-only delivery
2026-10-09 07:30:48 -07:00
Kaoru0822andClaude Opus 5.5 ad813e473b fix(process): treat non-ASCII letters as port continuations
\w is ASCII-only even with the u flag, so "port: 8080.β" was treated as
a sentence-ending port. Use Unicode letter and number classes for the
port boundary checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:28:19 +00:00
N0zoM1z0 1e341973cf test(ghidra): size oversized annotations for canonical delivery 2026-10-09 14:21:38 +00:00
Kaoru0822andGitHub 69833fb0d0 Merge pull request #1293 from morluto/fix/process-capture-terminal-byte-accounting
fix(process): validate terminal byte totals against retained frames
2026-10-09 07:20:08 -07:00
Kaoru0822andClaude Opus 5.5 184ed970b9 fix(process): keep ports before a chunk-final period
PTY chunks are normalized independently. A period that ends a chunk may
begin a decimal continued in the next chunk ("port: 80." then "5"), so
leave such a port unnormalized instead of masking the decimal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:19:37 +00:00
N0zoM1z0 8c9c5550d0 Merge remote-tracking branch 'origin/main' into feat/website-seo-metadata 2026-10-09 22:19:04 +08:00
Kaoru0822andClaude Opus 5.5 fb57c8643f fix(javascript): reject encoded separators joined by HTML URL whitespace
#1287 removes URL tabs and newlines from an HTML script URL before
percent-decoding. A declaration such as %2<newline>fapp.js passed the
raw admission check and then decoded to a separator, resolving to a
file the encoded-separator rule must refuse. Apply canonical path
admission again to the parsed URL text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:18:39 +00:00
Kaoru0822andClaude Opus 5.5 48de11ce2e test(process): check malformed capture choices concurrently
The malformed process-choice acceptance test spawned 26 CLI processes one
after another. On CI it took 45-59 s against its 60 s deadline and timed
out on unrelated PRs. Run the independent cases concurrently, each with
its own scenario file; every assertion is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:17:27 +00:00
Kaoru0822andGitHub b80bd2db96 Merge pull request #1289 from morluto/fix/ghidra-address-verifier-error-envelope
fix(ghidra): stop dereferencing the removed error payload in address verification
2026-10-09 07:14:32 -07:00
Kaoru0822andGitHub d601b8016e Merge pull request #1287 from morluto/fix/javascript-html-script-url-decoding
fix(javascript): resolve HTML script URLs after URL whitespace and percent decoding
2026-10-09 07:13:13 -07:00
Kaoru0822andClaude Opus 5.5 39eb0587c9 fix(process): validate terminal byte totals against retained frames
parseProcessCapture accepted terminal retention accounting that its
retained frames contradict: any retained_bytes within budget, and
observed_bytes above retained_bytes with no omitted frame. A malformed
capture could therefore report truncated: false while its terminal
evidence was incomplete. Recompute retained raw and rendered bytes from
the frames, and require equal observed and retained bytes when no frame
was omitted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:12:05 +00:00
Kaoru0822andClaude Opus 5.5 db98a51dd1 fix(process): normalize ports that end a sentence
Contextual port normalization refused any port followed by a period, so
common log lines such as "Listening on port: 8080." or
"http://localhost:8080." kept their run-specific port and equivalent
captures compared as changed. Accept a sentence-ending period while
still refusing a period that continues a decimal, version, or host name,
and bump the committed port-normalization version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:06:41 +00:00
Kaoru0822andClaude Opus 5.5 59fbaa2d33 fix(ghidra): stop dereferencing the removed error payload in address verification
Since #1277 an MCP tool error carries no structuredContent, so the real
Ghidra address-boundary verifier threw a TypeError on its first expected
rejection and never checked the remaining representations or the
alias-preservation control. Assert that the error carries no structured
payload instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:04:35 +00:00
Kaoru0822andClaude Opus 5.5 7b51121f7c fix(mcp): measure tool errors against their text-only delivery
Since #1277 an error result reaches the client without structuredContent,
but toErrorToolResult and the transport recovery still budgeted it as
structured JSON plus escaped text. An error whose text fit between about
half and all of the response budget was replaced by resource_constraint,
and without Evidence retention the original diagnostic was lost.

Count only the escaped text for errors. The boundary, process-global and
real Ghidra large-result probes now use diagnostics that exceed the
text-only budget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 14:03:12 +00:00
YsopwnableandGitHub 33bf585185 fix(process): localize capture truncation diagnostics (#1284)
Report per-source capture coverage and existing file-hash omissions while preserving comparable observations in unaffected dimensions. Keep legacy truncated captures conservative and retain known partial trace events.

Closes #1250
Partially addresses #1251; independent hashing remains out of scope.
2026-10-09 21:56:43 +08:00
N0zoM1z0 f61673fa99 Merge remote-tracking branch 'origin/main' into fix/ghidra-session-root-stability 2026-10-09 13:54:37 +00:00
YsopwnableandGitHub 7e96f25f8b fix(mcp): deliver typed errors without invalid structured output (#1277)
* fix(mcp): deliver tool errors within advertised schema contracts

Retain complete typed JSON error content while omitting non-conforming
structured errors at the public transport boundary. Recover oversized
diagnostics into Evidence before removing their private structured carrier.
Update schema-validated client readers and cover actual stdio delivery.

Closes #1261

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)

* test(mcp): read typed errors in canonical Evidence regressions

* test(mcp): validate public error diagnostics in acceptance workflows
2026-10-09 13:54:32 +00:00
Kaoru0822andClaude Opus 5.5 502528c58d fix(javascript): resolve HTML script URLs after URL whitespace and percent decoding
An HTML script src or base href with percent-encoded letters or
surrounding whitespace was looked up literally, so an inventoried script
was reported as not-found. Apply HTML attribute and URL parser
whitespace handling, then percent-decode the path as the URL standard
does. Encoded dot and separator bytes are still rejected, and paths that
decode to NUL or non-UTF-8 bytes are rejected explicitly.

Closes #1236

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:52:55 +00:00
N0zoM1z0 bb8ff2cfba docs(website): explain SEO maintenance and indexing follow-up
Document the Python preview environment, automatic sitemap updates, canonical URLs, generated sharing card and Search Console checks after publication. Apply the website's clear, concise writing standard to search and sharing metadata.
2026-10-09 21:47:08 +08:00
N0zoM1z0 b8851cb977 feat(website): add search metadata and automatic sitemap
Prefer rea.tools in page canonicals and search listings. Generate the sitemap from current HTML indexing directives and render a shared PNG preview from SVG before verification and manual deployment.

Refs #1283
2026-10-09 21:46:05 +08:00
N0zoM1z0 2060a6d7f3 Merge branch 'fix/mcp-error-schema-delivery' into fix/ghidra-session-root-stability 2026-10-09 13:42:28 +00:00
N0zoM1z0 09058ebc4a test(mcp): validate public error diagnostics in acceptance workflows 2026-10-09 13:42:08 +00:00
N0zoM1z0 1e83d270c2 test(ghidra): use host-native absolute session root fixtures 2026-10-09 13:20:49 +00:00
YsopwnableandGitHub 0c6852b392 docs(ghidra): explain supported heap and CPU controls (#1278)
Explain consumed heap settings, owned JVM environment overrides, CPU affinity and memory measurements in the Ghidra setup guide.

Closes #1255
2026-10-09 21:20:33 +08:00
felipeatpandN0zoM1z0 a8b8288396 fix: keep the Ghidra session root free of dot-prefixed path elements
Ghidra validates every project path element with NamingUtilities.checkName and aborts the headless analyzer on any element starting with '.', so an inherited TMPDIR such as ~/.cache/<tool> failed every Ghidra operation with a generic analysis failure. Select the session root through a helper that prefers the inherited base, then a dot-free platform temp directory, then the nearest dot-free ancestor.
2026-10-09 13:10:30 +00:00
N0zoM1z0 5486860673 Merge remote-tracking branch 'origin/main' into fix/mcp-error-schema-delivery 2026-10-09 13:06:26 +00:00
YsopwnableandGitHub f085589957 fix(ci): pass selected environment to Windows Ghidra fixture (#1281) 2026-10-09 13:05:54 +00:00
N0zoM1z0 fd46cff017 test(mcp): read typed errors in canonical Evidence regressions 2026-10-09 13:03:28 +00:00
morluto d6d1cd2485 test: remove duplicate workflow examples and self assertions 2026-10-09 21:01:53 +08:00
morluto af7a439633 fix(windows): retain runtime authority after cleanup failure 2026-10-09 21:01:53 +08:00
morluto 81b70bc358 fix(managed): preserve literal library names during native matching 2026-10-09 21:01:52 +08:00
morluto 5eb0049a9f fix(process): retain known events from incomplete captures 2026-10-09 21:01:52 +08:00
morluto b7b4333703 fix(reference)!: represent unreadable symlink targets explicitly
BREAKING CHANGE: Historical source symlinks with unreadable or unknown target_state require target: null. Placeholder target strings are rejected.
2026-10-09 21:01:52 +08:00
morluto 0696bde266 fix(providers): preserve observations and primary cleanup failures 2026-10-09 21:01:52 +08:00
morluto 88640f60fe fix(browser): retain scenario resources until cleanup succeeds 2026-10-09 21:01:52 +08:00
N0zoM1z0 7bf63ed7f8 chore: integrate canonical Evidence changes for MCP error delivery 2026-10-09 12:43:17 +00:00
YsopwnableandGitHub 636b245f1b fix(android): support owned JADX stdio on Windows (#1276)
Support owned JADX stdio on Windows x64, preserve protocol input errors through cancellation, and verify native stdin and Android CLI/MCP lifecycle on the real Windows host.

Closes #1262
2026-10-09 20:34:42 +08:00
morluto b71a591a60 test: consolidate redundant assertions into boundary workflows
Remove getter, enum, cloned-projection, cache-identity, and obsolete profile assertions along with the shadow JSON Schema engine and dead test-only APIs. Retain producer, filesystem, SDK, lifecycle, integrity, and malformed-format coverage.

Document the priority of real end-to-end workflows, boundary integration, and producer goldens.
2026-10-09 20:26:46 +08:00
N0zoM1z0 da606ff777 fix(mcp): deliver tool errors within advertised schema contracts
Retain complete typed JSON error content while omitting non-conforming
structured errors at the public transport boundary. Recover oversized
diagnostics into Evidence before removing their private structured carrier.
Update schema-validated client readers and cover actual stdio delivery.

Closes #1261

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-09 12:26:27 +00:00
morluto 2f02eff988 fix(managed): separate metadata and signature completeness 2026-10-09 20:18:52 +08:00
morluto 5510b27d7f refactor(domain)!: remove obsolete comparison representations
Compare complete function dossiers directly, remove unreachable truncation and collection wrappers, and preserve deterministic Unicode ordering. Require real external reference targets instead of display placeholders.

BREAKING CHANGE: function comparison results no longer advertise the unreachable truncated state or counter.
2026-10-09 20:18:52 +08:00
morluto 475a0f84da fix(javascript)!: preserve property paths and uncertain slot presence
Use one explicit object/array slot model and JSON-pointer property identity across mutation analysis, return projection, and semantic graphs. Require observed presence for discriminants and resolve writes only through retained object or array receivers.

BREAKING CHANGE: projected return fields require explicit presence and semantic object operations carry full property paths.
2026-10-09 20:18:52 +08:00
morluto 63bf91405c refactor!: enforce canonical evidence and provider boundaries
Deliver complete Evidence directly through MCP with required nullable analysis profiles and immutable per-server delivery settings. Bind selected environments at construction and require typed cleanup outcomes with retained retry ownership.

Remove test-only routing, duplicate session and snapshot metadata, producer-field repairs, and ambiguous provider arguments. Separate artifact byte identity from occurrence classification and retain typed source-map and partial native facts across CLI, MCP, and verifier consumers.

BREAKING CHANGE: obsolete Evidence envelopes, session aliases, incomplete snapshots, and missing normalized producer facts are no longer accepted.
2026-10-09 20:18:52 +08:00
morluto 2a7746998d fix(process)!: require current captures and preserve cleanup failures
Remove v3 capture conversion and require explicit executable identity and event journals. Preserve cancellation, execution diagnostics, snapshots, and cleanup outcomes from preparation through CLI delivery.
2026-10-09 20:12:07 +08:00
morluto abc4f47683 build: separate runtime artifacts and supervise command ownership 2026-10-09 20:11:17 +08:00
YsopwnableandGitHub c8544b1574 fix(process): preserve unknown filesystem absence in partial captures
Separate exhausted path enumeration from hash coverage and preserve known
effects outside incomplete roots or unfollowed symlink subtrees. Return
explicit unknown effects through capture Evidence and comparison workflows.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-09 12:09:24 +00:00
YsopwnableandGitHub 4578647c59 Merge pull request #1272 from morluto/docs/website-calculator-continuation
docs(website): continue the Calculator example with reconstruction
2026-10-09 19:57:38 +08:00
morluto cc39fc53b8 feat(website): add Discord link beside GitHub badge 2026-10-09 19:54:34 +08:00
YsopwnableandGitHub 13c3b68730 Merge pull request #1270 from morluto/fix/batch-procedure-identity
fix(native): distinguish batch selectors from resolved entries
2026-10-09 19:39:48 +08:00
N0zoM1z0 18a1e8cd0e docs(website): continue the Calculator example with reconstruction 2026-10-09 19:38:17 +08:00
N0zoM1z0 933fcb33c1 test(native): assert batch identity in production registration 2026-10-09 19:27:27 +08:00
YsopwnableandGitHub f6fe575094 fix(process): await cleanup on CLI and MCP cancellation
Propagate CLI interrupts to capture and interrupt post-exit settlement
without cancelling owned-resource cleanup or discarding prior observations.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-09 11:26:41 +00:00
N0zoM1z0 8342e3a78f chore: merge current main into batch identity fix 2026-10-09 19:13:13 +08:00
N0zoM1z0 bfaa5a6c2c fix(native): distinguish batch selectors from resolved entries 2026-10-09 19:09:30 +08:00
YsopwnableandGitHub b189c3ceb1 Merge pull request #1268 from morluto/fix/ghidra-return-flow
fix(ghidra): preserve decoded return flow evidence
2026-10-09 19:04:47 +08:00
N0zoM1z0 bcc8a773e2 fix(ghidra): preserve decoded return flow evidence 2026-10-09 18:53:28 +08:00
YsopwnableandGitHub 6cc817e8bd Merge pull request #1266 from morluto/feat/website-apk-showcase
feat(website): add an Android showcase and clearer project prompts
2026-10-09 18:46:52 +08:00
keemsisiandGitHub 9426c3f1bb perf(hopper): resolve string search records once per query (#1229)
* perf(hopper): resolve string search records once per query

search_strings called _string_inventory(document) once per match, and each
call sorts every string address and rebuilds the record dict, so a query cost
O(matches x strings log strings). Resolve the inventory once per search.
Warm search, 50% matches, fake document, best of 7: 1000 strings 186 -> 0.5 ms,
4000 strings 3161 -> 2.1 ms, 8000 strings 13121 -> 4.9 ms; output byte-identical.

* perf(hopper): skip record resolution for empty string searches

Resolving the full string inventory for a query with no matches added a sort
of every string address that the previous code never performed. Return early
when nothing matches. Zero-match search on a warm document, best of 7:
64000 strings 35.9 ms before this change, 4.0 ms after (main: 3.9 ms).
2026-10-09 18:39:19 +08:00
N0zoM1z0 5691606aa9 fix(website): clarify Android host and JDK requirements 2026-10-09 18:31:22 +08:00
45e3edc17f feat(javascript): report observed export property presence (#1160)
* feat(javascript): report observed export property presence

Extend compare_javascript_export_shapes so each retained return variant
lists observed property names and each change reports presence independently
of value resolution. Complete parent coverage classifies one-sided names as
added or removed even when static values stay unknown.

Fixes #725

* test(javascript): match unknown export-shape values by availability

Nested availability objects include a reason when values stay unresolved.
Assert availability through objectContaining so presence-only added and
removed rows still verify unknown values.

* fix(javascript): preserve uncertain export property presence and locations

* fix(javascript): normalize presence and preserve local property coverage

* fix(javascript): require present discriminants for return pairing

* fix(javascript): normalize retained shapes before comparison

* refactor(javascript): share return projection with executable examples

* fix(javascript): localize uncertainty for missing mutated slots

* fix(javascript): bind advertised export examples to exact artifacts

* fix(javascript): keep uncertain property flow as candidates

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-09 18:30:31 +08:00
YsopwnableandGitHub 04aef6df33 Merge pull request #1265 from morluto/fix/snapshot-receipt-counts
fix(snapshot): report query workflow and Evidence counts separately
2026-10-09 18:29:02 +08:00
YsopwnableandGitHub 552634d634 Merge pull request #1264 from morluto/perf/snapshot-materialization
perf(snapshot): avoid redundant result copies and serialization
2026-10-09 18:19:59 +08:00
N0zoM1z0 0e779533a9 fix(snapshot): report query workflow and Evidence counts separately 2026-10-09 18:13:50 +08:00
YsopwnableandGitHub c5c75c38c3 Merge pull request #1263 from morluto/fix/process-normalization-fidelity
fix(process): preserve numeric output and original PTY evidence
2026-10-09 18:07:22 +08:00
N0zoM1z0 569d2bc6b9 perf(snapshot): avoid redundant result copies and serialization 2026-10-09 18:07:21 +08:00
889fb374df fix(javascript): match source-map originals that name parent directories (#1215)
* fix(javascript): match source-map originals that name parent directories

* fix(javascript): resolve parent segments against the source map's directory

* fix(javascript): resolve source originals against their map location

* fix(javascript): preserve URI and empty source map path semantics

* fix(javascript): separate source URL paths from opaque URI payloads

* fix(javascript): preserve filesystem names during URI classification

* style(javascript): format source URI presence guard

* fix(javascript): resolve source map references with URL semantics

* fix(javascript): preserve literal UNC source map paths

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-09 18:04:25 +08:00
YsopwnableandGitHub 24a3aa08d1 fix(session): retain failed provider cleanup for lifecycle retries (#1260)
Retire inactive clients until cleanup succeeds and block replacement startup
while owned resources remain. Preserve startup/cancellation failures alongside
cleanup diagnostics and retain explicit document choices across retries.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-09 17:56:17 +08:00
N0zoM1z0 00d8e44cbf fix(process): preserve numeric output and original PTY evidence 2026-10-09 17:55:28 +08:00
N0zoM1z0 3fb9ffaa4d docs(website): invite deeper projects and reader feedback 2026-10-09 17:48:59 +08:00
Kaoru0822andGitHub db0afce5f3 Merge pull request #1259 from morluto/fix/cli-json-input-read-cause
fix(cli): list the read failure cause for an unreadable JSON input file
2026-10-09 02:47:42 -07:00
Kaoru0822andGitHub 5612496f6d Merge pull request #1258 from morluto/fix/inspect-plist-default-remediation
fix(native): name the plist selection that works when Info.plist is missing
2026-10-09 02:47:30 -07:00
Kaoru0822andGitHub fe5291e916 Merge pull request #1239 from morluto/fix/javascript-input-selection-errors
fix(javascript): classify application input selection failures by cause
2026-10-09 02:47:09 -07:00
Kaoru0822andGitHub d4a598e936 Merge pull request #1256 from morluto/fix/evidence-file-selection-code
fix(errors): report caller-selected evidence path failures as invalid input
2026-10-09 02:46:04 -07:00
Kaoru0822andGitHub ddaa18301a Merge pull request #1240 from morluto/fix/web-script-export-capture-selection
fix(browser): classify export-web-scripts capture selection failures by cause
2026-10-09 02:45:47 -07:00
morluto d6832c3632 docs: require focused brittleness cleanup and executable examples 2026-10-09 17:41:14 +08:00
Kaoru0822andClaude Opus 5.5 9b6950373c fix(native): name the CLI flag that selects another plist
rea inspect-plist takes the target as its positional path and selects a
plist with --relative-path, so "Pass path" pointed CLI callers at the
wrong argument. Name the MCP path input and the CLI flag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:32:24 +00:00
Kaoru0822andClaude Opus 5.5 6020df53d9 fix(cli): list the read failure cause for an unreadable JSON input file
A CLI workflow given a JSON input file that cannot be read (missing, a
directory, or permission denied) returned invalid_request with
input_reason "read-failed" but no details. The remediation "Correct the
listed arguments and retry." therefore listed nothing, and the system
error that separates a typo from a permission denial was dropped.

Add an invalid_value issue naming the system error code and the path.
The envelope, code and input_reason are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:30:15 +00:00
Kaoru0822andClaude Opus 5.5 a6fdf426bd fix(native): name the plist selection that works when Info.plist is missing
inspect_plist on a target without a readable default Contents/Info.plist
(for example a bare Mach-O) reported the generic "This analysis is
unavailable for the current target. Choose another analysis or target."
as message and remediation. The specific reason, including "Pass path to
inspect another plist", appeared only in details.reason, although
selecting another plist in the same target is the available workflow.

Pass that reason as the refusal's user message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:26:18 +00:00
Kaoru0822andClaude Opus 5.5 db177c91b8 fix(errors): report caller-selected evidence path failures as invalid input
An EvidenceFileError for a missing evidence file, a selected path that is
not a regular file, or an output that already exists projected code and
category execution_failure. The message already told the caller to
correct the path, but agents branching on code or category saw a tool
failure.

Project those three reasons as invalid_request with category
invalid_input. An unreadable file (io) and invalid JSON keep their
codes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:23:00 +00:00
Kaoru0822andClaude Opus 5.5 d186ca7e41 test(javascript): expect the invalid input_path code in the streamed CLI failure test
The acceptance test uses a missing input path only to produce a streamed
JSON failure with a nonzero exit. The missing path is now an invalid
input_path rather than an artifact io failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:20:16 +00:00
YsopwnableandGitHub aa5750c263 fix(mcp): emit portable Unicode NUL patterns (#1230)
Preserve NUL rejection while avoiding the short escape rejected by strict
schema consumers. Guard the entire advertised input/output catalog and all
three JavaScript regexp modes.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-09 17:18:17 +08:00
Kaoru0822andClaude Opus 5.5 8c5e34cd37 fix(browser): classify export-web-scripts capture selection failures by cause
export_web_scripts reported a missing capture, a directory selected as
the capture, and an unreadable capture as an artifact io failure ("Script
export failed for <capture> -> <output>: ENOENT ..."), unlike its sibling
inspect_web_network_capture, which already reports these as invalid
input or access_denied.

Read the selected capture in its own step: ENOENT, ENOTDIR and EISDIR
become an invalid capture_path issue, and EACCES or EPERM becomes
access_denied. Failures while writing the export keep their existing
classification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:16:59 +00:00
N0zoM1z0 0270dd5739 feat(website): add an Aegis APK code-generation showcase 2026-10-09 17:15:07 +08:00
Kaoru0822andClaude Opus 5.5 0a14bbbf05 fix(javascript): classify application input selection failures by cause
analyze_javascript_application reported every input-selection problem as
an artifact fault:

- a missing input path: "Artifact could not be read or written", with no
  path or reason;
- an unreadable selected directory: the same generic io failure;
- a regular file that is neither a directory nor an .asar, and a
  --artifact-format that contradicts the selection: "Artifact is invalid
  or has changed. Get a fresh copy and try again."

Report a missing path as an invalid input_path, an unreadable selection
as access_denied, a non-directory non-.asar file as unsupported_target
with the accepted inputs as remediation, and a contradicting format as an
invalid format with the observed kind as expected value. Failures inside
a selected artifact keep their existing classification.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:13:17 +00:00
N0zoM1z0 f6f5c16097 docs(website): introduce the worked homepage examples 2026-10-09 16:52:45 +08:00
Kaoru0822andGitHub f4c99ab8a5 Merge pull request #1228 from morluto/fix/keyed-archive-host-remediation
fix(artifacts): name only host-available workflows for non-archive plists
2026-10-09 01:48:51 -07:00
954badbaaa refactor(schemas): share portable identifier and base64 patterns (#1227)
* refactor(schemas): share identifier and canonical base64 patterns

* test: hold the offset datetime schema to the validator it replaces

The module documents that its accepted set matches z.string().datetime({ offset: true }), and nothing in the suite checked that claim. Adds table-driven accept and reject cases (leap years including the 1900/2000 century pair, month, day, hour and offset ranges, fractional and omitted seconds, missing offset, basic format) plus a differential assertion that classifies every case exactly as the replaced validator does, and asserts the emitted pattern compiles under u and v while the replaced pattern does not compile under v.

---------

Co-authored-by: felipeatp <felipe.troncosopt@gmail.com>
2026-10-09 16:47:09 +08:00
Kaoru0822andClaude Opus 5.5 22958558ea fix(artifacts): name only host-available workflows for non-archive plists
inspect_keyed_archive runs on every host, but its remediation for an
ordinary property list pointed to inspect_plist, which only macOS
supports. On Linux that sent callers to a workflow the capability layer
rejects.

The domain error now names what the file is. The artifact reader picks
the remediation from the provider's host: inspect_plist on macOS, and
elsewhere the selection of an NSKeyedArchiver archive, with a note that
inspect_plist requires macOS. decode_interface_builder, which is
portable, stays the NIBArchive remediation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:40:45 +00:00
Kaoru0822andGitHub fef38e4d22 Merge pull request #1226 from morluto/fix/keyed-archive-kind-refusal
fix(artifacts): report non-archive keyed-archive selections as unsupported targets
2026-10-09 01:37:29 -07:00
Kaoru0822andGitHub 136d4aab18 Merge pull request #1225 from morluto/fix/exec-stop-timeout-validation
fix(process): refuse malformed timeouts for stoppable commands
2026-10-09 01:33:25 -07:00
Kaoru0822andGitHub 68cb02fe8b Merge pull request #1224 from morluto/fix/adapter-host-refusal-messages
fix: name host and tool requirements in optional adapter refusals
2026-10-09 01:33:15 -07:00
Kaoru0822andClaude Opus 5.5 8c5088c8cd fix(artifacts): report non-archive keyed-archive selections as unsupported targets
inspect_keyed_archive reported a selected ordinary property list or a
compiled NIBArchive as a damaged artifact: "Artifact is invalid or has
changed. Get a fresh copy and try again." The file is intact; it is
another kind of file, and the workflow that reads it (inspect_plist or
decode_interface_builder) appeared only in details.detail.

Report a NIBArchive, or a plist whose $archiver is not NSKeyedArchiver,
as unsupported_target with that workflow as the remediation. An
NSKeyedArchiver archive that fails to decode stays a format failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:28:21 +00:00
Kaoru0822andClaude Opus 5.5 3d328193d6 fix(process): apply one timeout rule to both execFileOutput modes
Node's execFile timeout contract differs by supported runtime: Node 22
and 24 accept any non-negative integer (their timers clamp anything
above 2^31-1 to 1 ms), while Node 26 caps it at Number.MAX_SAFE_INTEGER.
Mirroring either left stoppable and plain commands disagreeing on one
runtime. Validate a safe non-negative integer before spawning in both
modes, so every supported runtime gives the same answer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:22:09 +00:00
felipeatpandGitHub f0da05f67f fix: emit v-mode-compatible patterns for tool schemas (#1220)
* fix: emit v-mode-compatible patterns for tool schemas

Character classes in emitted patterns carried unescaped '-', '/' and '['. Annex-B and u-mode accept them, so REA's own Zod validation (u) and every u-based validator never saw a defect, but v-mode rejects ClassSetSyntaxCharacters and Ruby rejects [^s[]]. With 6.1.0 tools/list, 117 pattern fields across 11 tools were rejected under v.

The characters are escaped as \x2d, \x2f, \x5b and \x5d rather than \-/\//\[, because oxlint --fix removes an escaped '-' inside a character class as a useless escape, so an escape-only change does not survive the pre-commit hook. \x2d-style escapes are valid under Annex B, u and v, are matched identically, and are not useless-escape candidates.

22 pattern literals in 18 files are touched; no other token changes.

* fix: replace the Zod offset pattern and guard the advertised catalog

The offset datetime site projected Zod's offset class as [ +- ], which no escape in this repository's sources can reach, so evaluate_reconstruction_coverage stayed unreachable for exactly the clients this change targets. It now uses offsetDateTimeSchema in src/domain/offsetDateTime.ts: the same accepted set with the offset class escaped as [ +\x2d ].

Adds tests/boundary/mcp/advertisedPatternsVMode.test.ts, which performs the real tools/list projection, traverses every advertised input and output schema, compiles each pattern under v, and asserts the inventory it walked so a silent traversal collapse fails instead of passing vacuously.
2026-10-09 16:20:57 +08:00
Jay HemnaniandGitHub 01174c4a81 fix(javascript): report located sources with differing digests as modified (#1216) 2026-10-09 16:20:42 +08:00
Kaoru0822andClaude Opus 5.5 6489d58851 fix(javascript): keep Wakaru version stderr out of the refusal message
The version-mismatch reason ends with the tool's complete stderr, which
is too long for a caller-facing message. The message now names the
expected and reported version and exit code; details.reason keeps the
stderr.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:16:45 +00:00
Kaoru0822andClaude Opus 5.5 59c91c88fe fix(process): refuse malformed timeouts for stoppable commands
Since a stoppable command keeps its own deadline, execFile no longer
validated its timeout. A negative, NaN, fractional or infinite value
then started the command with no deadline (or one setTimeout coerced)
instead of failing with ERR_OUT_OF_RANGE as execFile does.

Apply execFile's unsigned-integer contract before spawning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:15:03 +00:00
c89b3a00dc test(artifacts): read /bin/ls slice layout from its FAT table (#1223)
The real-lipo slice test pinned the byte offsets and sizes of one macOS
release's /bin/ls, so it failed on any host whose /bin/ls differs
(macOS 26.7.1: x86_64 48128 bytes, arm64e 88672, versus the pinned 48112
and 89088). Read the expected layout from the binary's FAT header
instead.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:12:27 +08:00
Kaoru0822andClaude Opus 5.5 170d0bf9e2 fix: name host and tool requirements in optional adapter refusals
Host and tool-configuration refusals from the pwntools, EVMole, firmware,
mitmproxy, Wakaru, LLDB and xcrun adapters carried no userMessage, so CLI
and MCP callers saw the generic "This analysis is unavailable for the
current target. Choose another analysis or target." as both message and
remediation. Choosing another target cannot satisfy a Linux-only profile
or an unset REA_*_COMMAND. The actual requirement appeared only in
details.reason.

Pass each refusal's reason as its userMessage, as the adapters' other
configuration refusals (EVMole limits, JADX, pwndbg) already do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:12:25 +00:00
6935dc7fe1 fix(ghidra): classify modern Swift manglings in swift type analysis (#1208)
* fix(ghidra): classify modern Swift manglings in swift type analysis

Categorize modern Swift 4.2+ manglings ($s, _$s) instead of dropping them
in analyze_swift_types. The classifier only accepted the legacy _Tt marker,
so procedure names reported by current providers produced an empty inventory.
Legacy _Tt families and behavior are unchanged. Fixes #1187.

* fix(swift): retain provider aliases and category unknowns

---------

Co-authored-by: Saim Shafique <sx4imm@gmail.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-09 16:10:55 +08:00
Kaoru0822andGitHub 04a516b1e3 Merge pull request #1222 from morluto/fix/ghidra-relative-java-probe
fix(ghidra): do not run Java from a relative JAVA_HOME in doctor and setup
2026-10-09 01:04:53 -07:00
Kaoru0822andGitHub 4b38d18995 Merge pull request #1221 from morluto/fix/exec-stop-signal-timeout
fix(process): stop timed-out commands with the caller's stop signal
2026-10-09 01:04:21 -07:00
Kaoru0822andClaude Opus 5.5 c3f169823f fix(ghidra): do not run Java from a relative JAVA_HOME in doctor and setup
The installation inspection rejected a relative JAVA_HOME, but only after
it had already probed `<JAVA_HOME>/bin/java` with spawnSync. `rea doctor`
and `rea setup` therefore ran whatever `jdk/bin/java` (or `bin/java` for
an empty JAVA_HOME) the current directory held, while reporting the
setting as rejected.

Skip the probe when JAVA_HOME is not absolute on the inspected platform.
The configuration check still reports the rejection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 07:59:38 +00:00
Kaoru0822andClaude Opus 5.5 063de5014f fix(process): stop timed-out commands with the caller's stop signal
execFileOutput forwarded stopSignal only together with an AbortSignal, so
a caller with just a timeout (the native UI helper's swiftc build) still
got Node's SIGTERM. When the timeout did send the stop signal, nothing
killed a process that ignored it, and a process that exited cleanly
after the signal resolved as a success.

A stoppable command now owns its timeout: it sends the stop signal,
kills the process after the grace period, and rejects with ETIMEDOUT
and killed: true.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 07:57:14 +00:00
morluto e6905c18e0 fix(website): identify publication verifier requests 2026-10-09 15:46:20 +08:00
YsopwnableandGitHub 9405bd660d fix(javascript): allow cancellation during semantic graph commitment (#1218)
Move whole-graph commitment and batched integrity checks into owned domain steps while retaining eager input capture, canonical IDs, full validation and completion-only immutable proofs.

Verified complete real Notion identity parity and actual stdio MCP cancellation, Evidence retention and connection reuse.

Refs #1065.
2026-10-09 15:15:17 +08:00
27a9ceade7 fix!: restore caching, preserve failures, and verify fixture claims (#1211)
Restore profile-bound Ghidra snapshot reuse, preserve direct-analysis results through cleanup failures, and grade configured agent fixture claims against returned evidence.

Register the compiled agent-evaluation fixture entry for static analysis.

Co-authored-by: YouWish <29498139+Y0UW1SH@users.noreply.github.com>
Co-authored-by: N0zoM1z0 <161784452+N0zoM1z0@users.noreply.github.com>
2026-10-09 14:49:09 +08:00
YsopwnableandGitHub c399670653 docs: keep the 30k milestone in Star History (#1217) 2026-10-09 14:45:59 +08:00
YsopwnableandGitHub 863674b2e9 feat(website): add homepage navigation and faster reading paths (#1213)
feat(website): add homepage navigation and faster reading paths
2026-10-09 14:33:47 +08:00
YsopwnableandGitHub c2d8146f94 docs: clarify REA has no affiliated cryptocurrency or token (#1214) 2026-10-09 14:25:32 +08:00
N0zoM1z0 c94f06d98f feat(website): add homepage navigation and faster reading paths 2026-10-09 14:03:00 +08:00
Kaoru0822andGitHub 5b769d3a78 Merge pull request #1201 from morluto/fix/ghidra-runtime-cleanup-retry
fix(ghidra): keep and name a runtime directory that close could not remove
2026-10-08 22:49:12 -07:00
Kaoru0822andGitHub 6987cb066a Merge pull request #1207 from morluto/docs/celebrate-30000-stars
docs: celebrate 30,000 GitHub stars 🎉
2026-10-08 22:48:54 -07:00
YsopwnableandGitHub 7e9c91199e fix(cli): resolve xrefs symbol selectors after address validation (#1209)
* fix(cli): resolve xrefs symbol selectors after address validation

* style(cli): format xrefs fallback call
2026-10-09 13:28:48 +08:00
N0zoM1z0 9db1fd0bd7 docs: thank feature request contributors 2026-10-09 13:02:26 +08:00
YsopwnableandGitHub 796b65e1cd ci(website): allow explicitly requested Pages-only publication (#1205)
ci(website): allow explicitly requested Pages-only publication
2026-10-09 13:00:26 +08:00
N0zoM1z0 beca9977eb docs: celebrate 30,000 GitHub stars 🎉 2026-10-09 12:58:16 +08:00
YsopwnableandGitHub 6051cb2c0c fix(setup): preserve initial backups and Codex comments (#1204) 2026-10-09 12:57:00 +08:00
N0zoM1z0 864160d885 ci(website): allow explicitly requested Pages-only publication 2026-10-09 12:46:17 +08:00
db675f1d52 feat(mcp): select views of retained analysis results (#1180)
Add explicit summary, facet, item and paged views of retained analysis Evidence without repeating analysis. Preserve captured observations, graph validation, artifact identity, coverage and complete default results.

Fixes #1050

Verified with focused source, CLI, pinned-SDK schema and MCP tests, serial static checks, and one complete native Windows Notion ASAR workflow. Real Hopper/Ghidra verification was not performed for this provider-independent projection change.

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-10-09 12:45:48 +08:00
911152a04d fix(cli): complete cleanup after relayed interrupts (#1202)
* fix: Handle relayed SIGINT gracefully in withProcessCancellation

Changes `process.once` to `process.on` for SIGINT in `DirectAnalysis.ts`.
When REA is launched via npx, a single process-group SIGINT triggers two
SIGINT events (one direct, one relayed). Previously, the first event would
consume the handler and the second would abruptly terminate the Node process,
abandoning Ghidra resource cleanup.

This change ensures subsequent SIGINTs idempotently request cancellation
without crashing the process, matching the behaviour of `withCommandCancellation`.

* fix(cli): keep termination guards through provider cleanup

* test(cli): exercise repeated analysis signals on macOS

---------

Co-authored-by: N0zoM1z0 <1705004398@qq.com>
2026-10-09 12:45:23 +08:00
YsopwnableandGitHub 0fec65d06b feat(website): add beginner examples and synchronized publishing (#1203)
feat(website): add beginner examples and synchronized publishing
2026-10-09 12:41:51 +08:00
Kaoru0822andGitHub cf415619ca Merge pull request #1194 from morluto/fix/darwin-helper-compile-tmpdir
fix(process): stop cancelled Swift helper builds before removing their files
2026-10-08 21:21:32 -07:00
Kaoru0822andGitHub cfb49eb8a8 Merge pull request #1198 from morluto/fix/ghidra-extension-unsupported-host
fix(ghidra): report NativeAOT host and target refusals as unsupported, not failures
2026-10-08 21:21:18 -07:00
Kaoru0822andGitHub 8998438c23 Merge pull request #1200 from morluto/fix/doctor-setup-relative-provider-paths
fix(ghidra): reject relative installation and Java paths in doctor and setup
2026-10-08 21:21:04 -07:00
Kaoru0822andGitHub c3acc34475 Merge pull request #1199 from morluto/fix/config-error-names-setting
fix(config): name the rejected setting and its constraint in configuration errors
2026-10-08 21:20:48 -07:00
N0zoM1z0 761881cec3 ci(website): publish Cloudflare and Pages from one artifact 2026-10-09 12:19:38 +08:00
Kaoru0822andClaude Opus 5.5 b79d379c25 fix(ghidra): keep and name a runtime directory that close could not remove
When removing Ghidra's private runtime directory failed, close_binary
reported only a generic `provider-client` resource, and a later close,
after the permission was restored, returned success while the directory
and its contents remained. The client dropped its reference to the root
before removing it, and PrivateRuntimeRoot cached the rejected removal.

Keep each runtime or socket root until its removal succeeds, report a
failure as a ProviderCleanupError naming the leftover paths, let
PrivateRuntimeRoot retry a failed removal, and pass such typed cleanup
failures through closeAnalysisClient instead of replacing them.

Fixes #1190

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 04:19:10 +00:00
YsopwnableandGitHub 6fbdbd6820 fix(ghidra): resolve secondary symbols at function entries (#1195)
* fix(ghidra): resolve secondary symbols at function entries

* test(ghidra): derive interior bytes from decoded instructions
2026-10-09 12:19:07 +08:00
Kaoru0822andClaude Opus 5.5 53568568bf fix(ghidra): reject relative installation and Java paths in doctor and setup
A relative GHIDRA_INSTALL_DIR (or JAVA_HOME) that resolved from the current
directory passed doctor's Ghidra inspection, so doctor reported a healthy
provider and setup wrote the relative path into the MCP registration, but
REA's configuration parser rejects relative paths, so `providers`,
`capabilities` and the registered MCP server all failed.

The installation inspection's configuration check now applies the same
absolute-path rule, judged by the inspected platform's path syntax, and
names the relative setting. Doctor reports the provider unavailable with
that reason, and setup, which registers only an available inspection's
environment, no longer writes the path.

Fixes #1183

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 04:13:40 +00:00
Kaoru0822andGitHub f36c10f9e8 Merge pull request #1197 from morluto/fix/target-admission-access-denied
fix(domain): report target read-permission denials as access_denied
2026-10-08 21:13:32 -07:00
Kaoru0822andGitHub d39a450bdf Merge pull request #1196 from morluto/fix/target-truncated-headers
fix(native): refuse truncated executable headers at target admission
2026-10-08 21:13:15 -07:00
Kaoru0822andGitHub 98b07d07dd Merge pull request #1182 from morluto/fix/doctor-hopper-discovery-readonly
fix(doctor): find the Homebrew Hopper cask without writing Homebrew caches
2026-10-08 21:13:00 -07:00
Kaoru0822andClaude Opus 5.5 f198993f41 fix(ghidra): keep the NativeAOT target refusal's own recovery advice
An unsupported-target error always projected the generic "select a target"
remediation, which hid the adapter's available workflows (omit
REA_GHIDRA_NATIVEAOT_JAR for ordinary analysis, or use
inspect_managed_artifact). AnalysisUnsupportedTargetError accepts a
refusal-specific remediation, as AnalysisResourceConstraintError does, and
the NativeAOT refusal supplies its reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 04:09:50 +00:00
N0zoM1z0 54c0ed42aa chore: merge main before website publication 2026-10-09 12:09:29 +08:00
Kaoru0822andClaude Opus 5.5 0a0244db42 fix(config): name the rejected setting and its constraint in configuration errors
Every configuration failure projected the same message, "REA configuration
is invalid. Run `rea doctor` and fix the reported setting.", with no
details. The environment parser discarded the issue that names the variable
(for example `REA_GHIDRA_NATIVEAOT_JAR must be absolute`), and doctor can
report healthy for that environment, so neither the CLI, the MCP startup
message, nor doctor told callers which setting to correct.

ConfigurationError now carries the rejected settings and their constraints
(never their values). The projection names them in its message, lists them
in `details.settings`, and asks the caller to correct those settings where
REA is started. Errors without a named setting keep the previous message.

Fixes #1184

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 04:08:43 +00:00
Kaoru0822andClaude Opus 5.5 9f5dc52be8 fix(hopper): keep the OS error when the FAT64 source cannot be reopened
resolveHopperMachOImage built its BinaryTargetError without the open
failure as its cause, so a target that became unreadable after admission
still projected as `target_unavailable` instead of `access_denied`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 04:04:42 +00:00
Kaoru0822andClaude Opus 5.5 42c276af1e fix(ghidra): report NativeAOT host and target refusals as unsupported, not failures
With REA_GHIDRA_NATIVEAOT_JAR set on a host other than Linux, Ghidra
analysis was refused before Ghidra started, as intended, but the refusal
was a ProviderAdapterError: `execution_failure` with advice to retry and
run doctor, neither of which can change the host.

Adapters now say whether a refusal concerns the host or the target. A host
refusal is `capability_unavailable` whose message and remediation are the
adapter's reason (omit the JAR for ordinary analysis); a target refusal is
`unsupported_target` with the target path. Missing or malformed JARs on a
supported host remain provider failures.

Fixes #1185

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 04:03:10 +00:00
N0zoM1z0 291bc6fb70 feat(website): show manual analysis beside a one-prompt workflow 2026-10-09 12:02:58 +08:00
Kaoru0822andClaude Opus 5.5 facaae865a test(native): build the .app fixture executable with a complete Mach-O header
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:59:19 +00:00
Kaoru0822andClaude Opus 5.5 d0ff57a45c fix(domain): report target read-permission denials as access_denied
Opening a target the current user cannot read returned
`target_unavailable`, the same code as a missing target, although the
reason named EACCES. Clients that branch on the error code could not choose
read-access recovery, contrary to the boundary contract that separates host
permission denial from unavailable targets.

A BinaryTargetError whose cause is an OS EACCES or EPERM now records that
system code and projects as `access_denied` with `system_code`, the
filesystem-read boundary, and read-access remediation, while keeping its
specific reason and path. This covers target files, app bundle paths and
Info.plist reads, and selected plist reads, since every site passes the OS
error as the cause.

Fixes #1188

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:56:38 +00:00
Kaoru0822andClaude Opus 5.5 0b04d384cc fix(native): refuse truncated executable headers at target admission
Target admission accepted a thin Mach-O after reading only its magic and
CPU type, so a 12-byte prefix opened as a valid arm64 executable and the
first provider query failed as a generic execution failure. ELF headers
were likewise accepted after 20 bytes, and a FAT file whose selected slice
lies beyond its end was admitted.

Require the complete fixed header (Mach-O 28 or 32 bytes, ELF 52 or 64),
Mach-O load commands that fit in the file, and a selected FAT slice within
the file, checking commitments against the file size rather than the
probed prefix. Each refusal names the failed constraint.

Fixes #1189

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:51:37 +00:00
Kaoru0822andGitHub e6abaefbbc Merge pull request #1179 from morluto/fix/session-client-metadata-2025
fix(server): report 2025-era client identity and features in binary_session
2026-10-08 20:51:34 -07:00
Kaoru0822andGitHub f5539cfc2f Merge pull request #1178 from morluto/fix/codex-toml-preserve-comments
fix(setup): keep Codex TOML comments when adding or removing REA
2026-10-08 20:51:15 -07:00
2a620c06cd fix(javascript): resolve package exports targets only to the exact file (#1181)
A selected package exports target names one file, and Node tries no
extension or directory index for it. REA still resolved it like a relative
specifier, so `exports: "./file"` with only `file.js` present, or
`"./folder"` with only `folder/index.js`, reported a resolved import that
Node rejects under both import and require.

Resolve an exports target only to its exact file and otherwise report
not-found with a limitation naming the target. Legacy main entries keep
their extension and index fallbacks.

Fixes #1174

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 11:49:32 +08:00
N0zoM1z0 e750c262fb feat(website): clarify reverse engineering and showcase goals 2026-10-09 11:46:06 +08:00
Kaoru0822andClaude Opus 5.5 c717204795 fix(process): stop cancelled Swift helper builds before removing their files
Cancelling the macOS process-ownership helper build left swiftc object files
in TMPDIR. Node's execFile sends SIGTERM on abort and rejects before the
child exits, and swift-driver runs each frontend job in its own process
group: on SIGTERM the driver exits while a job keeps writing, so REA removed
its root while objects were still being written outside and inside it.

Add an opt-in `stopSignal` to execFileOutput that stops the process with the
caller's signal on abort or timeout and settles only after it exits. Swift
helper builds stop swiftc with SIGINT, on which swift-driver stops its jobs
and deletes their objects, and point TMPDIR inside the root cleanup removes.

Fixes #1173

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:43:43 +00:00
YsopwnableandGitHub e1afbc1914 perf(mcp): reuse input schemas without losing caller guidance (#1162) 2026-10-09 11:38:07 +08:00
Kaoru0822andClaude Opus 5.5 a503376b2f fix(doctor): find the Homebrew Hopper cask without writing Homebrew caches
`rea doctor`, documented as strictly read-only, ran
`brew --prefix --cask hopper-disassembler` when Hopper was not in a
standard location. Current Homebrew rejects that option combination, but
any brew command naming a cask first fetches the cask API, so each doctor
run wrote about 600 files (36 MB) into the user's Homebrew cache.

Ask brew only for its Caskroom, which brew answers without loading the
cask API, and read the application directory Homebrew recorded in the
Hopper cask's install receipt.

Fixes #1165

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:28:25 +00:00
Kaoru0822andGitHub 4fb2f3e6ed Merge pull request #1177 from morluto/fix/uninstall-preflight-client-config
fix(setup): stop uninstall before removals when a client config is unsafe
2026-10-08 20:22:34 -07:00
Kaoru0822andGitHub d8e314cb24 Merge pull request #1176 from morluto/fix/session-availability-active-target
fix(session): require an open target for session-bound native and artifact tools
2026-10-08 20:22:23 -07:00
N0zoM1z0 19c52f5e3f feat(website): lead with the playable dinosaur example 2026-10-09 11:21:18 +08:00
Kaoru0822andClaude Opus 5.5 b8312fa8d1 fix(server): report 2025-era client identity and features in binary_session
binary_session read the client's identity, protocol revision, and
capabilities only from the 2026-era per-request envelope. A 2025-era
connection sends none, so every such client was reported as `client: null`
with no negotiated protocol and no features, although it declared them in
`initialize`.

When a request carries no envelope, read the values the SDK keeps from the
connection's initialize handshake. An envelope still takes precedence.

Fixes #1167

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:20:43 +00:00
Kaoru0822andClaude Opus 5.5 fd975c75fa fix(setup): stop remaining uninstall removals after a client fails
A configuration that passes the preflight can still fail when uninstall
rereads it to edit, for example when it changes concurrently. Rereading
keeps that edit from overwriting the newer file; stopping at the failure
keeps later clients, the skill, and REA data from being removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:17:11 +00:00
Kaoru0822andClaude Opus 5.5 e9c48a61e4 fix(setup): keep Codex TOML comments when adding or removing REA
Setup and uninstall rewrote the whole Codex config.toml with a fresh TOML
serializer, which dropped every comment and respelled unrelated values,
although the plan promises to preserve unrelated configuration. Grok Build
already edited only REA's server tables.

Share that table editor with Codex, without Grok's root
disabled_mcp_servers handling, keep the original final line break, and
fall back to the full rewrite only when the edited text would not parse to
the requested document.

Fixes #1163

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:15:18 +00:00
b4927a0a4f fix(cli): advertise defaulted inputs as optional in --schema and help (#1175)
Incur derives `--schema`, the `--llms` manifests, and help synopses from
Zod's output view, where a defaulted field always has a value, so every
defaulted argument and option was listed as required even though the CLI
accepts its omission. Wrap each field that fills an omitted value as
optional after registration, keeping its default, constraints, metadata,
and parsed value.

Fixes #1169

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 11:11:11 +08:00
Kaoru0822andClaude Opus 5.5 5cc841d5c1 fix(setup): stop uninstall before removals when a client config is unsafe
The installation guide says malformed client configuration stops
`rea uninstall`, but uninstall reported that client as failed and still
removed other clients' registrations, the bundled skill, and with
--purge-data REA's cache and state.

Inspect every client configuration first, using the conditions setup
already treats as blocking (unsafe path, unreadable file, malformed
document), and stop before any removal when one fails. Purge paths that are
symbolic links are still retained and reported per item, as the guide now
states.

Fixes #1164

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:07:40 +00:00
N0zoM1z0 11b9f0346c feat(website): explain REA with Calculator and a playable dinosaur lab 2026-10-09 11:06:05 +08:00
Kaoru0822andClaude Opus 5.5 cf77d073fc fix(session): require an open target for session-bound native and artifact tools
binary_session reported native and artifact operations available whenever
their provider declared them, although these operations run on the active
target: in a closed session every call failed with target_unavailable, and
Mach-O-only operations stayed available with a ZIP or ELF target open.

Report target_required for every session-bound contract kind in a closed
session, and target_unsupported for Mach-O-only operations unless the open
target is a Mach-O executable. A host limitation is reported before target
selection, since opening a target cannot fix it; composed operations keep
deciding from their requirements.

Fixes #1166

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 03:02:40 +00:00
Kaoru0822andGitHub de5bfec79f Merge pull request #1172 from morluto/fix/macho-arm64e-variant-slices
fix(artifacts): match lipo arm64e variant names to their FAT slices
2026-10-08 19:42:05 -07:00
Kaoru0822andGitHub 37025cc09f Merge pull request #1171 from morluto/fix/extraction-preflight-cancellation
fix(artifacts): keep cancellation and the caller path in extraction refusals
2026-10-08 19:38:56 -07:00
Kaoru0822andClaude Opus 5.5 0b32577a90 fix(artifacts): match lipo arm64e variant names to their FAT slices
Newer lipo names arm64e ABI variants `arm64e.<variant>`: `arm64e.v1` for
pointer-auth ABI version 1 on freshly built universal binaries, and
`arm64e.x1` on recent macOS system binaries such as /bin/ls. The
structural FAT parser names the same slice `arm64e`, so the exact name
comparison failed and inspect_artifact reported a valid, unmodified
universal binary as an integrity mismatch ("Artifact is invalid or has
changed").

Accept `arm64e.<variant>` for an `arm64e` FAT slice. Offset, size, CPU
type, subtype (including the pointer-auth version bits when lipo prints
them) and alignment are still compared field by field. The slice keeps
lipo's name in its logical path.

Fixes #1168

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:37:03 +00:00
Kaoru0822andClaude Opus 5.5 eacf8461da fix(artifacts): keep cancellation and the caller path in extraction refusals
Two follow-ups to #1161 from its post-merge review:

- The new format preflight ran before scanArtifactInventory, which was
  the first cancellation check. An already-cancelled extraction of a
  DMG or PKG therefore reported unsupported_target instead of
  cancellation. Check the signal before the preflight.
- The unsupported-format and encrypted-entry refusals reported the
  realpath. When the caller selected the target through a symlink,
  junction, or other alias, the diagnostic named a different path.
  Report the caller's input path; I/O still uses the canonical path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:33:16 +00:00
Kaoru0822andGitHub b34bdcdb28 Merge pull request #1161 from morluto/fix/artifact-unsupported-target-errors
fix(artifacts): report wrong target kinds as unsupported targets
2026-10-08 19:30:54 -07:00
Kaoru0822andClaude Opus 5.5 de43da71ae fix(artifacts): report encrypted archive entries as unsupported extraction
extract_artifact on a ZIP containing a password-protected entry failed
the whole extraction with "Artifact is invalid or has changed. Get a
fresh copy" and named only an opaque occurrence ID. The archive was
intact; REA does not decrypt entries, so complete extraction is
unsupported for this target.

Raise AnalysisUnsupportedTargetError naming the encrypted entry's path.
Other unextractable occurrences keep their format failure but now name
the logical path alongside the occurrence ID.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:23:44 +00:00
Kaoru0822andGitHub 6a1e558db3 Merge pull request #1159 from morluto/fix/dylib-resolution-root-input-errors
fix(apple): report unusable dylib-resolution roots as invalid input
2026-10-08 19:23:22 -07:00
Kaoru0822andClaude Opus 5.5 8e74c9c62f fix(artifacts): refuse unsupported extraction formats before scanning
extract_artifact on a format without an extraction reader, such as a
DMG, first ran the full inventory scan (mounting the image) and then
failed with an `unavailable` artifact failure: "Check artifact support
and required tools". The target format, not the host, is unsupported.

Check the format before any inventory or output work and raise
AnalysisUnsupportedTargetError, which the provider now keeps, as it does
for the other target-kind checks in this PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:21:22 +00:00
Kaoru0822andClaude Opus 5.5 44d5b4b25e test(artifacts): assert asset-catalog target refusal only on macOS
Outside Darwin the session reports inspect_asset_catalog as unavailable
on the host before the provider checks the target kind, so the Linux
test shards would see capability_unavailable rather than
unsupported_target.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:21:21 +00:00
Kaoru0822andClaude Opus 5.5 637bcb5e41 fix(artifacts): report wrong target kinds as unsupported targets
decode_interface_builder, inspect_asset_catalog, inspect_keyed_archive
and trace_dylib_resolution refused a target of the wrong kind (for
example a plain Mach-O for the asset catalog, or a plist for dyld
tracing) as an `unavailable` artifact failure: "Artifact processing is
unavailable for the current target or host. Check artifact support and
required tools." Nothing was missing on the host; the operation does not
support that kind of target.

Raise AnalysisUnsupportedTargetError for these checks and let
translateFailure keep it. The result is now `unsupported_target`, naming
the operation, the target path and the requirement, with advice to pick
a supported target or another operation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:16:57 +00:00
YsopwnableandGitHub 33d5ae0b52 fix(hopper): reserve Linux demo application before launch (#1158)
* test(hopper): give locals oracle explicit stack storage

* fix(hopper): reserve Linux demo application before launch

* fix(hopper): serialize stale lease recovery
2026-10-09 10:14:25 +08:00
Kaoru0822andClaude Opus 5.5 24a30fd91c fix(apple): report unusable dylib-resolution roots as invalid input
trace_dylib_resolution blamed the artifact for the caller's root
selection. A missing root, a directory, or a symlink leading outside the
bundle got "Artifact contains an unsafe or conflicting internal path ...
correct the artifact". A non-Mach-O file such as Contents/Info.plist got
"Artifact is invalid or has changed. Get a fresh copy". Any schema
failure, including a bad architecture, was reported as "roots must be
normalized paths".

Report a caller-selected root that cannot be traced as an
invalid_request issue on roots[i] with the failed constraint, and
project schema failures through their real issues. The normalized-path
rule now carries a readable message. Roots REA derives itself (bundle
executables or the active target) keep reporting artifact failures.
This matches what #1070 did for inspect_keyed_archive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 02:12:58 +00:00
b620e2a2bd fix(javascript): omit self-referential static references with disclosure (#1157)
* fix(javascript): omit self-referential static references with disclosure

A bundled module that requires its own key (`r(50)` inside webpack
module 50) resolved, through the static-reference composer, to its own
module node. The resulting self-referential imports edge failed result
validation and lost the entire analysis ("Result schema rejected 1
issue ... (custom)"). This is the same invariant as #1146; #1152 fixed
the bundler async-chunk composer, and this is the remaining adjacent
composer.

Skip a reference whose resolved target is its own source, count it, and
disclose the omission the way #1152 discloses async-chunk references.
Sibling requires are kept.

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

* refactor(javascript): share the self-reference omission disclosure

The self-import (#1130), async-chunk (#1152) and static-reference
disclosures repeated one sentence template in three composers, and the
new test repeated the analyze-and-check sequence of its neighbour. That
put jscpd at its 2.5% threshold. Share the template through
selfReferenceOmissions with identical wording, and share one test helper
for the graph-wide self-reference invariants.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:01:59 +08:00
58a91f03d7 fix(artifacts): recheck failed DMG detaches before reporting cleanup failure (#1155)
* fix(artifacts): recheck failed DMG detaches before reporting cleanup failure

NativeDmgArtifactReader.close() detached each device once and, when a
detach failed, asked `hdiutil info` once whether the device was still
attached. On APFS images, detaching the synthesized container ejects the
image disk too. `hdiutil info` can still list that ejected device
briefly, and a just-read volume can report busy. Either way a real
cleanup succeeded but close() reported "DMG detach or mount-root cleanup
failed" and kept the mount root.

macOS CI hit this intermittently in verify:macos-bundle: `hdiutil
detach /dev/disk23` failed with "No such file or directory" (already
ejected) and the device was still counted as attached. The #1103
review also raised the missing recheck.

After the first pass, recheck the remaining devices up to three times
with 250/500/1000 ms settle delays. Drop any that hdiutil no longer
lists, retry the detach of any still listed, and fail only for devices
that stay attached. The host seam gains an optional delay so tests run
without real waits.

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

* test(artifacts): share DMG detach fixtures to stay under the duplication gate

The new busy-device and recheck cases copied the fake hdiutil host and
the APFS close sequence from neighbouring tests, which pushed jscpd to
its 2.5% threshold in Static checks. Share one single-device host
between the busy and retained-attachment cases and one APFS close
helper between the ejected-device cases.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:01:52 +08:00
N0zoM1z0 5160d9b717 feat(website): explain REA through a first investigation 2026-10-09 10:00:22 +08:00
089bbf58f3 fix(cli): cancel routed JavaScript analysis in rea analyze (#1156)
`rea analyze PATH` routes a JavaScript directory or ASAR to the same
static analysis as `rea analyze-javascript-application`, but it passed
no signal and was not wrapped in withCommandCancellation. On SIGINT the
process was killed with no output (signal SIGINT, empty stdout).
The dedicated command returns a typed `cancelled` result and exits 130.
The #1098 review raised this route.

Decide the route first. A JavaScript target now runs exactly like the
dedicated command: cancellation wraps logging, so the cancelled exit
code is not replaced by the logged failure status. The binary route is
unchanged and keeps its own SIGINT handling in runDirectAnalysis.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:48:10 +08:00
YsopwnableandGitHub 72201668ed fix(javascript): preserve graphs with async chunk self-references (#1152) 2026-10-09 09:37:37 +08:00
Kaoru0822andGitHub 84094af54a Merge pull request #1151 from morluto/docs/readme-french
docs: add French README translation
2026-10-08 18:34:31 -07:00
YsopwnableandGitHub 16624f1324 fix(evidence): cancel exports before atomic publication 2026-10-09 09:29:22 +08:00
Kaoru0822andClaude Opus 5.5 9664b2b101 docs: add French README translation
Adds README_fr.md, translated from the current English README with the
same commands, links, heading structure and FAQ entries. Links Français
from every README language selector and registers it in the README
consistency matrix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 01:21:53 +00:00
morluto 2609352eef chore(release): preserve concurrent main updates 2026-10-09 09:17:44 +08:00
morluto 90f532feb1 chore(release): sync published 6.1.0 checkpoint 2026-10-09 09:16:40 +08:00
YsopwnableandGitHub e9ebfb94ef fix(android): validate engine archive prerequisites (#1145)
* fix(android): validate engine archive prerequisites

* fix(android): bound engine metadata reads before allocation
2026-10-09 09:15:33 +08:00
Andrew BarnesandGitHub 13935077ba fix(browser): report Windows HAR heap exhaustion (#1147)
Recognize exit code 134 without a signal when the HAR decoder reports
V8 heap exhaustion. Preserve the observed termination in the memory
failure and cover Windows, POSIX, and unrelated decoder failures.
2026-10-09 09:13:00 +08:00
YsopwnableandGitHub 441813c070 perf(mcp): share repeated output schema definitions 2026-10-09 08:46:59 +08:00
morluto c12bad7f13 fix(release): publish reviewed release PR merges 2026-10-09 08:44:47 +08:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>morluto
70e5c24718 chore(main): release rea-agents 6.1.0 (#1106)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-09 08:15:17 +08:00
1883 changed files with 168759 additions and 31459 deletions
@@ -0,0 +1,134 @@
---
name: rea-changelog-update
description: Prepare or rewrite REA release changelogs and GitHub release notes from pinned Git history, with verified contributor thanks and Release Please synchronization.
---
# REA changelog update
Use this for release-note preparation and contributor attribution. Read
[docs/releasing.md](../../../docs/releasing.md) from the repository root for
publication authority and the existing checkpoint checks. This skill prepares
notes; it does not authorize merging, tagging, or publishing.
## Inventory before prose
Fetch complete history and tags. Select the published baseline tag from
`.release-please-manifest.json` on the release PR's **base branch**, and pin that
branch's exact SHA as the editorial target. REA tags are `rea-agents-VERSION`.
Use the proposed version, including its prerelease suffix; do not change the
`always-bump-minor` strategy to imitate OpenClaw's calendar versions.
```bash
node scripts/release-notes.mjs inventory \
--repository morluto/rea --base rea-agents-PREVIOUS \
--target FULL_BASE_BRANCH_SHA --version VERSION \
--manifest /tmp/rea-VERSION.contributions.json
node scripts/release-notes.mjs record \
--manifest /tmp/rea-VERSION.contributions.json \
--summary \
--output /tmp/rea-VERSION.record.md
```
Read the inventory, not just the existing bot draft. It includes side-branch
commits, GitHub-associated PRs whose merge commits are in the range, commit
authors/co-authors, and confirmed closing issues with their reporters. GitHub
connections are paginated. Network errors stop generation; rerun into a new
output file after recovery. Existing output files are never overwritten.
Unresolved commit identities are retained as names/emails with `user: null`;
never guess a handle or thank the merger as a substitute. The report preserves
unknowns. This is a reviewed metadata snapshot, not independent proof that a
human authored a patch. For unattributed identities, unusual merge strategies,
backports, reversions, or references that GitHub did not associate, inspect
the source PRs and diffs and report the limitation. The current collector uses
confirmed PR-closing relationships for issue-reporter credit; unrelated issue
mentions are not automatically credited. Do not claim that merely inventoried
work still ships after a revert.
## Write for users and retain credit
Rewrite only the newest `## [VERSION]` section in `CHANGELOG.md`, preserving its
version/date/link heading. Use single-line Markdown list items under:
- `### Highlights`: a few release-defining user outcomes; no quota for small releases.
- `### Changes`: capabilities and meaningful behavior changes.
- `### Fixes`: reliability, correctness, compatibility, and safety fixes.
- `### ⚠ BREAKING CHANGES`: retain when applicable, with migrations and original
PR/commit references required by the existing checkpoint validator.
Group related work by analyst workflow or user impact. Explain the resulting
behavior in short, concrete entries. Highlights summarize the release; avoid
repeating their full descriptions in Changes. Internal cleanup, tests, CI, and
routine documentation generally belong only in the provenance file. Read ambiguous PRs/diffs before making
claims. Distinguish simulated-provider checks from real-provider verification.
Credit each represented contribution once in the public notes with its link
and `Thanks @...` for its verified human author, known co-authors, and confirmed
closing-issue reporters. Grouping preserves all those credits in one line.
When Highlights, detailed entries or migrations reference the same work,
put its thanks in one of those entries, not all of them. Include issue links.
Direct-commit bullets carry the commit link and known human credit.
Exclude GitHub bots and known agent accounts. REA's observed Anthropic and
Cursor co-author trailers resolve to `@claude` and `@cursoragent` with GitHub
type `User`; the credit policy excludes them while retaining their metadata.
At the REA maintainer's request, omit `@morluto` self-thanks while preserving
authorship in the inventory. Other human contributors remain eligible.
Use explicit GitHub links for cross-repository references to avoid ambiguous
`#NNN` numbers. Unknown handles stay unknown; they are not fabricated credit.
Append the generated `record --summary` provenance link verbatim at the end
of this release. The linked inventory accounts for every discovered in-range
PR and direct contribution, including internal work omitted from the prose.
Do not paste the full `record` output into public notes: it duplicates thanks
and obscures the user-facing changes. Full records remain available for review.
Do not hand-edit generated credits to make validation pass. Refresh the inventory
when product history changes; a prose-only correction can reuse the snapshot.
## Finalize with Release Please
Before changing the live release PR, have authorization for that PR update.
Local preparation and validation can proceed independently.
1. Add `rea:release-notes-finalized` to the selected open release PR **before**
editing its branch/body. Main proposal pushes respect this label. This is
our workflow guard, not Release Please's `autorelease: snooze` mechanism.
A proposal already running must finish before editing. Do not dispatch
manual preparation over finalized notes.
2. On that release branch, save the reviewed inventory as
`docs/releases/VERSION.contributions.json`. This is durable public release
provenance, not a temporary planning file. Do not add credentials or local
environment dumps. Keep the existing version artifacts aligned.
3. Run the existing checkpoint validator and the new checker:
```bash
node scripts/release-notes.mjs check \
--manifest docs/releases/VERSION.contributions.json
node scripts/release-notes.mjs render \
--manifest docs/releases/VERSION.contributions.json \
--output /tmp/rea-VERSION.notes.md
```
The checker supports inline PR bodies, including their surrounding metadata,
up to GitHub's 65,536-character limit. It fails on larger notes rather than
truncating credit; Release Please's overflow-link bodies are not integrated.
4. Update the release PR body with the rendered section while preserving its
Release Please header/footer and component/version structure. Use a body
file for `gh pr edit --body-file`; changing only `CHANGELOG.md` does not
change Release Please's release body. Push only authorized changes.
5. Freshly fetch the PR body to a file and run `check --pr-body FILE`. Review
the complete diff and wait for current CI. Publication checks the body
again before release creation. Avoid further body edits while publishing.
The finalization label freezes bot refreshes, not main. New product changes
after the inventory target require refreshing the notes before publication.
The workflow checks target ancestry and allows only release metadata paths
after that target. It also requires the inventory target to equal the reviewed
merge's first parent, so intervening main commits require a fresh inventory.
Review diffs within the allowed release metadata paths too: the path guard does
not prove that package dependency/script edits are version-only changes.
To resume automatic proposals, remove the finalization label and let the bot
regenerate; expect editorial changes to be replaced.
Existing releases without a contribution inventory retain their current
publication path. Never retag or republish a package to correct release prose.
+20
View File
@@ -0,0 +1,20 @@
---
name: rea-tool-design
description: Design or change REA investigation tools, CLI/MCP contracts, provider capabilities, and Evidence semantics.
---
# REA tool design
Use the [tool-design guide](../../../docs/tool-design.md) for tool boundaries,
contract semantics, provider ownership, and discoverability. Inspect the current
contract and nearest existing tool relevant to the analyst question; source,
documentation, and live catalogs may describe different versions.
For a design request, return the proposed boundary, input/result shape, Evidence
semantics, nearest alternative, and verification approach. Implement when
requested, preserving the user's scope and existing authorization.
For implementation or verification, consult [testing](../../../docs/testing.md)
for the affected consumer and provider lanes, and
[contributing](../../../CONTRIBUTING.md) for generated-file ownership. Read
provider/workflow guides only as the task requires.
@@ -2,7 +2,7 @@
name: reverse-engineer-anything
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA. Use shipped-artifact or requested runtime evidence to explain features, compare versions, decompile code, or guide a reconstruction. Skip REA for ordinary source-repository architecture analysis.
metadata:
version: "33"
version: "37"
---
# REA
@@ -25,50 +25,18 @@ a skill installed from repository main may describe capabilities absent from
an older npm release. Keep complete inline Evidence when that server does not
advertise retained references.
When tools are absent or registration is stale:
If tools are absent, a call is blocked by the client, or a required provider is
unavailable, read [connection and recovery](references/connection-and-recovery.md).
Diagnose the observed blocker, continue useful supported work, and resume the
original task after repair. Client approval, shell PATH, registration and engine
availability have different remedies; avoid repeating setup for all of them.
1. Diagnose without changing files. For Codex, run
`npx -y rea-agents@latest doctor --client codex --json`. Substitute the current
supported client: `claude_code`, `claude_desktop`, `codex`, `cursor`,
`gemini_cli`, `windsurf`, `devin`, `opencode`, `antigravity`, `copilot_cli`,
`commandcode`, `vscode`, `grok_build`, or `grok_bot`. `grok_bot` has no local
file registration: doctor reports the Grok Bot chat step, and setup does not
write `mcp.json`. If the client is unknown, use `doctor --json` and
inspect its registration results before choosing a setup scope.
2. Distinguish the reason. Missing, malformed, or stale registration needs a
scoped configuration repair. An aligned registration with no tools in the
active session needs a restart/reconnection; doctor cannot prove that the
current agent has connected. A missing provider affects only tasks requiring
that provider: static JavaScript inspection needs neither Hopper nor Ghidra,
and Android inspection has separate bring-your-own JADX/Java prerequisites.
3. For a configuration repair, prepare the read-only plan:
`npx -y rea-agents@latest setup --client codex --dry-run --json`.
Use the current client's ID, show its exact proposed paths, backups, and
changes, and obtain approval before setup writes configuration or installs
Hopper. Setup normally installs the matching bundled skill too; include that
replacement in the reviewed plan. After approval, apply the same scope with
`npx -y rea-agents@latest setup --client codex --yes`. Add `--install-hopper`
only if that separate installation was needed and explicitly approved.
4. Restart/reconnect the affected agent. Verify that REA tools actually appear
in the session, then resume the original investigation. If they remain
absent, inspect the client's MCP launch error rather than repeating setup.
REA setup never installs or upgrades Node.js, npm, Homebrew, Java, Ghidra, IDA,
JADX, Binwalk, or Unblob. Use existing prerequisites; do not install unrelated
software to repair
MCP registration. For an unsupported client, use manual stdio registration
with a version-pinned `rea-agents` package or continue through the CLI.
A concrete CLI fallback for an operator-supplied JavaScript tree or ASAR is:
```bash
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
```
No MCP registration or native engine is required. Read the returned Evidence,
graph, limitations, and unknowns with the same care as an MCP result; the CLI
returns the Evidence record directly. This fallback does not establish that
MCP is configured. Native CLI tasks still require their selected engine.
Prefer an existing `rea` CLI. When none is installed and REA package acquisition
is within the authorized scope, use `npx -y rea-agents@latest` in its place.
Configuration repair starts with a read-only setup plan; show paths, backups and
skill replacement before applying authorized changes. Preserve existing approval
and target-execution boundaries. REA setup never installs or upgrades unrelated
software, including Node.js, npm, Homebrew, Java, Ghidra, IDA, JADX, Binwalk or Unblob.
## Route the target first
@@ -114,6 +82,9 @@ explicit path or endpoint and do not need it.
Historical PIDs do not select live processes. Request `include_debugger_context`
only when core-only mapping candidates help; see the
[recorded crash guide](https://github.com/morluto/rea/blob/main/docs/recorded-crashes.md).
- PE resource type/name/language trees and static icon group references:
`inspect_pe_resources` with an explicit path. This portable operation requires
no active target or engine; opaque payloads retain file ranges and SHA-256.
- Native executable, library, or analysis database: `open_binary`, then
use focused analysis tools directly; call `binary_overview` when metadata or
inventory context is useful and available from the selected provider.
@@ -130,9 +101,11 @@ after opening; IDA does not supply `binary_overview`. Consult session availabili
when composing broader workflows. Modern direct callers and unsupported dossier
facets remain unknown; live IDA results are not replayed from snapshots.
If the app is missing, ask which app to inspect. Resolve a human-readable app
name to one clear installed artifact when possible; ask only when matches are
ambiguous. Never choose an example app on the user's behalf.
If the user says only "my app" without a name, path, or target already selected
for this task, ask which app before searching for artifacts. Paths in unrelated
saved reports and nearby test fixtures do not select the user's target. Resolve
an actual human-readable app name to one clear installed artifact when possible;
ask when matches are ambiguous. Never choose an example app on the user's behalf.
In a target-free session, use `open_binary` to bind any archive/package or
native target whose analysis tool operates on the active target. Do not call an
@@ -143,15 +116,42 @@ list stays complete; availability depends on the operation, target, and host.
## Work summary-first
Start with the default result and use its inline Evidence and graph context.
Do not repeat an identical tool call. Make a focused follow-up only when the
For a JavaScript application or ELF layout whose size is unknown or large,
call `analyze_javascript_application` or `inspect_binary_layout` with
`"detail": "summary"`, then inspect the retained `parent_evidence_id` with
`inspect_analysis_view`.
Page module identities and select the returned `node_id` before requesting an
item; a single file path can represent several graph roles. Do not repeat an
identical analysis or rejected call without a changed input or resolved blocker.
Recheck session state when a lifecycle change makes that status useful.
Make a focused follow-up only when the
returned result leaves a specific question unanswered.
If MCP reports `resource_constraint` with `details.resource: "transport"`, use
its reported same-session Evidence reference with a focused application tool,
or call `export_evidence_bundle` to write the complete session to a selected
path. The analysis remains complete in the ledger; avoid repeating it merely
to request the same oversized response. Complete CLI JSON output also streams
without a single MCP frame.
If MCP reports `resource_constraint` with `details.resource: "transport"`, call
`inspect_analysis_view` with its reported same-session Evidence reference for a
summary, one section/module, or a stable page. Use `trace_application_feature`
once a seed is known, or call `export_evidence_bundle` to write the complete
session to a selected path. The analysis remains complete in the ledger; avoid
repeating it merely to request the same oversized response. Complete CLI JSON
output also streams without a single MCP frame.
When the retained parent ID is unknown, use `get_evidence_bundle` with
`detail: "summary"` and exact filters for operation, target SHA-256,
analysis-profile digest or canonical procedure address. Select its returned
Evidence ID for the next view instead of requesting the complete bundle.
`retention: "complete-record"` means the whole record is stored; native
value-flow truncation and unknown metadata remain separate. For an exported
portable bundle, use `rea inspect-evidence-bundle` with JSON containing `path`,
`detail: "summary"` and the same `filters`. Reading that file still requires
validating its full contents within the local memory budget.
A client can also truncate a successful tool result without a REA transport
error. Treat that preview as incomplete; use the retained parent ID for smaller
views or export when the full record is needed. Do not parse the preview as
canonical JSON or repeat the producer. For JavaScript, read the
[module-view and trace recipes](references/javascript-applications.md) before
drilling into a large graph; a broad bidirectional trace can expand unrelated
containment relationships even after summary analysis.
Every conclusion must distinguish observations, inferences, and unknowns. Cite
Evidence IDs, preserve limitations and incomplete coverage, and never imply
@@ -160,7 +160,9 @@ target and lifecycle; do not broaden the target or action beyond those fields.
Within the user's requested investigation, call available analysis tools
directly. REA does not require permission grants or per-call approval flags.
Follow the declared request scope and the host's actual access requirements.
The agent client can independently require approval. Follow the declared request
scope and the host's actual access requirements; use the recovery guide for an
observed client-policy rejection.
## Plan broader investigations
@@ -19,9 +19,12 @@ can select Java. REA setup does not install or configure that JAR, and doctor
provider scopes cover Hopper/Ghidra rather than JADX. Use existing tools and
report missing prerequisites for the Android task specifically.
Real verification covers Linux. macOS has the POSIX launch boundary but no
claimed real-provider verification; Windows is unsupported. Calls use one
worker, a bounded JVM heap, and provider deadlines. The APK is never launched,
Linux and macOS use the POSIX owned-process boundary. Windows x64 requires the
matching bundled native controls and uses an owned Job Object with bidirectional
stdio. A full JDK, including `jdk.compiler`, is required on every host; Windows
`JAVA_HOME` selects `bin\java.exe`. Consult the Android guide for actual host
verification coverage. Calls use one worker and provider deadlines; optional
`REA_JADX_HEAP_MIB` selects the JVM heap. The APK is never launched,
and no emulator is required.
Manifest entries and decompiled text are static observations, not execution or
@@ -0,0 +1,127 @@
# Connection and task recovery
Read this guide only for an observed connection, command, approval or provider
blocker. Keep the user's target and question in view. Explain what prevented the
operation and the next useful step; after repair, continue the investigation.
Commands below use an installed `rea`. If none is available, use the package
invocation in `SKILL.md` when acquiring REA is authorized. Follow the connected
server's schemas and the installed CLI's help rather than assuming repository
main and an older release expose the same arguments.
## Choose the remedy from the observed failure
| Observation | Meaning and next step |
| --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| No REA tools in the active session | Inspect registration with `rea doctor --client codex --json`. A skill installation alone does not register MCP. |
| Missing, malformed or stale registration | Prepare a scoped setup plan; apply only authorized changes with backups. |
| Aligned registration, but no connected tools | Restart/reconnect the client. Doctor checks registration; it cannot establish the current agent's connection. Inspect the client's launch error if reconnection fails. |
| `MCP tool call requires approval, but approval policy is never` | Codex rejected the call before REA executed it. Do not install an engine or repeat setup to solve this client-policy decision. See the approval section below. |
| REA returns `provider_unavailable` or an unavailable tool entry | Read that operation's provider diagnostics or `binary_session.result.tool_availability`. Resolve only the prerequisite needed for the task; a complete tool catalog does not imply every operation is available. |
| `rea` is missing in a child shell, or Node is incompatible | Inspect the actual shell PATH and launcher/runtime. A prefix installation may be absent from a login shell's PATH; this does not establish a broken MCP registration. |
If the client cannot launch its shell/sandbox helper or read the installed skill,
inspect its launch diagnostic. For example, Codex can refuse helper aliases when
CODEX_HOME is under `/tmp`; use an authorized profile outside the OS temporary
directory. REA setup cannot repair the client's executor. Preserve the sandbox
instead of silently disabling it to make an analysis command work.
Static JavaScript and ordinary ZIP inventory need neither Hopper nor Ghidra.
HAR inspection is offline and does not require a live browser. Native
decompilation, Android analysis and firmware extraction have their own
bring-your-own prerequisites. Use supported inventory/static evidence when it
answers part of the question, and name the unavailable evidence separately.
Do not substitute another target. Label observations from ordinary shell tools
as such; only actual REA output supplies REA Evidence.
## Repair registration when needed
For Codex:
```bash
rea doctor --client codex --json
rea setup --client codex --dry-run --json
```
Use the current supported client's ID: `claude_code`, `claude_desktop`, `codex`,
`cursor`, `gemini_cli`, `windsurf`, `devin`, `opencode`, `antigravity`,
`copilot_cli`, `commandcode`, `qwen_code`, `vscode`, `grok_build`, `omp`, `pi`,
`hermes`, or `grok_bot`. If unknown, inspect `doctor --json` before choosing a
scope. `grok_bot` uses a chat registration step rather than local `mcp.json`.
For unsupported clients, use version-pinned manual stdio registration or CLI.
Show the plan's exact paths, backups, changes and bundled-skill replacement.
Obtain approval for writes when that concrete scope is not already authorized,
then apply the same scope with `rea setup --client codex --yes`. Add
`--install-hopper` only when separately needed and explicitly approved. Do not
install or upgrade unrelated prerequisites. Restart/reconnect, verify tools
actually appear, and resume the original task. If they remain absent, inspect
the launch failure rather than looping through setup.
## Codex tool approval is separate from REA readiness
REA tools have no permission-grant handshake. Codex can still require approval
because an operation creates owned resources, launches a helper or has cleanup
effects. An advertised tool or successful doctor result does not override that
client policy. `workspace-write` alone does not resolve an MCP approval
rejection, and `approval_policy = "never"` does not mean every MCP tool is
preapproved.
When interactive approval is available, use the client's approval flow for the
requested operation. In an unattended run, continue through an authorized CLI
workflow if the execution environment permits it, or report the blocked
operation and the approval needed to proceed. Do not retry the same rejected
call, silently broaden approvals, or rewrite MCP effects as read-only.
For an operator who explicitly wants to preapprove named operations in a
disposable Codex profile, current Codex supports per-tool configuration. For
example, opening and closing an analysis session can be scoped independently:
```toml
[mcp_servers.rea.tools.open_binary]
approval_mode = "approve"
[mcp_servers.rea.tools.close_binary]
approval_mode = "approve"
```
Use the actual server ID and only the operations whose effects were approved;
this example does not approve inspection, extraction or runtime execution.
Show the proposed config edit and preserve unrelated entries and backups before
writing. Managed policy can constrain client settings. Consult the
[Codex configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference)
for the installed client's supported settings. This is an optional recovery
choice, not a prerequisite for every REA task.
## Continue through an installed CLI
Check the command environment only if the launcher fails:
```bash
command -v rea
command -v node
node --version
rea --version
```
Use the public launcher at its known installation path with a supported existing
Node on PATH when the child shell loses a prefix installation. Avoid internal
`dist/cli.js` entrypoints or global toolchain changes. MCP may have its own valid
launcher even when a shell cannot resolve `rea`.
For a user-supplied JavaScript tree or ASAR, select output files in the authorized
workspace and save complete Evidence before reading a view:
```bash
rea analyze-javascript-application /absolute/path/to/app --json > app-evidence.json
jq -c '{source: {kind: "inline", evidence: .}, view: {kind: "summary"}}' app-evidence.json > app-view.json
rea inspect-analysis-view app-view.json
```
These commands do not register MCP or install an analysis engine. CLI JavaScript
JSON is complete and can be very large; redirect it rather than loading it into
context. Use an existing JSON processor if `jq` is absent, without installing
one just for this recipe. Inspect a module page or item using the same inline
source and the [JavaScript recipes](javascript-applications.md). Preserve graph
coverage, limitations and unknowns. Native CLI analysis still requires its
selected engine, and all CLI operations retain the host's execution permissions.
@@ -1,11 +1,15 @@
# Evidence, comparison, and verification workflows
REA returns Evidence with each result. Read that result directly, cite its
Evidence ID when another tool or your explanation needs a stable reference, and
preserve authority, limitations, coverage, and residual unknowns. If a result
Evidence-producing tools return the complete Evidence record directly in MCP
`structuredContent` and CLI JSON. Read `normalized_result` for operation data,
and cite `evidence_id` when another tool or your explanation needs a stable
reference. Preserve authority, limitations, coverage, and residual unknowns. If a result
is incomplete or paginated, continue only when the remaining data matters to
the task; do not fetch a bundle or resource merely to read a result already
returned inline.
returned inline. When complete `inspect_binary_layout` or
`analyze_javascript_application` Evidence is already retained, call
`inspect_analysis_view` for a summary, one section/symbol/module, or a stable
page instead of repeating the producer.
Use `record_unknown` to track unresolved questions in the user's investigation
and name the authority or environment still required. Supply supporting and
@@ -34,3 +38,11 @@ or absence:
Process captures are opt-in behavioral evidence, not a security sandbox. V3
captures cannot be upgraded to V4; rerun the original scenario. Distinguish root
exit from descendant settlement and require freshness when the task needs it.
A timed-out target that must write a final report needs `finalization_ms`: REA
sends SIGTERM to the captured root, keeps observing, and sends SIGKILL once
only if the target has not exited by the end of the interval.
`exit.finalization.signals` lists each attempt with its delivery result; the
observed exit signal stays in `exit.signal`, `exit.code` is null for every
deadline exit, and the code of a finalizer that exited on its own is in
`exit.finalization.exit_code` (null on a signal exit or when no exit was
observed).
@@ -0,0 +1,149 @@
# JavaScript and Electron application artifacts
Use `analyze_javascript_application` directly on the operator-supplied ASAR or
extracted tree. When size is unknown or large and the connected schema advertises
`detail`, request `detail: "summary"`. This returns an `inspect_analysis_view`
Evidence record with a distinct ID and a `normalized_result.parent_evidence_id`
for the complete retained application analysis. Source-map contents are part of
that static analysis. Read findings, coverage, limitations and unknowns, then
follow a specific unanswered question. Older servers without `detail` return
the complete application Evidence inline when it fits.
When the connected schema advertises `max_heap_mb` and `analysis_timeout_ms`,
these select the isolated source analyzer's old-space heap and per-source
deadline. Defaults are 1024 MiB and 300000 ms. They do not change the MCP
process heap. Resource-limited analyses preserve completed static facts and
report partial semantic coverage with specific unknown scopes; this does not
mean the source is malformed. Inspect those limits before retrying a source.
When expanded relationships exceed the parent's available memory, inspect the
file's modules item view for retained `static_analysis` and
`semantic_module_analysis`. Their facts remain available even when graph links
are unknown. Cumulative result exhaustion can stop analysis before every file
is examined; the inventory and remaining unknown scopes distinguish that case.
Timeout or cancellation after source analysis begins retains partial Evidence
in the same session. A returned `error.details.partial_observation` reference
can be supplied directly to `inspect_analysis_view`. If the SDK cancels locally, retrieve its recorded ID from
the Evidence bundle before inspecting the partial analysis.
## Read a module without repeating analysis
Use the actual returned parent ID, on the same connection, as `source.evidence_id`.
The following IDs are placeholders to replace with returned values. When the
module's node ID is not already known, page identities before selecting an item.
Pages return only node IDs, paths and roles; choose a useful page size and follow
`coverage.next_offset` when another page matters:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "ev_ACTUAL_PARENT_ID"
},
"view": { "kind": "page", "collection": "modules", "offset": 0, "limit": 16 }
}
```
Select the relevant page entry by its exact `node_id` and recorded role:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "ev_ACTUAL_PARENT_ID"
},
"view": {
"kind": "item",
"collection": "modules",
"selector": { "node_id": "jag_node_ACTUAL_NODE_ID" }
}
}
```
Module pages include asset, bundled and source module roles, so one path can
identify several entries. Use `selector.path` only when uniqueness is established;
the returned node ID avoids needing a complete inventory to prove uniqueness. On ambiguity,
select the matching node ID from the page or the error's candidates. Follow
`next_offset` when another page matters. An item exposes that module node's
recorded observations, identity, hashes, exports and source ranges; it does not
include every child syntax observation, related edge or original source file.
An absent item fact is not evidence of absence from the whole application.
## Trace only the remaining question
Use `trace_application_feature` on the parent application Evidence for one
literal node ID, route, string, API, IPC channel, module, or native export.
Select `incoming` for relationships leading to the seed, `outgoing` for those
leaving it, and `both` when the question needs both. Trace traversal includes
containment relationships, so even a narrow seed can expand many nodes; a
bidirectional trace can reach unrelated sibling modules. A module item or page
is preferable when its observations already answer the question. Do not treat
all reached nodes as participants in the feature.
Reuse retained parent Evidence when the server advertises it, or supply complete
Evidence inline. Include Hopper or Ghidra Evidence only when its artifact digest
matches exactly.
## Recover an oversized display
An oversized response reports `resource_constraint` and
`details.resource: "transport"`. Reuse
`details.reported_limits.evidence_reference` with `inspect_analysis_view` for a
summary, one module, or a stable page of module identities.
`export_evidence_bundle` writes the complete canonical session to a
caller-selected file. These workflows keep the original Evidence and coverage;
a broad follow-up can also exceed framing.
A client can truncate a successful result inside its text envelope without a
REA `resource_constraint`. Treat a truncation notice or incomplete JSON as a
display limitation; do not claim the full record was examined. Reuse the known
parent ID for smaller views, or export complete Evidence to a selected file
while the session remains open. If the parent ID was lost from the preview,
use the prior analysis summary or explicit ledger entries to recover it; do
not invent an ID or rerun analysis just to reproduce the same display.
BrowserWindow preferences, preload and contextBridge surfaces, IPC
registrations, utility processes, and native binding requests are static syntax
observations. Only a unique exact literal IPC channel match supports an inferred
pairing. Dynamic or ambiguous channels remain unresolved. A requested `.node`
member is not a verified native export. Never claim runtime reachability,
registration, defaults, or policy enforcement from static analysis.
For version comparison, analyze each version once, then call
`compare_application_versions`. Accept only its digest, source-map, structural
fingerprint, or non-module semantic matches. Module ordinals and minified names
are not persistent identity. Report added or removed only with complete
opposite-side coverage; otherwise report unknown.
When the question asks how one exact exported callable's returned object shape
changed, analyze each version once and then call
`compare_javascript_export_shapes` with explicit module paths and export names.
Use the returned IDs on the same connection, or complete inline Evidence
records, from both analysis calls. Accept variant
pairing only through the tool's unique exact literal discriminant. Read
`property_inventories` and each change's `presence` before treating `unknown` as
"the name was not observed": inventories list observed property names even when
values stay unknown, with a `source_range` for each paired or unpaired variant.
Array holes and mutation-invalidated slots are not observed properties.
Complete parent coverage reports presence-only
`added`/`removed` independently of unresolved values. Cite the
comparison Evidence and report JSON Pointer changes; dynamic values, ambiguous
variants, and incomplete parent-property coverage stay unknown. This is static
inference, not runtime behavior. When runtime semantics are needed, run
behavioral probes against the relevant application versions and capture them
through the available browser, Electron, or process workflows.
## Reusing application Evidence
When advertised by the connected server, application trace and compare tools
accept complete inline Evidence or
`{"kind":"retained-evidence","evidence_id":"ev_<64 lowercase hex characters>"}`
for their application input (`application`, or `left`/`right`). `inspect_analysis_view`
uses the same retained-reference form in `source`, or portable inline Evidence,
to project a summary, module page, or one module with its recorded observations. This notation is
a template: replace it with the actual returned ID. Versions before 4.1.0 accept only full
inline Evidence. Use the exact ID
returned by the producer on the same MCP connection. Resolution does not run
analysis or select a provider; findings remain inline. Native observation
arrays still take full Evidence. `close_binary` clears retained references;
export a bundle before closing, or supply portable inline Evidence in another
connection. A missing reference includes its ID and recovery guidance.
@@ -16,6 +16,15 @@ Requested unavailable context fails with setup guidance. See
[recorded crashes](https://github.com/morluto/rea/blob/main/docs/recorded-crashes.md)
for exact upstream profiles, bounds and verification coverage.
## Offline ELF layout
Use `inspect_binary_layout` with an explicit local ELF path for file-backed
sections, symbols, relocations, linkage names, and static mitigation inferences
without opening a disassembler target. When that complete record is already
retained, call `inspect_analysis_view` for a summary, mitigations or linkage
facet, one section or symbol, or a stable page. Do not re-run the decoder to
read a single object.
## Native targets
After `open_binary`, use focused search, procedure, or function tools directly.
@@ -25,6 +34,15 @@ cross-references. Addresses and recovered pseudocode are analysis observations,
not original source. Provider unavailability and unsupported metadata remain
unknown rather than false.
For a completed `analyze_function` dossier, use `inspect_analysis_view` with
`view: {kind: "native", facet: "value_flow_operations", offset: 0, limit: 32}`
and the exact retained Evidence ID to read selected facts without reanalysis.
Native facets also include procedure, pseudocode, assembly, basic blocks,
comments, callers/callees, references, unresolved calls, referenced strings and
names, the native API record, and value-flow summaries. Pseudocode offsets and limits count UTF-16
code units; use the returned `next_offset` for continuation. Provider limitations
and unavailable facts remain explicit; the complete parent Evidence is retained.
To see which functions or Objective-C methods a Mach-O actually calls in one
run, use `observe_native_calls` with explicit breakpoints and a bounded
`duration_ms`/`max_events`. It launches a new process under LLDB, so the target
@@ -51,6 +69,15 @@ use inclusive ends and can contain gaps. Do not treat the enclosing span as code
For packed targets, retain the original and separately derived artifact identities;
decompiling an unpacking stub does not recover the unpacked program.
When reading Objective-C dispatch metadata, distinguish class implementation
methods from protocol requirements: class methods report null requirement
flags, while decoded protocol declarations retain required and optional facts.
Property attributes remain raw name/value tokens; use the property's
`atomicity` field for the decoded `N` marker or the default atomic behavior.
Null class/meta flags, ivar counts, atomicity, or read-only values mean the
selected provider did not establish that fact. Symbol names alone do not prove
that a class is a root class or has no ivars.
## Managed PE/CLI
Start with `inspect_managed_artifact`. REA's canonical managed inspection is
@@ -125,4 +152,16 @@ context. PSP/stack/device state remains unmodeled. See [DOS guide](https://githu
### Function annotations in Ghidra
Use `annotate_native_function` for one function name and/or entry comments, with at least one explicit change. Review its annotation readback and refreshed dossier inline. Changes are atomic and session-scoped; empty comments clear them, omitted fields preserve them. Later MCP calls observe edits until close. CLI `annotate-native-function` returns the updated analysis before discarding the session. Original executable bytes are unchanged; edits invalidate immutable snapshots. Windows P0 does not admit database mutations.
Use `annotate_native_function` for one function name and/or entry comments, with at least one explicit change. Review its annotation readback and refreshed dossier inline. Changes are atomic and session-scoped; empty comments clear them, omitted fields preserve them. Later MCP calls observe edits until close. CLI `annotate-native-function` returns the updated analysis before discarding the session. Original executable bytes are unchanged; edits invalidate immutable snapshots. Windows P0 does not admit database mutations. For naming only, `set_address_name` / `set_addresses_names` also work with Ghidra: they name function entries or data addresses (primary labels) and return compact per-address success booleans instead of a dossier.
## Offline PE resource inventory
Use `inspect_pe_resources` with an absolute `path`, or
`rea inspect-pe-resources ./selected.exe --json`, for portable PE32/PE32+
resource inspection without opening a native target. Preserve returned Evidence:
type/name/language IDs and UTF-16 names, original directory/data/payload ranges,
code pages, payload hashes and static icon-group references. Same-language icon
resolution is explicit; missing references and size mismatch remain visible.
Other payloads are opaque, and this operation does not decode images or simulate
Windows resource loading. Consult the budgets and supported tree profile in
[offline binary diagnostics](https://github.com/morluto/rea/blob/main/docs/binary-diagnostics.md).
+6
View File
@@ -0,0 +1,6 @@
self-hosted-runner:
labels:
- hopper
- ghidra-12-1-2
# Hosted label introduced after the pinned actionlint release.
- macos-15-intel
+1 -1
View File
@@ -28,7 +28,7 @@ intentionally not included. -->
- Provider, bridge, target-format, or platform compatibility:
- Evidence, artifact, provenance, or reconstruction contract:
- Process execution, authorization, cleanup, or containment impact:
- Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `skill-src/` and never commit build outputs):
- Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `.agents/skills/reverse-engineer-anything/` and never commit build outputs):
## Evidence and regression coverage
+163 -92
View File
@@ -5,10 +5,16 @@ on:
branches: [main]
pull_request:
branches: [main, "release/*"]
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
# The latest main push verifies the full tree, including earlier changes.
# Publication uses its own release workflow and concurrency group.
cancel-in-progress: true
env:
HUSKY: "0"
@@ -34,30 +40,39 @@ jobs:
name: Classify changes
runs-on: ubuntu-latest
outputs:
code: ${{ steps.package.outputs.required }}
package: ${{ steps.package.outputs.required }}
code: ${{ steps.plan.outputs.code }}
runtime: ${{ steps.plan.outputs.runtime }}
package: ${{ steps.plan.outputs.package }}
apple: ${{ steps.plan.outputs.apple }}
fixtures: ${{ steps.plan.outputs.fixtures }}
readiness: ${{ steps.plan.outputs.readiness }}
docs: ${{ steps.plan.outputs.docs }}
workflows: ${{ steps.plan.outputs.workflows }}
browser: ${{ steps.plan.outputs.browser }}
binary_layout: ${{ steps.plan.outputs.binary_layout }}
evm: ${{ steps.plan.outputs.evm }}
javascript_recovery: ${{ steps.plan.outputs.javascript_recovery }}
recorded_crash: ${{ steps.plan.outputs.recorded_crash }}
web_network: ${{ steps.plan.outputs.web_network }}
web_runtime: ${{ steps.plan.outputs.web_runtime }}
web_source_map: ${{ steps.plan.outputs.web_source_map }}
nativeaot: ${{ steps.plan.outputs.nativeaot }}
website: ${{ steps.plan.outputs.website }}
matrix: ${{ steps.plan.outputs.matrix }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Select package and Windows lanes
id: package
shell: bash
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
- name: Select verification lanes
id: plan
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
echo "required=true" >> "${GITHUB_OUTPUT}"
elif git diff --quiet "${BASE_SHA}" "${HEAD_SHA}" -- \
. \
':(exclude)docs/**' \
':(exclude)AGENTS.md' \
':(exclude)CONTRIBUTING.md'; then
echo "required=false" >> "${GITHUB_OUTPUT}"
else
echo "required=true" >> "${GITHUB_OUTPUT}"
fi
CI_FULL: ${{ contains(github.event.pull_request.labels.*.name, 'ci:full') }}
run: node scripts/ci/plan.mjs
static:
name: Static checks
@@ -75,17 +90,17 @@ jobs:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
- if: needs.changes.outputs.code == 'true'
run: npm run check:ci
- if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
- if: needs.changes.outputs.code == 'true'
run: npm run verify:test-discovery
- if: github.event_name == 'pull_request' && needs.changes.outputs.code != 'true'
- if: needs.changes.outputs.code != 'true'
run: npm run format:check
test-shard:
name: Test shard (${{ matrix.shard }})
needs: [changes, build]
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -102,7 +117,7 @@ jobs:
with:
name: rea-dist
path: dist
- name: Restore generated outputs from downloaded build
- name: Generate test artifacts from the downloaded runtime
run: |
node scripts/generate-mcp-tool-catalog.mjs
node scripts/generate-skill-metadata.mjs
@@ -122,7 +137,7 @@ jobs:
build:
name: Build package
needs: changes
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -215,7 +230,7 @@ jobs:
conformance-fixtures:
name: Source-built conformance fixtures
needs: changes
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
if: needs.changes.outputs.fixtures == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
@@ -226,7 +241,7 @@ jobs:
windows-native-build:
name: Build bundled Windows x64 native controls
needs: changes
if: github.event_name == 'push' || needs.changes.outputs.package == 'true'
if: needs.changes.outputs.runtime == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
@@ -256,24 +271,11 @@ jobs:
package-e2e:
name: Native package baseline (${{ matrix.platform }} ${{ matrix.architecture }})
needs: [changes, windows-native-build]
if: github.event_name == 'push' || needs.changes.outputs.package == 'true'
if: needs.changes.outputs.runtime == 'true'
strategy:
fail-fast: false
max-parallel: 2
matrix:
include:
- os: ubuntu-latest
platform: linux
architecture: x64
- os: ubuntu-24.04-arm
platform: linux
architecture: arm64
- os: macos-15
platform: darwin
architecture: arm64
- os: macos-15-intel
platform: darwin
architecture: x64
matrix: ${{ fromJSON(needs.changes.outputs.matrix) }}
runs-on: ${{ matrix.os }}
timeout-minutes: 20
env:
@@ -302,13 +304,13 @@ jobs:
- run: npm run verify:windows-native:artifact
- run: npm run verify:package
- name: Verify real Node Inspector discovery and observation
if: matrix.platform == 'darwin'
timeout-minutes: 10
run: npm run verify:inspector
apple-artifacts:
name: Real Apple artifact CLI/MCP E2E
needs: changes
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
if: needs.changes.outputs.apple == 'true'
runs-on: macos-15
timeout-minutes: 15
steps:
@@ -321,6 +323,8 @@ jobs:
- run: npm run verify:keyed-archive
- run: npm run verify:asset-catalog
- run: npm run verify:macos-bundle
- name: Legacy simulator platform verification
run: npm run verify:legacy-simulator
- name: Native installer and compiled NIB hierarchy regressions
run: npm run test:focused -- tests/boundary/filesystem/installScript.test.ts tests/boundary/filesystem/nibNativeHierarchy.test.ts tests/boundary/filesystem/interfaceBuilderBundle.test.ts
- name: Real binary metadata and Interface Builder integration
@@ -334,12 +338,12 @@ jobs:
- name: Process filesystem snapshot descriptor regressions
run: npm run test:focused -- src/process/capture/FilesystemSnapshot.test.ts
- name: Native Darwin ownership and process cleanup regressions
run: npm run test:focused -- tests/boundary/process/darwinProcessRunTokenReader.test.ts tests/boundary/process/processCaptureLifecycle.test.ts tests/boundary/process/processCli.test.ts tests/boundary/mcp/sessionMcp.test.ts
run: npm run test:focused -- tests/boundary/process/darwinProcessRunTokenReader.test.ts tests/boundary/process/directAnalysisSignals.test.ts tests/boundary/process/processCaptureLifecycle.test.ts tests/boundary/process/processCli.test.ts tests/boundary/mcp/sessionMcp.test.ts
reconstruction-readiness:
name: Reconstruction readiness
needs: changes
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
if: needs.changes.outputs.readiness == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
@@ -365,52 +369,10 @@ jobs:
if-no-files-found: error
retention-days: 30
javascript-runtime-observation:
name: JavaScript runtime observation (${{ matrix.os }})
needs: changes
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
strategy:
fail-fast: false
max-parallel: 2
matrix:
include:
- os: ubuntu-latest
platform: linux
architecture: x64
- os: ubuntu-24.04-arm
platform: linux
architecture: arm64
- os: windows-latest
platform: win32
architecture: x64
runs-on: ${{ matrix.os }}
timeout-minutes: 10
env:
NODE_OPTIONS: "--max-old-space-size=1024"
UV_THREADPOOL_SIZE: "2"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- name: Verify native runtime identity
env:
EXPECTED_CI_PLATFORM: ${{ matrix.platform }}
EXPECTED_CI_ARCHITECTURE: ${{ matrix.architecture }}
run: >-
node -e "const assert = require('node:assert/strict');
assert.equal(process.platform, process.env.EXPECTED_CI_PLATFORM);
assert.equal(process.arch, process.env.EXPECTED_CI_ARCHITECTURE);
console.log(JSON.stringify({ platform: process.platform, architecture: process.arch, node: process.version }));"
- run: npm ci
- name: Verify real Node Inspector discovery and observation
run: npm run verify:inspector
windows-curated:
name: Windows capability and package lane
needs: [changes, windows-native-build]
if: github.event_name == 'push' || needs.changes.outputs.package == 'true'
if: needs.changes.outputs.package == 'true'
runs-on: windows-latest
timeout-minutes: 25
steps:
@@ -448,15 +410,14 @@ jobs:
tests/boundary/filesystem/binaryTarget.test.ts
tests/boundary/filesystem/safeOutputTree.test.ts
tests/boundary/providers/native/artifactProvider.archiveSafety.test.ts
tests/boundary/providers/native/artifactProvider.extractionCompleteness.test.ts
tests/boundary/filesystem/setupUnavailableProvider.test.ts
tests/boundary/filesystem/windowsNpxRegistration.test.ts
src/application/ClientRegistrationIdentity.test.ts
tests/boundary/filesystem/webScriptManifestPaths.test.ts
tests/boundary/process/ProcessEvidence.host.test.ts
tests/acceptance/webModuleCli.test.ts
tests/acceptance/webSourceLocationCli.test.ts
tests/boundary/cli/referenceSourceImportStatus.test.ts
src/cliReferenceSourceImportStatus.test.ts
tests/boundary/filesystem/asarInventoryFreshness.test.ts
tests/composition/javascript-applications/javascriptArtifactReconstruction.test.ts
tests/conformance/providers/ghidra/windowsCapabilities.test.ts
@@ -464,6 +425,7 @@ jobs:
tests/boundary/providers/ghidra/ghidraTransport.test.ts
tests/boundary/providers/ghidra/ghidraTargetSnapshot.test.ts
tests/boundary/providers/ghidra/ghidraLauncher.test.ts
tests/boundary/providers/hopper/hopperClient.cleanupRetry.test.ts
src/windows/WindowsNativeLoader.test.ts
src/windows/WindowsOwnedProcess.test.ts
src/ghidra/GhidraLauncherEnvironment.test.ts
@@ -475,6 +437,12 @@ jobs:
tests/process-global/updateMaintenance.test.ts
tests/conformance/providers/ghidra/realGhidraWindowsWorkflow.test.ts
- run: npm run verify:windows-native
- name: Verify real Node Inspector discovery and observation
timeout-minutes: 10
env:
NODE_OPTIONS: "--max-old-space-size=1024"
UV_THREADPOOL_SIZE: "2"
run: npm run verify:inspector
- run: npm run verify:package:windows
- name: Verify native directory identity on Node 24
run: >-
@@ -485,12 +453,13 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 22.19.0
- name: Verify native directory identity on Node 22
- name: Verify native path boundaries on Node 22
run: >-
npx vitest run --coverage.enabled=false
tests/boundary/filesystem/directoryArtifactReaderOpen.test.ts
tests/boundary/filesystem/javascriptPackagePrecedence.test.ts
tests/boundary/filesystem/javascriptArtifactContentIdentity.test.ts
tests/boundary/process/sourceMapUncHosts.test.ts
- uses: actions/upload-artifact@v4
if: always()
with:
@@ -500,7 +469,8 @@ jobs:
docs:
name: Docs Generation
if: github.event_name == 'pull_request'
needs: changes
if: needs.changes.outputs.docs == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -520,3 +490,104 @@ jobs:
docs/verification/managed-conformance-*.json
skills/reverse-engineer-anything
if-no-files-found: error
workflows:
name: Validate workflows
needs: changes
if: needs.changes.outputs.workflows == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate workflow syntax and expressions
run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.7 -shellcheck= -pyflakes=
browser:
needs: changes
if: needs.changes.outputs.browser == 'true'
uses: ./.github/workflows/real-browser.yml
binary_layout:
needs: changes
if: needs.changes.outputs.binary_layout == 'true'
uses: ./.github/workflows/real-binary-layout.yml
evm:
needs: changes
if: needs.changes.outputs.evm == 'true'
uses: ./.github/workflows/real-evm-interface.yml
javascript_recovery:
needs: changes
if: needs.changes.outputs.javascript_recovery == 'true'
uses: ./.github/workflows/real-javascript-recovery.yml
recorded_crash:
needs: changes
if: needs.changes.outputs.recorded_crash == 'true'
uses: ./.github/workflows/real-recorded-crash.yml
web_network:
needs: changes
if: needs.changes.outputs.web_network == 'true'
uses: ./.github/workflows/real-web-network-captures.yml
web_runtime:
needs: changes
if: needs.changes.outputs.web_runtime == 'true'
uses: ./.github/workflows/real-web-runtime.yml
web_source_map:
needs: changes
if: needs.changes.outputs.web_source_map == 'true'
uses: ./.github/workflows/real-web-source-map.yml
nativeaot:
needs: changes
if: needs.changes.outputs.nativeaot == 'true'
uses: ./.github/workflows/nativeaot-fixtures.yml
website:
needs: changes
if: needs.changes.outputs.website == 'true'
uses: ./.github/workflows/website-check.yml
required:
name: CI required
if: ${{ always() }}
needs:
[
changes,
pr-title,
static,
build,
test-shard,
test,
conformance-fixtures,
windows-native-build,
package-e2e,
apple-artifacts,
reconstruction-readiness,
windows-curated,
docs,
workflows,
browser,
binary_layout,
evm,
javascript_recovery,
recorded_crash,
web_network,
web_runtime,
web_source_map,
nativeaot,
website,
]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
- name: Require every selected lane to pass
env:
CI_JOBS: ${{ toJSON(needs) }}
run: node scripts/ci/required.mjs
+1 -6
View File
@@ -2,12 +2,7 @@ name: Source-built NativeAOT fixtures
on:
workflow_dispatch:
pull_request:
paths:
- "bridge/ghidra/extensions/nativeaot/**"
- "scripts/generate-nativeaot-fixtures.mjs"
- "tests/fixtures/nativeaot/**"
- ".github/workflows/nativeaot-fixtures.yml"
workflow_call:
permissions:
contents: read
+1 -30
View File
@@ -7,36 +7,7 @@ on:
description: "Also verify the complete 65,281-section result over MCP (slow)"
type: boolean
default: false
pull_request:
paths:
- ".github/workflows/real-binary-layout.yml"
- "bridge/pwntools/**"
- "src/native/pwntools/**"
- "src/domain/native/binaryLayout*"
- "src/application/binaryDiagnostics/**"
- "src/contracts/native/binaryDiagnosticsToolContracts.ts"
- "src/composition/binaryDiagnostics.ts"
- "src/server/registerBinaryDiagnosticsTools.ts"
- "src/server/createServer.ts"
- "src/cli/binaryDiagnosticsCommands.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/process/OwnedCommand.ts"
- "src/process/ProviderProcess.ts"
- "src/process/ProviderDeadline.ts"
- "src/process/ProcessOwnership*.ts"
- "src/process/PrivateRuntimeRoot.ts"
- "src/artifacts/readStableArtifact*.ts"
- "src/artifacts/ArtifactReader.ts"
- "src/domain/analysisError*.ts"
- "scripts/verify-binary-layout.mjs"
- "scripts/lib/elf-section-name-fixtures.mjs"
- "scripts/lib/large-result-mcp.mjs"
- "scripts/fixtures/binary-layout*"
- "package.json"
- "package-lock.json"
workflow_call:
permissions:
contents: read
+1 -34
View File
@@ -1,40 +1,7 @@
name: Real browser verification
on:
pull_request:
paths:
- ".github/workflows/real-browser.yml"
- "scripts/verify-real-browser.mjs"
- "scripts/verify-browser-network.mjs"
- "scripts/verify-browser-scripts.mjs"
- "scripts/verify-browser-modules.mjs"
- "scripts/verify-browser-dom-destinations.mjs"
- "scripts/lib/browser-*.mjs"
- "scripts/fixtures/browser-network-site.mjs"
- "scripts/fixtures/browser-script-site.mjs"
- "scripts/fixtures/browser-module-site.mjs"
- "scripts/fixtures/browser-verifier-site.mjs"
- "scripts/fixtures/page-cdp-proxy.mjs"
- "src/browser/**"
- "src/domain/browser*.ts"
- "src/domain/webScript*.ts"
- "src/domain/webModule*.ts"
- "src/application/WebModule*.ts"
- "src/composition/webModules.ts"
- "src/artifacts/readStableArtifact.ts"
- "src/artifacts/ArtifactPaths.ts"
- "src/application/WebScriptExportService.ts"
- "src/contracts/webScriptToolContracts.ts"
- "src/server/registerWebScriptTool.ts"
- "src/server/registerWebModuleTool.ts"
- "src/server/createServer.ts"
- "src/cli/webModuleCommands.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/contracts/toolEffects.ts"
- "src/cli/webScriptCommands.ts"
- "package.json"
- "package-lock.json"
workflow_call:
workflow_dispatch:
concurrency:
+1 -27
View File
@@ -2,33 +2,7 @@ name: Real offline EVM interface
on:
workflow_dispatch:
pull_request:
paths:
- ".github/workflows/real-evm-interface.yml"
- "src/evm/**"
- "src/domain/evm/**"
- "src/application/evm/**"
- "src/contracts/evm/**"
- "src/composition/evm.ts"
- "src/cli/evmCommands.ts"
- "src/server/registerEvmTools.ts"
- "src/server/createServer.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/process/OwnedCommand.ts"
- "src/process/ProviderProcess.ts"
- "src/process/ProcessOwnership*.ts"
- "src/process/ProviderDeadline.ts"
- "src/process/PrivateRuntimeRoot.ts"
- "src/artifacts/readStableArtifact*.ts"
- "src/artifacts/ArtifactReader.ts"
- "scripts/verify-evm-interface.mjs"
- "scripts/fixtures/evm-interface.sol"
- "third_party/evmole/**"
- "package.json"
- "package-lock.json"
workflow_call:
permissions:
contents: read
+20
View File
@@ -64,6 +64,14 @@ jobs:
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows -- --x86 | Tee-Object -FilePath windows-ghidra-x86-proof.log
- name: Verify native x64 DLL Windows Ghidra operations
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows -- --dll | Tee-Object -FilePath windows-ghidra-dll-proof.log
- name: Verify native x86 DLL Windows Ghidra operations
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows -- --x86 --dll | Tee-Object -FilePath windows-ghidra-x86-dll-proof.log
- name: Verify ordinary-user CLI and MCP operations
env:
REA_ANALYSIS_PROVIDER: ghidra
@@ -72,6 +80,14 @@ jobs:
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows:package -- --x86 | Tee-Object -FilePath windows-ghidra-x86-package-proof.log
- name: Verify ordinary-user x64 DLL CLI and MCP operations
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows:package -- --dll | Tee-Object -FilePath windows-ghidra-dll-package-proof.log
- name: Verify ordinary-user x86 DLL CLI and MCP operations
env:
REA_ANALYSIS_PROVIDER: ghidra
run: npm run verify:ghidra:windows:package -- --x86 --dll | Tee-Object -FilePath windows-ghidra-x86-dll-package-proof.log
- uses: actions/upload-artifact@v4
if: always()
with:
@@ -81,4 +97,8 @@ jobs:
windows-ghidra-package-proof.log
windows-ghidra-x86-proof.log
windows-ghidra-x86-package-proof.log
windows-ghidra-dll-proof.log
windows-ghidra-x86-dll-proof.log
windows-ghidra-dll-package-proof.log
windows-ghidra-x86-dll-package-proof.log
retention-days: 30
+3 -28
View File
@@ -1,32 +1,7 @@
name: Real JavaScript recovery
on:
pull_request:
paths:
- ".github/workflows/real-javascript-recovery.yml"
- "src/javascript/recovery/**"
- "src/domain/javascript/**"
- "src/application/javascript/JavaScriptRecovery*.ts"
- "src/composition/javascriptRecovery.ts"
- "src/contracts/javascript/javascriptRecoveryToolContracts.ts"
- "src/cli/javascriptRecoveryCommands.ts"
- "src/cli/javascriptApplicationAnalysis.ts"
- "src/server/registerJavaScriptRecoveryTool.ts"
- "src/server/createServer.ts"
- "src/server/sessionAvailabilityPolicy.ts"
- "src/application/CapabilityInventory.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "scripts/rea.mjs"
- "src/process/**"
- "src/artifacts/SafeOutputTree.ts"
- "scripts/verify/javascript/recovery.mjs"
- "scripts/fixtures/javascript-recovery/**"
- "third_party/wakaru"
- "package.json"
- "package-lock.json"
workflow_call:
workflow_dispatch:
permissions:
@@ -56,9 +31,9 @@ jobs:
shell: bash
run: |
mkdir -p "$RUNNER_TEMP/rea-wakaru"
curl --fail --location --retry 3 https://github.com/pionxzh/wakaru/releases/download/v1.13.0/wakaru-linux-x64.tar.gz -o "$RUNNER_TEMP/rea-wakaru/release.tar.gz"
curl --fail --location --retry 3 https://github.com/pionxzh/wakaru/releases/download/v1.14.0/wakaru-linux-x64.tar.gz -o "$RUNNER_TEMP/rea-wakaru/release.tar.gz"
tar -xzf "$RUNNER_TEMP/rea-wakaru/release.tar.gz" -C "$RUNNER_TEMP/rea-wakaru" wakaru
printf '%s %s\n' e8c7ca052974604197389f6ace7464e4dd24dce64e2730971521bd6606ec9c9e "$RUNNER_TEMP/rea-wakaru/wakaru" | sha256sum --check
printf '%s %s\n' 664fa06782a61eda7ed15885134b52525fd565dd77607e642062ceb6cd927c38 "$RUNNER_TEMP/rea-wakaru/wakaru" | sha256sum --check
- name: Install isolated fixture compilers
run: npm install --prefix "$RUNNER_TEMP/rea-fixture-compilers" --ignore-scripts --no-audit --no-fund esbuild@0.25.10 webpack@5.101.3
- run: npm run build:cached
+1 -28
View File
@@ -2,34 +2,7 @@ name: Real recorded crash evidence
on:
workflow_dispatch:
pull_request:
paths:
- ".github/workflows/real-recorded-crash.yml"
- "bridge/pwntools/**"
- "bridge/pwndbg/**"
- "src/native/pwntools/**"
- "src/native/pwndbg/**"
- "src/domain/native/recordedCrash*"
- "src/application/binaryDiagnostics/**"
- "src/contracts/native/binaryDiagnosticsToolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/contracts/toolOutputSchemaGroups.ts"
- "src/composition/binaryDiagnostics.ts"
- "src/server/registerRecordedCrashTools.ts"
- "src/server/createServer.ts"
- "src/server/sessionAvailabilityPolicy.ts"
- "src/cli/binaryDiagnosticsCommands.ts"
- "src/cliCommandNames.ts"
- "src/process/**"
- "src/artifacts/readStableArtifact*.ts"
- "src/domain/analysisError*.ts"
- "scripts/verify-recorded-crash.mjs"
- "scripts/verify/recorded-crash/**"
- "scripts/lib/recorded-core-fixtures.py"
- "scripts/fixtures/recorded-crash.c"
- "third_party/pwndbg/**"
- "package.json"
- "package-lock.json"
workflow_call:
permissions:
contents: read
+57
View File
@@ -0,0 +1,57 @@
name: Real Termux browser verification
on:
workflow_dispatch:
concurrency:
group: real-termux-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
env:
HUSKY: "0"
jobs:
real-termux:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- name: Download the pinned Termux app and verify its release checksum
shell: bash
run: |
mkdir -p "$RUNNER_TEMP/rea-termux"
cd "$RUNNER_TEMP/rea-termux"
release=https://github.com/termux/termux-app/releases/download/v0.118.3
apk=termux-app_v0.118.3+github-debug_x86_64.apk
sums=termux-app_v0.118.3+github-debug_sha256sums
curl --fail --location --retry 3 --output "$apk" "$release/$apk"
curl --fail --location --retry 3 --output "$sums" "$release/$sums"
awk -v apk="$apk" '$2 == apk || $2 == "*" apk' "$sums" > selected.sha256
test "$(wc -l < selected.sha256)" -eq 1
sha256sum --check selected.sha256
- name: Enable emulator acceleration
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Build and capture a page inside Termux
uses: reactivecircus/android-emulator-runner@4c44018e59b437e86cdfc41da381398f93ed8808 # v2
with:
api-level: 30
arch: x86_64
target: google_apis
ram-size: 4096M
heap-size: 512M
disk-size: 8192M
disable-animations: true
script: bash scripts/verify/termux/emulator.sh
- name: Upload Termux and Android diagnostics
if: always()
uses: actions/upload-artifact@v4
with:
name: termux-browser-diagnostics
path: ${{ runner.temp }}/rea-termux/diagnostics
if-no-files-found: warn
@@ -2,38 +2,7 @@ name: Real historical web network captures
on:
workflow_dispatch:
pull_request:
paths:
- ".github/workflows/real-web-network-captures.yml"
- "bridge/mitmproxy/**"
- "src/browser/history/**"
- "src/domain/webNetworkCapture*.ts"
- "src/domain/analysisError*.ts"
- "src/contracts/errorSchemas.ts"
- "src/domain/explicitSensitive*.ts"
- "src/application/WebNetworkCapture*"
- "src/composition/webNetworkCaptures.ts"
- "src/cli/webNetworkCaptureCommands.ts"
- "src/server/registerWebNetworkCaptureTool.ts"
- "src/server/createServer.ts"
- "src/server/toolRegistrationOptions.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/process/OwnedCommand.ts"
- "src/process/ProviderProcess.ts"
- "src/process/ProviderDeadline.ts"
- "src/process/ProcessOwnership*.ts"
- "src/process/PrivateRuntimeRoot.ts"
- "src/process/capture/ProcessCaptureLifecycle.ts"
- "src/artifacts/readStableArtifact*.ts"
- "src/artifacts/ArtifactReader.ts"
- "src/contracts/webNetworkCaptureToolContracts.ts"
- "scripts/verify-web-network-captures.mjs"
- "scripts/fixtures/generate-mitmproxy-capture.py"
- "package.json"
- "package-lock.json"
workflow_call:
permissions:
contents: read
+1 -29
View File
@@ -1,34 +1,6 @@
name: Real website runtime attribution
on:
pull_request:
paths:
- ".github/workflows/real-web-runtime.yml"
- "scripts/verify-browser-runtime.mjs"
- "scripts/lib/browser-runtime-*.mjs"
- "src/process/ProviderProcess.ts"
- "src/process/ProcessOwnership*.ts"
- "scripts/fixtures/browser-runtime-site.mjs"
- "src/browser/execution/**"
- "src/browser/CdpConnection.ts"
- "src/browser/CdpEndpoint.ts"
- "src/browser/CdpTarget*.ts"
- "src/browser/CdpCaptureValues.ts"
- "src/browser/CdpAuthorized*.ts"
- "src/domain/webRuntime.ts"
- "src/domain/webExecution.ts"
- "src/domain/webEventListeners.ts"
- "src/domain/browserObservationError*.ts"
- "src/application/WebRuntime*.ts"
- "src/composition/webRuntime.ts"
- "src/contracts/webRuntimeToolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/server/registerWebRuntimeTools.ts"
- "src/server/createServer.ts"
- "src/cli/webRuntimeCommands.ts"
- "src/cli/commandCancellation.ts"
- "src/cli.ts"
- "package.json"
- "package-lock.json"
workflow_call:
workflow_dispatch:
permissions:
contents: read
+1 -22
View File
@@ -1,27 +1,6 @@
name: Real website source-map verification
on:
pull_request:
paths:
- ".github/workflows/real-web-source-map.yml"
- "scripts/verify-browser-source-maps.mjs"
- "scripts/lib/browser-source-map-e2e.mjs"
- "scripts/fixtures/browser-source-map-site.mjs"
- "src/javascript/sourceMaps/**"
- "src/browser/assets/**"
- "src/domain/webSource*.ts"
- "src/domain/webScript*.ts"
- "src/application/WebSourceLocation*.ts"
- "src/application/ValidateSelectedWebScript.ts"
- "src/composition/webSourceLocations.ts"
- "src/server/registerWebSourceLocationTool.ts"
- "src/server/createServer.ts"
- "src/contracts/webScriptToolContracts.ts"
- "src/process/**"
- "src/cli/webSourceLocationCommands.ts"
- "src/cli.ts"
- "src/artifacts/readStableArtifact.ts"
- "package.json"
- "package-lock.json"
workflow_call:
workflow_dispatch:
permissions:
contents: read
+34
View File
@@ -35,7 +35,21 @@ jobs:
contents: write
pull-requests: write
steps:
- name: Respect finalized release notes
id: editorial
env:
GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
finalized=$(gh api --paginate "repos/${GH_REPO}/pulls?state=open&base=main&per_page=100" \
--jq '.[] | select(.head.repo.full_name == .base.repo.full_name) | select(.head.ref | startswith("release-please--branches--main--")) | select(any(.labels[]; .name == "rea:release-notes-finalized")) | .number')
if [[ -n "${finalized}" ]]; then
echo "Finalized release notes on PR ${finalized}; automatic proposal refresh is paused." >> "$GITHUB_STEP_SUMMARY"
echo "frozen=true" >> "$GITHUB_OUTPUT"
fi
- uses: googleapis/release-please-action@v4
if: steps.editorial.outputs.frozen != 'true'
with:
token: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
target-branch: main
@@ -80,6 +94,16 @@ jobs:
node scripts/verify-release-checkpoint.mjs \
--phase publish --release-branch main --source-sha "$SOURCE_SHA"
- name: Validate finalized notes before release creation
env:
GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
RELEASE_PR: ${{ github.event.pull_request.number }}
SOURCE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
run: |
node scripts/release-notes.mjs publication --repository "$GH_REPO" \
--source "$SOURCE_SHA" --pr "$RELEASE_PR"
- uses: googleapis/release-please-action@v4
id: release
with:
@@ -192,6 +216,16 @@ jobs:
--phase "$RELEASE_PHASE" --release-branch "$RELEASE_BRANCH"
--source-sha "$SOURCE_SHA"
- name: Validate manual finalized notes before release creation
if: inputs.phase == 'publish'
env:
GH_TOKEN: ${{ secrets.RELEASE_PLEASE_TOKEN || secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
SOURCE_SHA: ${{ steps.branch.outputs.sha }}
run: |
node scripts/release-notes.mjs publication --repository "$GH_REPO" \
--source "$SOURCE_SHA"
- uses: googleapis/release-please-action@v4
id: release
with:
+15 -12
View File
@@ -1,13 +1,7 @@
name: Website checks
on:
pull_request:
branches: [main, "release/*"]
paths:
- "website/**"
- "scripts/verify-website.py"
- "scripts/prepare-website.py"
- ".github/workflows/**"
workflow_call:
workflow_dispatch:
permissions:
@@ -21,11 +15,20 @@ jobs:
check:
name: Website checks
runs-on: ubuntu-latest
timeout-minutes: 5
timeout-minutes: 10
steps:
- name: Check out the repository
uses: actions/checkout@v4
- name: Prepare the example download
run: python3 scripts/prepare-website.py
- name: Check website links and publishing configuration
run: python3 scripts/verify-website.py
- name: Set up Python for website assets
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: website/requirements.txt
- name: Install sharing-image dependencies
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y libcairo2 fonts-dejavu-core
python3 -m pip install -r website/requirements.txt
- name: Check shared HTML, links, assets and contributor workflows
run: python3 scripts/website.py check
+136 -6
View File
@@ -2,6 +2,15 @@ name: Publish REA website
on:
workflow_dispatch:
inputs:
target:
description: Publish both hosts, or Pages while configuring Cloudflare
type: choice
required: true
default: both
options:
- both
- pages
permissions:
contents: read
@@ -14,17 +23,56 @@ jobs:
prepare:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
timeout-minutes: 5
timeout-minutes: 10
permissions:
contents: read
pages: read
steps:
- name: Validate the publication target
env:
PUBLISH_TARGET: ${{ inputs.target }}
run: |
case "$PUBLISH_TARGET" in
both|pages) ;;
*) echo "::error::Unknown publication target: $PUBLISH_TARGET"; exit 1 ;;
esac
- name: Require Cloudflare publishing credentials
if: inputs.target == 'both'
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
run: |
if [[ -z "$CLOUDFLARE_API_TOKEN" || -z "$CLOUDFLARE_ACCOUNT_ID" ]]; then
echo "::error::Set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in repository Actions secrets before publishing."
exit 1
fi
- name: Check out the repository
uses: actions/checkout@v4
- name: Prepare the example download
run: python3 scripts/prepare-website.py
- name: Check website links and publishing configuration
run: python3 scripts/verify-website.py
- name: Set up Python for website assets
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: website/requirements.txt
- name: Install sharing-image dependencies
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y libcairo2 fonts-dejavu-core
python3 -m pip install -r website/requirements.txt
- name: Check shared HTML, links, assets and contributor workflows
run: python3 scripts/website.py check
- name: Record the published commit
run: |
python3 - <<'PY'
import json
import os
from pathlib import Path
Path("website/public/deployment.json").write_text(
json.dumps({"commit": os.environ["GITHUB_SHA"]}) + "\n",
encoding="utf-8",
)
PY
- name: Configure Pages
uses: actions/configure-pages@v5
- name: Upload the website
@@ -35,14 +83,96 @@ jobs:
deploy:
needs: prepare
runs-on: ubuntu-latest
timeout-minutes: 5
timeout-minutes: 15
permissions:
contents: read
actions: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Check out publishing configuration
if: inputs.target == 'both'
uses: actions/checkout@v4
- name: Set up Node.js for Wrangler
if: inputs.target == 'both'
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
- name: Download the verified website
if: inputs.target == 'both'
uses: actions/download-artifact@v4
with:
name: github-pages
path: ${{ runner.temp }}/website-archive
- name: Extract the shared publishing artifact
if: inputs.target == 'both'
run: |
mkdir -p "$RUNNER_TEMP/rea-website-public"
tar -xf "$RUNNER_TEMP/website-archive/artifact.tar" -C "$RUNNER_TEMP/rea-website-public"
- name: Publish the website to Cloudflare
if: inputs.target == 'both'
uses: cloudflare/wrangler-action@v4
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
wranglerVersion: "4.149.0"
packageManager: npm
command: deploy --cwd website --env production --assets "${{ runner.temp }}/rea-website-public"
- name: Publish to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
- name: Verify the selected published revisions
env:
PAGES_URL: ${{ steps.deployment.outputs.page_url }}
PUBLISH_TARGET: ${{ inputs.target }}
run: |
python3 -u - <<'PY'
import json
import os
import sys
import time
from urllib.error import URLError
from urllib.parse import urljoin
from urllib.request import Request, urlopen
expected = os.environ["GITHUB_SHA"]
pages_url = os.environ["PAGES_URL"]
if not pages_url:
sys.exit("GitHub Pages returned no published URL.")
target = os.environ["PUBLISH_TARGET"]
if target not in ("both", "pages"):
sys.exit("Unknown publication target: " + target)
hosts = {"GitHub Pages": pages_url}
if target == "both":
hosts["Cloudflare"] = "https://rea.tools/"
pending = dict(hosts)
for attempt in range(24):
for name, base in list(pending.items()):
url = urljoin(base, "deployment.json") + "?commit=" + expected
try:
request = Request(url, headers={
"Cache-Control": "no-cache",
"User-Agent": "REA-Website-Verifier/1.0 (+https://github.com/morluto/rea)",
})
with urlopen(request, timeout=10) as response:
actual = json.load(response).get("commit")
if actual == expected:
print(f"{name} serves {expected}: {base}")
del pending[name]
else:
print(f"Waiting for {name}: observed revision {actual}")
except (URLError, TimeoutError, ValueError) as error:
print(f"Waiting for {name}: {error}")
if not pending:
break
if attempt < 23:
time.sleep(5)
if pending:
sys.exit("Could not verify published revision on: " + ", ".join(pending))
with open(os.environ["GITHUB_STEP_SUMMARY"], "a", encoding="utf-8") as summary:
links = " and ".join(f"[{name}]({url})" for name, url in hosts.items())
summary.write(f"Published commit `{expected}` to {links}.\n")
PY
+5 -4
View File
@@ -49,6 +49,10 @@ Thumbs.db
# Generated website download
/website/public/examples/notes-example.zip
/website/public/deployment.json
/website/public/sitemap.xml
/website/public/assets/social-card.png
/website/.venv/
# Local Cloudflare development state
/website/.wrangler/
@@ -57,11 +61,8 @@ Thumbs.db
!/website/.dev.vars.example
!/website/.env*.example
# Build-generated MCP tool catalog (regenerated by `npm run build`; never commit)
src/generatedMcpToolCatalog.ts
# Derived catalogs, portable conformance projections, and packaged skill bundles
# (regenerated from this checkout by `npm run build:cached`; never commit)
# (regenerated by `npm run docs:generate`; never commit)
/skills/
/docs/public/product-catalog.json
/docs/verification/managed-conformance-manifest.json
+2 -2
View File
@@ -1,6 +1,6 @@
{
"_comment": "Test files are intentionally NOT excluded: the gate used to report zero clones because it skipped **/*.test.ts, hiding all test-tree duplication. Current actual is ~2.4% lines across src+ and tests/, down from 3.4% when tests were included. Lower this as duplication is removed.",
"threshold": 2.5,
"_comment": "Test files are intentionally NOT excluded: the gate used to report zero clones because it skipped **/*.test.ts, hiding all test-tree duplication. Current actual is ~2.47% lines across src+ and tests/, down from 3.4% when tests were included. The 2.6% limit leaves modest headroom for ordinary changes; lower it as duplication is removed.",
"threshold": 2.6,
"reporters": ["consoleFull"],
"ignore": [
"node_modules/**",
+1 -1
View File
@@ -1,3 +1,3 @@
{
".": "6.1.0"
".": "6.4.0"
}
+25 -88
View File
@@ -1,112 +1,49 @@
# Repository Guidelines
## Product Direction
## Product and Authority
REA exposes reverse-engineering tools through a CLI and MCP server. Hopper, the bring-your-own Ghidra adapter, and the bring-your-own IDA MCP adapter are operation-capable deep binary-analysis providers. Ghidra is supported on Linux x64/arm64 and macOS x64/arm64 with matching native decompiler tools, and has an experimental Windows x64 P0 boundary for approved native x86 and x86-64 PE applications; on Linux and macOS it supplies inventory, function analysis, and atomic function annotation edits in an ephemeral database, without modifying executable bytes or controlling a GUI. Windows P0 has no mutation authority. IDA adapts upstream legacy attached GUI and modern headless database-supervisor profiles for live read-only analysis; initial real verification covers Windows, and an attached GUI database is never saved or closed. Keep provider-specific code out of the domain and application layers.
REA is a local-only reverse-engineering tool with shared CLI/MCP workflows. Distinguish observations, derivations, inferences, and unknowns; preserve Evidence provenance and session semantics through both adapters. Provider support and setup live in [README.md](README.md#choosing-a-deep-analysis-provider) and its linked guides.
Prioritize:
Ghidra uses ephemeral databases without modifying executable bytes or controlling a GUI; Windows Ghidra P0 has no mutation authority. IDA analysis is read-only; never save or close an attached GUI database.
- tool results that distinguish observations, inferences, and unknowns;
- equivalent behavior through the CLI and MCP;
- additive, idempotent configuration with backups;
- end-to-end tests for packaged artifacts and real Hopper/Ghidra claims.
Configuration changes must be additive and idempotent, with backups. Installers must not install or upgrade unrelated software, including Homebrew, Node.js, npm, Java, or Ghidra. Ghidra and IDA are bring-your-own. `rea setup` must show its planned changes and require approval before writing files or installing Hopper.
Installers must not install or upgrade Homebrew, Node.js, npm, Java, Ghidra, or other unrelated software. Ghidra is bring-your-own. `rea setup` must print its planned changes and require approval before writing files or installing Hopper.
Preserve caller-selected inputs and local evidence, including output, URLs, paths, digests, and metadata. Redact transport authentication credentials and explicitly marked sensitive values; do not infer secrecy from names or text patterns. Do not persist the ambient environment merely because a child inherits it.
REA is a local-only tool. Preserve caller-selected inputs, captured output, URLs, paths, digests, mismatch locations, and analysis metadata. Do not guess that local evidence is secret from environment-variable names, argument names, or text patterns. Redact transport authentication credentials and values the caller explicitly marks sensitive; do not persist the entire ambient environment merely because a child inherits it.
## Architecture and Cleanup
## Project Structure & Module Organization
Dependencies flow inward: domain semantics and contracts, provider adapters, shared application workflows, then CLI/MCP adapters. Keep engine protocols and provider-specific code out of domain/application layers. See [docs/architecture.mermaid](docs/architecture.mermaid) when changing composition.
REA is a layered ESM TypeScript application. Dependencies flow inward from pure domain logic through contracts, providers, application workflows, and CLI/MCP adapters. See [docs/architecture.mermaid](docs/architecture.mermaid) for the component map.
Give each interpretation and resource a clear owner. Preserve identity, omission, uncertainty, and source evidence across boundaries. Retain ownership of resources whose cleanup failed. Reuse `src/process/` supervision and identity primitives; a PID and executable path alone do not establish ownership after exit or reuse.
- `src/domain/` owns pure provider-neutral semantics; `src/contracts/` owns caller-visible schemas and the canonical tool inventory.
- `src/hopper/`, `src/ghidra/`, `src/ida/`, `src/browser/`, `src/inspector/`, `src/native/`, `src/artifacts/`, and `src/dotnet/` own provider-specific boundaries. Keep provider protocols out of domain and application code.
- `src/application/` composes shared CLI/MCP workflows, including Evidence provenance, unknowns, and eligible snapshot bindings; `src/server/` translates MCP requests; `src/cli.ts` and `src/main.ts` are the CLI and MCP entry points.
- `src/process/` owns shared process lifecycle primitives, not provider wire protocols. Reuse its supervision and identity primitives before adding provider-local lifecycle code; a PID and executable pathname alone do not establish ownership after exit or reuse. `bridge/` contains provider-side adapters.
- `tests/` contains unit, composition, boundary, acceptance, and conformance tests. `scripts/verify-*` and capability directories under `scripts/verify/` contain real-toolchain checks.
- `docs/public/product-catalog.json`, `docs/verification/managed-conformance-*.json`, and `skills/` are ignored build outputs. Update source contracts and authored instructions in `skill-src/`, then run `npm run build:cached`; never commit derived catalog digests or portable conformance projections.
- `src/generatedMcpToolCatalog.ts` is build-generated and gitignored. Never commit it; resolve any trace of it in merges by deleting it and running `npm run build:cached`.
Assess brittleness in touched code during implementation, debugging, review, and maintenance. Fix the producing representation or ownership rule before adding downstream repairs. Normalize once at the owning boundary using format-aware parsers. Remove superseded representations, aliases, wrappers, and redundant tests after verifying affected consumers. Introduce abstractions only when they remove observed complexity.
## Build, Test, and Development Commands
Parse unknown boundary values and model expected failures with the tagged error algebra and `Result`. Preserve partial facts and meaningful failure reasons. Keep identity and lookup values separate from display formatting; preserve source values and explicit unknowns when normalization loses information. Absolute paths, file URLs, and HTTP paths have different semantics.
- `npm ci`: install the locked dependencies.
- `npm run build:cached`: build the CLI and MCP server.
- `npm run test:local`: run changed source tests without building; pass exact source test paths to run them regardless of Git status.
- `npm run test:focused -- PATH...`: run exact test files; build first for boundary, acceptance, or process-global tests.
- `npm run check:changed`: run cached static checks and source tests affected since the branch merge base (default `origin/main`).
- `npm run check:fast`: run cached typecheck and lint checks.
- `npm run check:pr`: opt into the complete local deterministic gate and generated-document checks for broad changes; CI owns full coverage. Routine iterations need focused tests and relevant checks, not the whole gate each time.
- `npm run docs:check`: build and validate generated documents for the current checkout; `npm run docs:generate` regenerates them. CI retains ignored outputs as artifacts and does not push snapshot commits to feature branches.
- For provider-dependent changes, see [docs/testing.md](docs/testing.md) and run the matching real-provider verification.
- Keep each verification lane's prerequisites limited to the claim it checks. Use host-native fixtures for host/provider acceptance; put optional cross-target formats and their external toolchains in a separate lane. Preflight required commands and report the missing dependency and lane clearly.
Validate advertised JSON Schemas after SDK conversion against their declared dialect and actual clients. Bind handlers to named contracts with exact types; catalog ordering must never select an operation or schema.
See [docs/testing.md](docs/testing.md) for test scopes and verification lanes and [CONTRIBUTING.md](CONTRIBUTING.md) for contribution checks. Pre-commit formats and lints staged source; pre-push runs `npm run check:fast`.
## Development
## Configuration & Environment Variables
Use [.nvmrc](.nvmrc) and `package.json#packageManager` for the pinned toolchain. Cursor Cloud may place older Node.js first on `PATH`; environment setup installs the pinned toolchain under `/usr/local/bin`.
Configuration is parsed and validated by `src/config.ts` and `src/config/`. Keep user-facing setup and provider configuration in [README.md](README.md) and the relevant guide under `docs/`; do not maintain a second environment-variable catalogue here.
- `npm ci`: install locked dependencies.
- `npm run build:cached`: build the runtime and packaged skill.
- `npm run test:local -- PATH...`: source tests without building.
- `npm run test:focused -- PATH...`: exact tests with their required artifacts.
- `npm run check:fast`: cached typecheck/lint and the pre-push check.
- `npm run docs:check`: validate generated documentation.
## Coding Style & Naming Conventions
Use relevant checks for the change. The complete local gate, `npm run check:pr`, is optional for broad changes or CI diagnosis. See [CONTRIBUTING.md](CONTRIBUTING.md) for development, generated-file ownership, and release conventions.
Use ESM TypeScript, two-space indentation, and the committed Oxfmt configuration. Keep compiler strictness intact (`strict`, `exactOptionalPropertyTypes`, `noUncheckedIndexedAccess`, `verbatimModuleSyntax`). Use `camelCase` for values/functions, `PascalCase` for classes/types, and `UPPER_SNAKE_CASE` for constants. Parse unknown values at every MCP, environment, and subprocess boundary. Avoid `any`, unchecked casts, non-null assertions, import-time I/O, and floating promises. Exported APIs require concise JSDoc. Model expected failures with the tagged error algebra and `Result`, not broad exception wrappers.
`docs/public/product-catalog.json`, `docs/verification/managed-conformance-*.json`, and `skills/` are ignored outputs. Edit source contracts and `.agents/skills/reverse-engineer-anything/`, then regenerate as needed. `.cache/mcp-tool-catalog.json` is test metadata; runtime builds and source checking do not consume it. Never commit binaries, provider project documents, credentials, `dist/`, `node_modules/`, or local planning artifacts.
## Boundary Contracts
## Tool and Test Changes
Treat a boundary as a contract between the producer's actual representation and the consumer's required meaning. When implementing or auditing a boundary, trace the value through parsing, normalization, authorization, serialization, and the CLI/MCP result. Establish affected callers from their code paths; similar tool names or workflows do not prove that they share a schema or failure mode.
For tool design, follow [docs/tool-design.md](docs/tool-design.md): start from the analyst question, reuse existing contracts, preserve caller choices, and return useful evidence inline. Limits must follow real format, protocol, authority, or resource constraints. Account for representation expansion before allocation; derive completeness from examined coverage.
When changing boundary behavior, inspect adjacent input representations, failure paths, and affected callers, and correct the underlying assumption across those cases.
For test changes or provider claims, use [docs/testing.md](docs/testing.md). Prefer real public CLI/MCP workflows, then production-boundary integration, then producer goldens. Keep module tests for distinct semantics stronger workflows cannot reliably reproduce. Preserve malformed-input, cancellation, cleanup, permission, capacity, and target-identity coverage when pruning. Report unverified coverage explicitly; simulated providers do not establish real-provider behavior.
Keep portable evidence and scenario validation distinct from host-native execution checks. Absolute filesystem paths, file URLs, and HTTP paths have different semantics; do not substitute one platform's syntax for the domain concept. Interpret provider metadata according to its documented or observed producer behavior. Keep values used for identity, provenance, matching, and path resolution separate from display formatting. When normalization loses information, preserve the source value and an explicit unknown; display placeholders must not feed back into lookup or selection.
Preserve meaningful failure reasons through application and adapter layers. Malformed input is distinct from an unsupported target, unavailable provider, or host operating-system permission denial. Diagnostics should identify the failed constraint and the target or lifecycle request it applies to. Recovery advice must address that reason and point to an available workflow; generic catches must not erase actionable validation details. Preserve collected observations on execution failure independently of whether cleanup succeeds.
Preserve partial native facts. A shared schema must not require one provider's full metadata before another provider can report the facts it observes. Keep observed classifications and endpoints alongside explicit unknowns for unsupported flags; never invent missing flags or discard known facts to satisfy an all-or-nothing availability shape. Before claiming a native API lacks a capability, inspect the installed API and probe representative producer objects. Exercise the resulting partial representation through CLI, MCP, and composed results such as function dossiers.
Leave meaningful target, action, capture, and output choices to the agent. A selected operation already expresses intent; do not require approval booleans or repeated permission declarations. Trace each setting to its consumer: remove ignored options and single-value confirmations, derive built-in lifecycle behavior, and supply defaults for omitted optional metadata. Report actual effects and limitations where they help interpret results rather than asking callers to restate them.
Verify the representation consumed at the next boundary. Internal validator success does not establish JSON Schema validity or client compatibility: validate advertised input and output schemas against their declared dialect after SDK conversion, and keep generated contracts aligned. Use representative producer data and regressions that exercise the failed behavior. Platform and provider support claims require the corresponding real workflow; package startup, capability probes, and mock transport tests establish only their narrower claims. Report unverified coverage explicitly.
Bind tool handlers to named contracts, preserving their exact input and output types. Catalog ordering is presentation metadata; changing that order must not select a different schema or operation for an existing handler.
## Designing MCP Tools
Start from the analyst question and desired result, not a provider API. Before adding a tool, inspect the existing contract and its nearest alternative.
Let agents compose experiments with ordinary commands, scripts, and local fixture servers. REA tools should perform the requested inspection or capture and return evidence. A custom orchestration language, replay engine, or separate prepare/execute plan needs an observed requirement that those primitives cannot satisfy. A plan-only tool without an executor does not establish runtime behavior; expose the useful inspection directly.
- Prefer reusable, composable primitives: inspect one explicit object or
relationship and return evidence that can support different analyst
questions. Compose primitives into a workflow only for a recurring outcome
that benefits from joining evidence sources; keep one-application or
business-domain interpretations out of general tool contracts.
- Use **inspect/search** tools for facts about a target or candidate set; use **trace** tools for relationships; use **compare** tools for explicitly paired inputs.
- Add a **workflow** when observed agent use shows a repeated sequence that REA can compose without losing analyst control. Return useful results inline so callers can choose their next action.
- Use **observe/capture** only when runtime activity is required, and declare authority and lifecycle effects in the contract.
- Extend an existing tool when intent and result contract are unchanged. Add a tool for a distinct analyst outcome or materially different authority.
- Keep caller-facing names and results provider-neutral. Put engine-specific behavior in provider adapters and report each provider's exact coverage.
- Keep results complete by default. Add a limit only when it follows from a real format, protocol, authority, or resource-safety constraint; explain truncation and unsupported facets. Account for representation expansion and products of independently bounded dimensions before allocating or retaining output. Derive facet completeness from what was examined and exhausted, not an empty failure list. Keep observed, derived, inferred, and unknown results distinct.
- Include artifact identity, source locations, Evidence references, actionable errors, and relevant limitations when they affect conclusions. Return the evidence needed for the next analysis inline rather than requiring a resource or identifier lookup.
- Implement shared application workflows behind CLI and MCP adapters. Update canonical contracts and generated catalog together.
See [docs/tool-design.md](docs/tool-design.md) for the design checklist. When usability or tool selection changes, evaluate representative CLI/MCP tasks as well as schema and transport behavior.
## Testing Guidelines
Prioritize real end-to-end workflows, boundary integration, and golden producer data. Keep a focused module test when it covers a distinct failure or semantic case absent from those workflows; test paths do not establish depth. See [docs/testing.md](docs/testing.md) for pruning and classification rules.
Name tests `*.test.ts`. Use Vitest and production seams (`tests/fixtures/`) rather than module mocks. Domain tests assert pure behavior; adapter tests use fake launcher/socket seams; MCP tests connect with the client SDK version pinned in `package.json`. Preserve the canonical tool inventory defined by `TOOL_CONTRACTS` and verified through `CATALOG_IDENTITY` and generated product metadata. Cover malformed input, cancellation, lifecycle cleanup, and actual format, protocol, host-permission, and target-identity boundaries. Do not add tests that merely freeze arbitrary caps or prescribed call sequences. Real Hopper, Ghidra, browser, managed conformance, and any real managed-tool claims cannot be replaced by mocks; use the corresponding `verify:*` command.
Keep tool catalogs complete and self-describing; prefer capability- and session-scoped availability over schema truncation. Serialized bytes alone do not measure agent usability or model context cost.
## Cursor Cloud specific instructions
Development requires Node.js 24.18.0 and npm 11.16.0 (`.nvmrc` and `packageManager`). The Cloud Agent image places an older `node` on `PATH` ahead of a normal install. Environment setup installs the pinned toolchain under `/usr/local` and prepends `/usr/local/bin` for login shells. Confirm `node -v` is `v24.18.0` before installing dependencies.
`npm ci` installs locked dependencies. `npm run build:cached` produces the CLI and MCP server. `npm run check:fast` is the pre-push typecheck and lint. Hopper, Ghidra, and IDA are optional bring-your-own providers. JavaScript analysis and the deterministic Vitest suites do not need them. `rea doctor` reports those engines as missing until they are configured.
## Commit & Pull Request Guidelines
Use Conventional Commit subjects because Release Please derives changelogs from them. Release Please uses `always-bump-minor`: every release increments minor, including breaking changes. Examples: `feat: add historical source import`, `fix(process): stop timers after exit`, and `docs: update architecture`. Use `!` or a `BREAKING CHANGE:` footer for breaking changes. Pull request titles must follow the same format because squash merges use the title as the release commit. Pull requests should describe contract or behavior changes, list verification commands, link issues, and include sanitized MCP examples when schemas change. State whether real Hopper/Ghidra verification was performed. Never commit binaries, Hopper or Ghidra project documents, credentials, `dist/`, `node_modules/`, or local planning artifacts (e.g. `.codex/`).
Use Conventional Commit subjects and PR titles. Mark breaking changes with `!` or a `BREAKING CHANGE:` footer. Describe behavior changes, relevant validation, and real-provider verification scope.
<!-- BEGIN:turborepo-agent-rules -->
+476
View File
@@ -1,5 +1,480 @@
# Changelog
## [6.4.0](https://github.com/morluto/rea/compare/rea-agents-6.3.0...rea-agents-6.4.0) (2026-10-11)
### Highlights
- Android: added device inspection, split-APK acquisition, logs, screenshots, file transfers and explicit app lifecycle actions through ADB, plus manifest and localized-string decoding with Apktool. ([#1552](https://github.com/morluto/rea/pull/1552), [#1556](https://github.com/morluto/rea/pull/1556)) Thanks @3QL.
- JEB: browse project units and decompile selected items through a caller-started local JEB MCP server. ([#1536](https://github.com/morluto/rea/pull/1536)) Thanks @3QL.
- Large analyses: discover retained Evidence without loading every payload, and inspect JavaScript graphs, binary layouts and function dossiers through summaries and selected views. ([#1682](https://github.com/morluto/rea/pull/1682), [#1568](https://github.com/morluto/rea/pull/1568), [#1570](https://github.com/morluto/rea/pull/1570), [#1345](https://github.com/morluto/rea/pull/1345), [#1507](https://github.com/morluto/rea/pull/1507), [#1247](https://github.com/morluto/rea/issues/1247)) Thanks @jhuang-tw, @kaoru0822-kitauji, @N0zoM1z0.
- JavaScript: isolate source analysis in an owned process with configurable heap and timeout limits; retain completed facts and explicit unknowns when analysis runs out of resources. ([#1651](https://github.com/morluto/rea/pull/1651), [#1563](https://github.com/morluto/rea/issues/1563), [#1565](https://github.com/morluto/rea/issues/1565)) Thanks @N0zoM1z0, @peter-research.
- Ghidra: configure import language/compiler specifications and seed functions, code and labels before auto-analysis. ([#1667](https://github.com/morluto/rea/pull/1667)) Thanks @sqmagellan.
- RPC discovery: recognize supported tRPC calls, HTTP-link URLs and named GraphQL operations in JavaScript applications and web bundles. ([#1670](https://github.com/morluto/rea/pull/1670)) Thanks @pompiliodonatoapp.
### Changes
- Added Ghidra support for Windows PE DLLs and bounded MIPS ELF analysis, including carved MIPS inputs with incomplete section tables. Windows P0 remains read-only. ([#1303](https://github.com/morluto/rea/pull/1303), [#1362](https://github.com/morluto/rea/pull/1362), [#1629](https://github.com/morluto/rea/pull/1629), [#1290](https://github.com/morluto/rea/issues/1290), [#718](https://github.com/morluto/rea/issues/718), [#1619](https://github.com/morluto/rea/issues/1619)) Thanks @bqw371, @jaelliot, @kvalls, @N0zoM1z0.
- Enabled `set_address_name` and `set_addresses_names` for Ghidra sessions with mutation authority, including namespace-aware data labels and per-address batch results. ([#1635](https://github.com/morluto/rea/pull/1635), [#1634](https://github.com/morluto/rea/issues/1634)) Thanks @giri256.
- Recovered additional signed AArch64 relative jump-table patterns. ([#1592](https://github.com/morluto/rea/pull/1592)) Thanks @RishTheFish21.
- Added PE resource inspection and read-only NativeAOT metadata parsing for supported x64 PE32+/.NET 8 RTR 9.1 inputs. The NativeAOT parser’s Windows-host Ghidra workflow remains unverified on a real Windows host. ([#1482](https://github.com/morluto/rea/pull/1482), [76d8f68](https://github.com/morluto/rea/commit/76d8f68cb918dfb43869f2b649a0b6c0c1cf266d), [#1254](https://github.com/morluto/rea/issues/1254)) Thanks @N0zoM1z0, @thangldw.
- Added Pi, Hermes and Qwen Code setup, including Hermes active-profile support. ([#1376](https://github.com/morluto/rea/pull/1376), [#1403](https://github.com/morluto/rea/pull/1403), [#1415](https://github.com/morluto/rea/pull/1415), [#1409](https://github.com/morluto/rea/issues/1409)) Thanks @rasatpetabit, @yiliang114, @zaydiscold.
- Added `REA_MCP_INPUT_SCHEMA_PROFILE=compact` for size-capped MCP clients such as Kimi/Moonshot, while retaining canonical runtime validation. ([#1514](https://github.com/morluto/rea/pull/1514), [#1580](https://github.com/morluto/rea/pull/1580), [#1484](https://github.com/morluto/rea/issues/1484), [#1581](https://github.com/morluto/rea/issues/1581)) Thanks @haythemsellami, @N0zoM1z0.
- Added live process-capture progress and optional `finalization_ms` to capture shutdown output before timeout escalation; cancellation remains immediate. ([#1483](https://github.com/morluto/rea/pull/1483), [#1583](https://github.com/morluto/rea/pull/1583), [#1252](https://github.com/morluto/rea/issues/1252), [#1253](https://github.com/morluto/rea/issues/1253), [modelcontextprotocol/typescript-sdk#2997](https://github.com/modelcontextprotocol/typescript-sdk/issues/2997)) Thanks @N0zoM1z0, @nikolay-dementiev, @sathariels.
- Improved Codex onboarding and recovery from observed client, PATH and provider blockers. ([#1613](https://github.com/morluto/rea/pull/1613)) Thanks @N0zoM1z0.
- Reduced redirected JSON and terminal output size, and deferred heavy imports until their commands need them. ([#1413](https://github.com/morluto/rea/pull/1413), [#1450](https://github.com/morluto/rea/pull/1450), [#1439](https://github.com/morluto/rea/pull/1439), [21dbcf7](https://github.com/morluto/rea/commit/21dbcf7a1458219989ad291e44ce7d017378b727)) Thanks @kaoru0822-kitauji.
### Fixes
- Electron analysis: follow renamed and default-imported APIs and optional calls, ignore overwritten identities and media preload attributes, and resolve packaged `app.asar` pages and unpacked companions. ([#1391](https://github.com/morluto/rea/pull/1391), [#1393](https://github.com/morluto/rea/pull/1393), [#1400](https://github.com/morluto/rea/pull/1400), [#1664](https://github.com/morluto/rea/pull/1664), [#1673](https://github.com/morluto/rea/pull/1673)) Thanks @kaoru0822-kitauji, @marnixpluim, @N0zoM1z0, @suninrain086.
- JavaScript data flow: preserve returned/yielded reference uncertainty, invalidate property-stored aliases correctly, and retain bundled-module runtime scope. ([#1437](https://github.com/morluto/rea/pull/1437), [#1445](https://github.com/morluto/rea/pull/1445), [#1471](https://github.com/morluto/rea/pull/1471), [#1577](https://github.com/morluto/rea/pull/1577), [#1428](https://github.com/morluto/rea/issues/1428), [#1442](https://github.com/morluto/rea/issues/1442), [#1449](https://github.com/morluto/rea/issues/1449), [#1576](https://github.com/morluto/rea/issues/1576)) Thanks @CassieFox23, @dakjdakd, @N0zoM1z0.
- JavaScript packages: resolve exact exports subpaths, preserve trailing-slash directory requests and exact CommonJS keys, and respect shadowed `require` bindings. ([#1424](https://github.com/morluto/rea/pull/1424), [#1615](https://github.com/morluto/rea/pull/1615), [5485483](https://github.com/morluto/rea/commit/5485483f7da2f6cb66441bb784aaf2a1a5f8731a), [8b2f851](https://github.com/morluto/rea/commit/8b2f8514c50e469c3add8ce9ba7ebebef888b14f), [f998fcb](https://github.com/morluto/rea/commit/f998fcb1cca9994c3589fb70d6e0127fc215f76f), [1e51c73](https://github.com/morluto/rea/commit/1e51c732bbf08191688d6526bf58ab2650b601e3), [#1365](https://github.com/morluto/rea/issues/1365)) Thanks @akshitkhokhani, @AWUQAQ, @immanuwell, @rudycelekli.
- Large JavaScript inputs: handle oversized inline source maps, deep returns and reassignment loops; avoid argument expansion limits and yield during large analysis passes. ([#1386](https://github.com/morluto/rea/pull/1386), [#1368](https://github.com/morluto/rea/pull/1368), [#1390](https://github.com/morluto/rea/pull/1390), [#1539](https://github.com/morluto/rea/pull/1539), [#1525](https://github.com/morluto/rea/pull/1525), [#1542](https://github.com/morluto/rea/pull/1542), [#1545](https://github.com/morluto/rea/pull/1545), [#1557](https://github.com/morluto/rea/pull/1557), [#1380](https://github.com/morluto/rea/issues/1380), [#1401](https://github.com/morluto/rea/issues/1401), [#1538](https://github.com/morluto/rea/issues/1538), [#1462](https://github.com/morluto/rea/issues/1462)) Thanks @cold-atom, @KadirJeager, @kaoru0822-kitauji, @marnixpluim, @N0zoM1z0, @rudycelekli.
- JavaScript receivers: expand escaped methods once, index returned-object targets, and avoid replaying earlier writes or duplicating retained graph allocations. ([#1517](https://github.com/morluto/rea/pull/1517), [#1537](https://github.com/morluto/rea/pull/1537), [#1444](https://github.com/morluto/rea/pull/1444), [#1601](https://github.com/morluto/rea/pull/1601), [#1495](https://github.com/morluto/rea/issues/1495)) Thanks @CassieFox23, @geekwolf, @kaoru0822-kitauji, @N0zoM1z0, @zeynelacikgoez.
- Browser captures: retain WebSocket URLs, empty connections and frame order; compare only common known payload coverage and preserve incomplete WebMCP replay coverage. ([db4e360](https://github.com/morluto/rea/commit/db4e3608465486466591b594cf77037ac150c988), [aa257ea](https://github.com/morluto/rea/commit/aa257ea4b16f2d2a35c12df63359d650b48b1154), [e52c0a7](https://github.com/morluto/rea/commit/e52c0a72c59c740315e89149881a27ce4d89a11c))
- Browser scenarios: seed storage in the correct partition, normalize loopback attach identities, retain declared-secret redaction and require verified lineage before Windows Electron signals. ([#1604](https://github.com/morluto/rea/pull/1604), [#1590](https://github.com/morluto/rea/pull/1590), [#1588](https://github.com/morluto/rea/pull/1588), [8b4c3de](https://github.com/morluto/rea/commit/8b4c3de3b3a3b580adec266f94f29ccedf1da228), [#1497](https://github.com/morluto/rea/issues/1497), [#1591](https://github.com/morluto/rea/issues/1591), [#1589](https://github.com/morluto/rea/issues/1589)) Thanks @Adolanium, @akushonkamen, @dakjdakd.
- Added Termux Android browser-scenario support. ([#1655](https://github.com/morluto/rea/pull/1655)) Thanks @tyloryang.
- Web inputs: accept BOM-prefixed HAR, preserve the first duplicate DOM attribute and resolve SVG/XLink URLs in HTML and XHTML. ([#1509](https://github.com/morluto/rea/pull/1509), [#1516](https://github.com/morluto/rea/pull/1516), [#1602](https://github.com/morluto/rea/pull/1602), [#1683](https://github.com/morluto/rea/pull/1683), [#1496](https://github.com/morluto/rea/issues/1496), [#1586](https://github.com/morluto/rea/issues/1586)) Thanks @CassieFox23, @kaoru0822-kitauji, @sathariels, @taljeri.
- Screenshot comparisons: validate PNG chunks, distinguish corruption from unsupported encodings and bound comparison memory. ([4e4b15b](https://github.com/morluto/rea/commit/4e4b15b8250b29e176d4191c9610a3931b693474), [b3e977e](https://github.com/morluto/rea/commit/b3e977e6d073ab1783cece8581279f87fc360411)) Thanks @rudycelekli.
- Archives: preserve case-distinct names, report collisions at their diverging segment, detect nested formats from bytes and reject Windows alternate-stream extraction paths. ([#1480](https://github.com/morluto/rea/pull/1480), [#1505](https://github.com/morluto/rea/pull/1505), [#1553](https://github.com/morluto/rea/pull/1553), [573598c](https://github.com/morluto/rea/commit/573598c6324698cc48ceafd24ed3864670e08d00), [#1470](https://github.com/morluto/rea/issues/1470), [#1491](https://github.com/morluto/rea/issues/1491)) Thanks @CassieFox23, @kaoru0822-kitauji.
- Cleanup: retain failed readers, ASAR handles, output trees and provider workers for retry without discarding completed output or partial observations. ([ffe0574](https://github.com/morluto/rea/commit/ffe0574e17b9d973860371083cb1a351be912131), [de0d341](https://github.com/morluto/rea/commit/de0d341524dc68250a45b41eb7e49fcecc1e32a9), [3f8c51e](https://github.com/morluto/rea/commit/3f8c51e9b506d88fc41aded7b1a22b9a09037c26), [d1235fa](https://github.com/morluto/rea/commit/d1235fadc901e1fb9ab3149d53063306c8545414), [026126e](https://github.com/morluto/rea/commit/026126eafe741e5a8b857433587fd615cdd44c19))
- Providers: canonicalize IDA workspace roots before identity checks, respect IDA cancellation, serialize JEB acquisition and correct Ghidra no-return/imported-symbol recovery. ([#1481](https://github.com/morluto/rea/pull/1481), [#1419](https://github.com/morluto/rea/pull/1419), [5f30ea6](https://github.com/morluto/rea/commit/5f30ea6ff2dd89aab7af6da6e8dfa5e508ed459b), [f88c990](https://github.com/morluto/rea/commit/f88c99021b88ce67e513025901f57478d8107d0c), [49e6f00](https://github.com/morluto/rea/commit/49e6f00ed08b225abf9ddb7c762553607fdab115)) Thanks @AS9929, @JonahSimon, @Y0UW1SH.
- Binary metadata: respect PE/.NET section extents, bound binary-plist expansion, scope keyed-archive traversal and decode app `Info.plist` files without `plutil`. ([#1678](https://github.com/morluto/rea/pull/1678), [#1515](https://github.com/morluto/rea/pull/1515), [#1378](https://github.com/morluto/rea/pull/1378), [#1476](https://github.com/morluto/rea/pull/1476), [975dff2](https://github.com/morluto/rea/commit/975dff2e25b14b634e14dd5e0db1537d0ca9815b), [76296c5](https://github.com/morluto/rea/commit/76296c5a3868ba3b54be6ed3896719283d6de5f8)) Thanks @jayhemnani9910, @kaoru0822-kitauji, @rudycelekli.
- Windows runtimes: preserve drive-root paths when creating private provider directories. ([ee46323](https://github.com/morluto/rea/commit/ee46323b493994902b04824a7dc8aae2a8117903))
- Compatibility: load Windows native controls under Node-API hosts with renamed executables, preserve dylib directory requirements, support Wakaru 1.x and reject directory-valued Hopper launchers. ([#1531](https://github.com/morluto/rea/pull/1531), [#1623](https://github.com/morluto/rea/pull/1623), [#1540](https://github.com/morluto/rea/pull/1540), [#1426](https://github.com/morluto/rea/pull/1426)) Thanks @evenafterallisaid, @Fazmin, @pionxzh, @xeropresence.
- Reference imports: normalize internal symlink lookup consistently, preserve exact paths and exclusion provenance, report root access failures and reject FIFO replacements without blocking. ([#1535](https://github.com/morluto/rea/pull/1535), [2ca3ad2](https://github.com/morluto/rea/commit/2ca3ad238608adfca80a7ff1aaadea6e59a58225), [6636045](https://github.com/morluto/rea/commit/6636045c9c5b472bba51afee9d434394861e93a4), [3967cfa](https://github.com/morluto/rea/commit/3967cfa43e786c65a57e89c265343983d19ef9d0), [f1c58cc](https://github.com/morluto/rea/commit/f1c58cc53fbd83b968e11b3e2eccebca51299c54)) Thanks @anujsingh-cse.
- Setup: honor active configuration and skill roots, preserve configured MCP environments, validate Hermes/OMP profiles before writing, recognize Omarchy and retain recovery backups. ([#1504](https://github.com/morluto/rea/pull/1504), [#1607](https://github.com/morluto/rea/pull/1607), [#1528](https://github.com/morluto/rea/pull/1528), [#1562](https://github.com/morluto/rea/pull/1562), [#1662](https://github.com/morluto/rea/pull/1662), [a011485](https://github.com/morluto/rea/commit/a01148553e2a37c72ae78405418ab648876a96a6), [#1606](https://github.com/morluto/rea/issues/1606), [#1521](https://github.com/morluto/rea/issues/1521), [#1561](https://github.com/morluto/rea/issues/1561)) Thanks @Adkid-Zephyr, @CassieFox23, @LuisTaffelli, @N0zoM1z0, @peter-research.
- Process capture: retain descendant lineage after launcher exit, preserve identity uncertainty before signaling and release terminals after observation failures. ([80896a1](https://github.com/morluto/rea/commit/80896a1d64b216ef893907249cd4252f86215d49), [c916850](https://github.com/morluto/rea/commit/c9168508527302ac57bc86385ccf0d824697b5dc)) Thanks @Y0UW1SH.
- CLI/MCP errors: accept JSON files for web comparisons, preserve native option help and union correction details, remove invalid aliases and validate doctor against its discovered output contract. ([#1397](https://github.com/morluto/rea/pull/1397), [#1395](https://github.com/morluto/rea/pull/1395), [#1425](https://github.com/morluto/rea/pull/1425), [#1461](https://github.com/morluto/rea/pull/1461), [8b4c96e](https://github.com/morluto/rea/commit/8b4c96e6c6b3ed6806e4cd72b556b5db6114304a), [#1421](https://github.com/morluto/rea/issues/1421), [#1454](https://github.com/morluto/rea/issues/1454)) Thanks @Fazmin, @kaoru0822-kitauji, @N0zoM1z0.
### ⚠ BREAKING CHANGES
- WebSocket results: use `network.websocket_connections` instead of `network.websocket_events`. Connections contain `request_id`, `url` and `events`; allow `payload_bytes: null` when size is unknown. No legacy alias remains. ([db4e360](https://github.com/morluto/rea/commit/db4e3608465486466591b594cf77037ac150c988))
- Direct resource APIs: pass a caller-owned `ArtifactResourceScope` to inventory/extraction, JavaScript analysis, reference imports and web exports; retain it through cleanup/shutdown. For `readJavaScriptArtifactFiles`, scope is argument three and abort signal is argument four. Keep each root inventory source’s single cleanup owner. Use `OwnedFileHandle` owners, injected ASAR `fd`/`read` handles instead of `createReadStream`, VCS `Result` values, and `WebScriptExportError`’s options object. CLI/MCP inputs for the scoped operations are unchanged. ([ffe0574](https://github.com/morluto/rea/commit/ffe0574e17b9d973860371083cb1a351be912131), [53e7fad](https://github.com/morluto/rea/commit/53e7fadbd078422ba3d55b5499a70d237c5f4908), [684199b](https://github.com/morluto/rea/commit/684199ba0be7822266d57ddb8a40e95f087fdc42), [be75ed5](https://github.com/morluto/rea/commit/be75ed5e4b4bfb146af497f8fa5d172a1ea19462), [be6272f](https://github.com/morluto/rea/commit/be6272f26115bd8e94f2ab0df4cf092004587a18), [e0e49e9](https://github.com/morluto/rea/commit/e0e49e9dd53d9d1f1d2330b23f7f880dc1c81774), [95a77b6](https://github.com/morluto/rea/commit/95a77b6e25420b3879bd0e32bdbb14d452b38776))
- Saved reference graphs: exclusions require their matching `pattern` and distinguish `project-ignored` from `default-ignored`. Re-import graphs missing that provenance. ([6585293](https://github.com/morluto/rea/commit/6585293c562853b95c3a70df02c12ad8cc17afc4))
- Terminal captures: keep initial and resized buffers within 1,000,000 cells using `columns × (rows + scrollback)`; oversized scenarios are rejected before launch. ([f9ea9a9](https://github.com/morluto/rea/commit/f9ea9a9268c854d31048da9f8a50cfa37703fe5a))
- Optional agent-verification reports: accept schema version 4, nullable `expectedFirstTool` and `targetClarificationPassed`. Production CLI/MCP contracts are unchanged. ([#1613](https://github.com/morluto/rea/pull/1613))
- Capture comparisons: recapture both sides with matching `literal-replacements-v1` semantics when custom normalization patterns are used. Legacy unversioned pattern captures remain readable but cannot be compared with new pattern captures; captures without patterns are unaffected. ([#1456](https://github.com/morluto/rea/pull/1456), [2b6f14f](https://github.com/morluto/rea/commit/2b6f14f528297cf12c776c960af0859f5cfbefbf)) Thanks @Madhavan006, @N0zoM1z0.
- Artifact graph edges: read child artifact IDs and paths from the occurrence selected by `occurrence_id`, not edge fields `child_artifact_id`/`logical_path`. Earlier inventory Evidence no longer validates against the new commitment. ([#1493](https://github.com/morluto/rea/pull/1493)) Thanks @kaoru0822-kitauji.
- Semantic graph schema: nodes and relations no longer include `identifier_strategy`, and relation IDs no longer hash it. Earlier Evidence no longer validates against this schema. ([#1474](https://github.com/morluto/rea/pull/1474)) Thanks @kaoru0822-kitauji.
- Semantic identities: select IDs from the parent graph; read exact event names from `event_name`, endpoints from `endpoint` and literal values from `properties.value`. New analyses use digest-based IDs for long/reserved event and endpoint names and `value-sha256` literal role keys, with shorter labels; string literal labels now read `string literal`. Previously stored graphs retain their original IDs and remain valid workflow inputs. ([#1427](https://github.com/morluto/rea/pull/1427), [#1423](https://github.com/morluto/rea/pull/1423), [#1407](https://github.com/morluto/rea/pull/1407)) Thanks @N0zoM1z0.
### Contributors
- Thanks also to @BaaRai, @commit-regrets, @coygeek, @Franky100-pig, @inii-sayaa, @jopemachine, @JosephDemarest, @keemsisi, @Totopo27 for contributions included in this release.
Full contribution record: [336 commits and 163 merged PRs](https://github.com/morluto/rea/blob/rea-agents-6.4.0/docs/releases/6.4.0.contributions.json).
## [6.3.0](https://github.com/morluto/rea/compare/rea-agents-6.2.0...rea-agents-6.3.0) (2026-10-09)
### ⚠ BREAKING CHANGES
* **captures:** Historical captures without current producer accounting or transaction identity, and web diffs missing accessibility or storage dimensions, are rejected. Preserve original captures and recapture with the current producer; update comparison consumers to include every dimension rather than synthesizing missing observations. See the [process capture guide](docs/process-capture.md) and [browser scenario contract](docs/browser-scenario-contract.md). ([3283a45](https://github.com/morluto/rea/commit/3283a45d09457c79e3adadb50a48620926d4bc5b))
* **browser:** JSON shape paths now contain typed property and array-element segments. WebMCP input_schema_shape is replaced by input_schema and input_schema_sha256, retaining declared examples and defaults.
* **process:** Filesystem digest omission entries now require system_code; budget and changed-file omissions use null, and unavailable-file omissions preserve the operating-system error code.
* **contracts:** Provider analysis outputs must explicitly supply metadata previously repaired with defaults; unsupported nullable facets must be reported as null.
* **javascript:** Semantic graph facts now store evidence context IDs and locations. Graph and semantic trace results require an inline evidence_contexts table.
* **contracts:** source-map URLs now live in target observations selected by declared_url_sha256, and doctor skill identity no longer emits installed_catalog_digest. Use the documented observation join and identity.skill.state instead.
* **javascript:** remove the never-incremented truncated_scopes statistic from JavaScript application analysis results and schemas.
* **native:** Objective-C attribute tokens now contain only name and value. Properties report nullable atomicity and readonly facts; class flags, ivar counts, and method requirement flags are nullable when unobserved.
### Features
* **setup:** register OMP during setup ([#1301](https://github.com/morluto/rea/pull/1301)) ([8b4c359](https://github.com/morluto/rea/commit/8b4c3591358ee59297d8298ede1b63d08459d817))
* **javascript:** record Electron integrity mismatches ([7915ee5](https://github.com/morluto/rea/commit/7915ee51781878ed67e094259924b6e6f3093b3f))
### Bug Fixes
* **inspector:** retain observations after capture failures ([dea3498](https://github.com/morluto/rea/commit/dea3498b2b8d919606eefc4fd62f6ebcbbe5ed30))
* **artifacts:** bind ASAR interpretation to owned snapshots ([d79317c](https://github.com/morluto/rea/commit/d79317cda0bbe8240eb7e25b0a5de90dcffca5fa))
* **artifacts:** infer legacy Mach-O simulator platforms ([5aa2002](https://github.com/morluto/rea/commit/5aa200285ab066e48b37b716495936e6e2a963fd))
* **artifacts:** preserve archive facts and Unicode path identity ([5751f5c](https://github.com/morluto/rea/commit/5751f5caac86c770123ae739a4e4101a72b0989c))
* **artifacts:** reject incomplete inventoried extraction ([5e8fb53](https://github.com/morluto/rea/commit/5e8fb531e255a4a04fc053c54096f66d5c84cde3))
* **artifacts:** retain DMG ownership through uncertain attachment ([a27794c](https://github.com/morluto/rea/commit/a27794c246b3f11d7f92ae7f6d276718190ab731))
* **artifacts:** validate only active extraction entries ([cfb12e4](https://github.com/morluto/rea/commit/cfb12e47dc241f057be93a00892f7d7361d6119d))
* **browser:** follow only HTTP redirect statuses for source maps ([82bbe74](https://github.com/morluto/rea/commit/82bbe743336244d398e67512659ea6943d43a4a4))
* **browser:** preserve payload shapes and WebMCP declarations ([4951a89](https://github.com/morluto/rea/commit/4951a897c53bb6882300c5d7a9660a3f43e374f5))
* **browser:** release attached viewport overrides without resizing the external page ([f6cfbfc](https://github.com/morluto/rea/commit/f6cfbfcc554ff24173dd7ad5333e8e26ab9c962d))
* **browser:** retain attached scenario emulation until cleanup ([a0523b3](https://github.com/morluto/rea/commit/a0523b375eb3147f1d2d1e7eb10a2f4546f5d0fc))
* **browser:** retain malformed redirect diagnostics ([617cd84](https://github.com/morluto/rea/commit/617cd84d27d100e7cc3cd4b5721dea4a996c9775))
* **browser:** serialize attached scenarios through cleanup settlement ([cfce91d](https://github.com/morluto/rea/commit/cfce91d418fbcde4a9ef283a61549279751854e7))
* **ci:** scope verification and reuse native runners ([#1344](https://github.com/morluto/rea/issues/1344)) ([d5cb8ae](https://github.com/morluto/rea/commit/d5cb8aee063065a48233458e04771635167825c8))
* **cli:** avoid duplicate primary cleanup diagnostics ([37fcea7](https://github.com/morluto/rea/commit/37fcea78cecbeeadd869e9a3d77dd133ed264a0a))
* **cli:** classify JSON input permission denials ([08daf05](https://github.com/morluto/rea/commit/08daf056cc8e4d092f9592574d09d5182457b7bc))
* **cli:** classify oversized JSON inputs ([f7cf4c8](https://github.com/morluto/rea/commit/f7cf4c890d4b9c70b1f56e6c627b44a59e58fd73))
* **cli:** stream JSON inputs beyond the whole-document string limit ([#1360](https://github.com/morluto/rea/issues/1360)) ([6ce3288](https://github.com/morluto/rea/commit/6ce3288f3bd65a886e47905455ed5c9b661015e6)), closes [#1331](https://github.com/morluto/rea/issues/1331)
* **cli:** stream JSON results at the shared command boundary ([810107a](https://github.com/morluto/rea/commit/810107a2ad15cc52afd6662aec24d231d8c77225))
* **contracts:** advertise NUL with a portable hex escape ([3f59a84](https://github.com/morluto/rea/commit/3f59a84bd1039763bb349894542601ed78be2033)), closes [#1329](https://github.com/morluto/rea/issues/1329)
* **contracts:** require observed provider output metadata ([a4ba8ae](https://github.com/morluto/rea/commit/a4ba8aecd507637b6261026afc17f79516840d50))
* **electron:** preserve unrepresentable numeric option evidence ([41a228c](https://github.com/morluto/rea/commit/41a228c1b01a89127858b1706879ede08a81deaf))
* **evidence:** order canonical projections independently of locale ([614fb76](https://github.com/morluto/rea/commit/614fb7681ee9e4eba7219c1ee9e90d6a85d78095))
* **files:** reject nonregular capture and JSON inputs ([5f16124](https://github.com/morluto/rea/commit/5f16124a31fa4a82bd03037506809d6be959d768))
* **filesystem:** reject unstable artifact targets ([7829b1a](https://github.com/morluto/rea/commit/7829b1aeef8f43f186be2d2adbd6c67541306a7a))
* **ghidra:** reject a native decompiler built for another host ([#1280](https://github.com/morluto/rea/issues/1280)) ([3728c82](https://github.com/morluto/rea/commit/3728c8267b4fb6da78cbae42a2a6cbddff80ea84)), closes [#1192](https://github.com/morluto/rea/issues/1192)
* **ghidra:** retain process ownership after failed launch rollback ([07675f7](https://github.com/morluto/rea/commit/07675f78c66ce9e8706e808d417265e18ba9f3a5))
* **ghidra:** verify dense jump tables on an optimized fixture ([#1374](https://github.com/morluto/rea/issues/1374)) ([73a664b](https://github.com/morluto/rea/commit/73a664bc78ee618045a2733b8714821281f77403))
* **hopper:** allow restart after verified owned-provider shutdown ([1c12349](https://github.com/morluto/rea/commit/1c123493a21cc579ba7532c40e7ef30df45db3e8))
* **hopper:** probe interior navigation from multi-byte instructions ([#1285](https://github.com/morluto/rea/issues/1285)) ([bf934d5](https://github.com/morluto/rea/commit/bf934d5592e707ba5e7769043de3a430ed8d4923))
* **ida:** compare admitted document paths consistently ([890bb66](https://github.com/morluto/rea/commit/890bb66b35d5f9f8ee54ff0049bf7dc7b82b2480))
* **javascript:** avoid positive-zero evidence for signed zero ([9055bd6](https://github.com/morluto/rea/commit/9055bd695b75f72fb1b8a538d1485d30c0b0ee0b))
* **javascript:** decline source-map UNC references with an unusable host ([#1372](https://github.com/morluto/rea/issues/1372)) ([f504c2a](https://github.com/morluto/rea/commit/f504c2a351027f17ac353fba2d7cfc3505ee17d6))
* **javascript:** distinguish prefix-only builtins from packages ([2b4abbf](https://github.com/morluto/rea/commit/2b4abbf1ccb6dd6ad1248cf48e381df0842542c1))
* **javascript:** honor module-sync package exports ([#1361](https://github.com/morluto/rea/issues/1361)) ([d0e6069](https://github.com/morluto/rea/commit/d0e606930acb701790c286340226b1e3e7060b4f))
* **javascript:** parse declaration artifacts in ambient mode ([4896adc](https://github.com/morluto/rea/commit/4896adcd0f9316034e83129685ed3807ade6f3ea))
* **javascript:** preserve agreeing module provenance ([db171be](https://github.com/morluto/rea/commit/db171be6e570fd1261a30d711e4da2d17de85a93))
* **javascript:** preserve capture-time guards and ordering ([001851f](https://github.com/morluto/rea/commit/001851fde6f972e6ebd01fddccdff4c645a85f63))
* **javascript:** preserve semantic evidence through satisfies ([e995b19](https://github.com/morluto/rea/commit/e995b19f834ba78faa294f5959fd3ad8a97290ca))
* **javascript:** preserve uncertainty after references escape to calls ([#1292](https://github.com/morluto/rea/issues/1292)) ([355a292](https://github.com/morluto/rea/commit/355a292198bf58245c67ae315fdb4f77e62769cc))
* **javascript:** reject invalid package exports configurations ([7a4f268](https://github.com/morluto/rea/commit/7a4f2685d41b134507331c322f0f5da8e1f6c3f4))
* **javascript:** resolve exported callables through lexical bindings ([#1351](https://github.com/morluto/rea/issues/1351)) ([a9f5dad](https://github.com/morluto/rea/commit/a9f5dad5a8f196c88f6305d8d958b355cc0b52c2))
* **javascript:** resolve query-only HTML references to their document ([55a46f7](https://github.com/morluto/rea/commit/55a46f7c7176075c9edda4fe61ed995f2ceadf6a))
* **javascript:** retain array identity after length mutations ([4bcea1a](https://github.com/morluto/rea/commit/4bcea1aa76e3e7ca665197181739c5e27a62c40a))
* **javascript:** retain conditional mutation ordering uncertainty ([b8a8190](https://github.com/morluto/rea/commit/b8a8190b2f30e377eee2d69d1ba31ea454fa70b9))
* **javascript:** retain distinct module provenance path components ([2bd7de6](https://github.com/morluto/rea/commit/2bd7de6f8ca62fc1d48334cfa7fdced461b7b153))
* **javascript:** retain unresolved value frontiers in provenance queries ([3e19875](https://github.com/morluto/rea/commit/3e19875c7fa9c61cff655bbe6046ddc4ab558533))
* **javascript:** store source map URLs once ([ed8fcae](https://github.com/morluto/rea/commit/ed8fcae94b699b62b44162f880faa077a36c455d))
* **json:** preserve runtime limits across JSON file readers ([#1350](https://github.com/morluto/rea/issues/1350)) ([9c4a68b](https://github.com/morluto/rea/commit/9c4a68bc19a0f7d39557e3cc039f5877f6550f63))
* **managed:** bind graph facts to their source Evidence ([cc7b5af](https://github.com/morluto/rea/commit/cc7b5af0777fc68ebba10ec061244729ebf2357d))
* **mcp:** admit composed analysis through result bookkeeping ([e11f4d3](https://github.com/morluto/rea/commit/e11f4d371abaa8cb65ebf7b94fa216329fd78d88))
* **mcp:** advertise object roots for union input schemas ([#1373](https://github.com/morluto/rea/issues/1373)) ([39dabd0](https://github.com/morluto/rea/commit/39dabd0608ed9617d60f16ece05993089f24ff38))
* **mcp:** advertise primitive semantic literal seeds ([f62b449](https://github.com/morluto/rea/commit/f62b44971deee0e99df6fcf32758c8e5592400ed))
* **mcp:** preserve JavaScript workflow identity validation ([#1366](https://github.com/morluto/rea/issues/1366)) ([53ed942](https://github.com/morluto/rea/commit/53ed942a85f51ff9f0e4f01cbb53359df476071d)), closes [#1364](https://github.com/morluto/rea/issues/1364) [#1065](https://github.com/morluto/rea/issues/1065)
* **mcp:** retry failed shutdown resources and retain failure reasons ([e64678e](https://github.com/morluto/rea/commit/e64678e8f9768dd819d8f5f12cc844a6660ff2c5))
* **native:** distinguish symbol definitions from metadata ([70bad53](https://github.com/morluto/rea/commit/70bad53847b0e14489acee73d204ff645e1adfcd))
* **native:** preserve unknown Objective-C metadata ([b112d44](https://github.com/morluto/rea/commit/b112d44a3961939881779c81a57e7a3f9d1372f7))
* **native:** refuse to list architectures of non-Mach-O targets ([#1325](https://github.com/morluto/rea/issues/1325)) ([1b73b5a](https://github.com/morluto/rea/commit/1b73b5ab4bc75bd424e643de8e49f142ffa2b336))
* **native:** retain LLDB cleanup ownership through client close ([7ad353f](https://github.com/morluto/rea/commit/7ad353fa8b3f07e14face80336678d23cc7c6507))
* **process:** keep unobserved file contents unknown ([#1358](https://github.com/morluto/rea/issues/1358)) ([f91f279](https://github.com/morluto/rea/commit/f91f2798b4dc6adb61b3ffe28a24a5d55adbd6ff))
* **process:** retain per-file digest open failures ([415145d](https://github.com/morluto/rea/commit/415145d04f09a15cbfb7dda8ea9dc363a77f9bf0))
* **reference:** report malformed UTF-8 before import parsing ([f166a2a](https://github.com/morluto/rea/commit/f166a2ae15b072216173a51a8f5cad930a858366))
* report malformed application evidence as input errors ([218c131](https://github.com/morluto/rea/commit/218c13160ec0ed7116d6633fc76559ec39dae4d7))
* retain completed observations when later analysis steps fail ([35f121f](https://github.com/morluto/rea/commit/35f121f4acac821e848c485fb82a2c42f51f6ea1))
* **setup:** install the skill for Claude Code ([b4a1919](https://github.com/morluto/rea/commit/b4a19193fe3baf9075f8ac419517021ea0c71ea3))
* **setup:** recognize supported Nobara hosts ([f0dc233](https://github.com/morluto/rea/commit/f0dc233d64de4c215c453c346e516b7622713e95))
* **skill:** pin packaged commands to the shipping package version ([2793672](https://github.com/morluto/rea/commit/2793672ee2a575f97a8011c7fec5288098cdd5d1))
* **skill:** pin packaged commands to the shipping package version ([#1346](https://github.com/morluto/rea/issues/1346)) ([f39e71c](https://github.com/morluto/rea/commit/f39e71ce1897bb5c704b33a8b0049567f11e3a13))
* **snapshot:** preserve complete investigation revision histories ([#1354](https://github.com/morluto/rea/issues/1354)) ([1c0cc8a](https://github.com/morluto/rea/commit/1c0cc8a6753b5ac781b28ebb1832f3a6a1771a68))
* **targets:** cancel resolution before provider admission ([f3c4a33](https://github.com/morluto/rea/commit/f3c4a332f7bd198bd67f0187bc2a85c7b31bb960))
* **update:** preserve disabled client registrations ([abf5e24](https://github.com/morluto/rea/commit/abf5e243c4d2cae03404b6e1fb1ccc77be917b53))
### Performance Improvements
* **javascript:** index version relationships once per comparison ([#1347](https://github.com/morluto/rea/issues/1347)) ([b1e85ad](https://github.com/morluto/rea/commit/b1e85ad711743a594c572dbd5b0d5cb664e2a502))
* **javascript:** validate the version change graph once ([#1370](https://github.com/morluto/rea/issues/1370)) ([037709a](https://github.com/morluto/rea/commit/037709a52c0824f4d2bbee90d8e2642b2d88d364))
* **json:** encode streamed JSON iteratively ([#1322](https://github.com/morluto/rea/issues/1322)) ([56598be](https://github.com/morluto/rea/commit/56598beb4e82968a313deb9efdf4b98db5bd1f4f))
### Code Refactoring
* use canonical implementations and types directly ([765e809](https://github.com/morluto/rea/commit/765e809e366eff21b4b9c224f1a813ad64245ea3))
* **artifacts:** remove unused root classifier ([5291bca](https://github.com/morluto/rea/commit/5291bca108af781214572fac709f9808bb8aa4db))
* **artifacts:** test inventory changes at materialization boundary ([750fb65](https://github.com/morluto/rea/commit/750fb6565052e9eaad40b946b6a284d0730d14f8))
* **browser:** open scenario sessions without a factory wrapper ([d1983a4](https://github.com/morluto/rea/commit/d1983a45767bfcdc020652f48109a78a3f9fa590))
* **catalog:** import CLI metadata from its owner ([8c96baa](https://github.com/morluto/rea/commit/8c96baab80dc258d31ca1632d761fffb11dbaaae))
* consolidate boundary semantics and prune redundant tests ([392f1f3](https://github.com/morluto/rea/commit/392f1f310733f2c365da7bc57a1154cf10ec4ba0))
* **javascript:** normalize erased expression syntax once ([b628bba](https://github.com/morluto/rea/commit/b628bba1fa65fd3b51363bf4b745f0afc57e1dba))
* **javascript:** parse runtime evidence into one verified owner ([006b295](https://github.com/morluto/rea/commit/006b295f1de19fd5351832cf52d98a202a5cd5cd))
* **javascript:** remove obsolete scope truncation statistic ([449d570](https://github.com/morluto/rea/commit/449d57075eec71b2f064af8877c50cbbde30a283))
* **javascript:** share Babel child traversal ([0f10499](https://github.com/morluto/rea/commit/0f10499245ec2fab8823f116caf34450b3a7385b))
* **javascript:** share semantic evidence at fact construction ([e3bbb9a](https://github.com/morluto/rea/commit/e3bbb9ac453da8d15f3b32511180451613710616))
* **process:** remove duplicate observation and trace entry points ([070339a](https://github.com/morluto/rea/commit/070339af50a50a0f23e82db859e761c53277ee79))
* **providers:** use canonical artifact and managed identities ([87f0051](https://github.com/morluto/rea/commit/87f0051496aff1b05ab24d6b63f79884f4ca9b8f))
* **reference:** simplify malformed UTF-8 handling ([377df71](https://github.com/morluto/rea/commit/377df715ea5b2523cd6c1084fdc286eb8a056182))
* remove obsolete source exclusions and identity wrapper ([44c92f8](https://github.com/morluto/rea/commit/44c92f88c51841735741811a68cc89fde14efa80))
* remove single-use forwarding helpers ([4144e45](https://github.com/morluto/rea/commit/4144e454f385c372d29e301e6bb959092c606a6e))
### Documentation
* keep license sections text-only ([e10f1f0](https://github.com/morluto/rea/commit/e10f1f0901fa56fb4443837cf9528b31a12e140e))
* align translated README artwork and layout ([ccfbe87](https://github.com/morluto/rea/commit/ccfbe87e984e456e12c66d0d2fe6d5a559d09518))
* add README artwork and refine closing sections ([4b8e744](https://github.com/morluto/rea/commit/4b8e744d90579e353371649047215c4e4be7a5f6))
* add repository-local REA tool design skill ([7738c1f](https://github.com/morluto/rea/commit/7738c1f6a9ccf1ec9868ef832f154abe9ba5eebd))
* celebrate 40,000 GitHub stars 🎉 ([3edb217](https://github.com/morluto/rea/commit/3edb2172def0e0bd9076f23148f0c41cd2f341a3))
* celebrate 40,000 GitHub stars 🎉 ([5ecc98a](https://github.com/morluto/rea/commit/5ecc98a5eac4c10d33e9c418b9ffae61c68e3ef2))
* consolidate agent guidance around ownership and boundaries ([ba44222](https://github.com/morluto/rea/commit/ba4422296dc409d49836f25642555e00463bfe3b))
* **contracts:** explain canonical URL and skill metadata ownership ([e36afa1](https://github.com/morluto/rea/commit/e36afa112fd7b7ab5a925ca452de93b68f12a6ab))
* correct MCP error and capture import guidance ([077d6c4](https://github.com/morluto/rea/commit/077d6c407b3ea7443a7277ae0e5531b3927dd742))
* correct README setup and runtime guidance ([5b3715e](https://github.com/morluto/rea/commit/5b3715ef825a30150b02d3f1bb7d40dd89453018))
* explain CI scope and native runner reuse ([#1348](https://github.com/morluto/rea/issues/1348)) ([6c9161d](https://github.com/morluto/rea/commit/6c9161d61745e242643f224ce49e7468143a15f3))
* prune repeated contributor and tool design instructions ([5d79387](https://github.com/morluto/rea/commit/5d79387505ebae1ec8d800ee3ffd901920a9d8be))
* remove retired architecture and migration artifacts ([7a0c800](https://github.com/morluto/rea/commit/7a0c80085128e6329ca2e4f54f3539f3245c57d1))
### Tests
* share the client registration command to restore the jscpd gate ([#1317](https://github.com/morluto/rea/pull/1317)) ([5d16be2](https://github.com/morluto/rea/commit/5d16be2a7185db8b70a5fcbc5f5e1be63297f2c8))
* **mcp:** remove arbitrary schema inventory thresholds ([24673aa](https://github.com/morluto/rea/commit/24673aaae497ca4ef0902544c0cd69817f5424ed))
* **android:** allow provider readiness under load ([961c3c3](https://github.com/morluto/rea/commit/961c3c3de79ec44d608d011eb3fa3d6bd645cf6a))
* **artifacts:** verify extraction races with real filesystem changes ([1ac8389](https://github.com/morluto/rea/commit/1ac8389c5c1f75faf8d7f2f3faf2f24febad5fea))
* **browser:** avoid duplicating source-map listener setup ([9367dc1](https://github.com/morluto/rea/commit/9367dc13bd8d2732d36d5376b5de170c9f4af424))
* **browser:** report redirect status cases independently ([5a61562](https://github.com/morluto/rea/commit/5a61562dc200120c7b8020854085c17b8203e95d))
* **cli:** remove duplicate malformed JSON assertion ([5d32e42](https://github.com/morluto/rea/commit/5d32e4252941e93065cadd83b9f02aa6427544d8))
* exercise source test selection through Git and Vitest ([25711ad](https://github.com/morluto/rea/commit/25711ad2590af136dfb301839dddd6d30971ba76))
* **filesystem:** bound FIFO regressions at consumers ([0bfb6e0](https://github.com/morluto/rea/commit/0bfb6e00abae1e67a96e548d64954bb21861f621))
* **ghidra:** allow rollback tests to reach spawned process ([d761d73](https://github.com/morluto/rea/commit/d761d7358b45fe0724b182a206241fd605f338b0))
* **javascript:** share primitive expansion producer fixtures ([c867bcd](https://github.com/morluto/rea/commit/c867bcd0aadd63473865f9a328459e0db3c89565))
* **javascript:** share semantic graph test facts ([ac356c4](https://github.com/morluto/rea/commit/ac356c46ad6a17c8864bc5d350984786db62d2f5))
* **javascript:** verify distinct module origins through reconstruction ([96b2b24](https://github.com/morluto/rea/commit/96b2b245fdefc9c78f5dcf6ce054232b51f7c117))
* **json:** remove assertions covered by CLI output consumers ([a959a83](https://github.com/morluto/rea/commit/a959a8309db79fbee6477efd7ee541615e625627))
* **managed:** include shared dossier fixture in artifact inputs ([66a20a2](https://github.com/morluto/rea/commit/66a20a2597b5daebc0a292361aa62a78b7df6e7d))
* **native:** retain trace diagnostics when observed hits differ ([048b798](https://github.com/morluto/rea/commit/048b79878c70c594789909082499dc675472b63a))
* **package:** share validated native dossier fixtures ([ca90109](https://github.com/morluto/rea/commit/ca9010936a934a49fbc6cf69eb1d7fc2242b6da9))
* **process:** publish capture readiness atomically ([74be526](https://github.com/morluto/rea/commit/74be52611e66f680ef1919d521fc3c304bc2326e))
* **process:** report cleanup details on cancellation failures ([79d5b9a](https://github.com/morluto/rea/commit/79d5b9a826b9204c1ef59b0a5c5ec83e7a2f2bec))
* **process:** use owned CLI and workspace fixtures ([4940a86](https://github.com/morluto/rea/commit/4940a867e2e56cbb974bfa321008a8f35db47d52))
* share snapshot replay and managed graph fixtures ([d83cbd2](https://github.com/morluto/rea/commit/d83cbd2abf1bbf15beef990f5353457fdbaaeb8e))
### Continuous Integration
* enforce architecture guards with portable checkout paths ([ecc67ca](https://github.com/morluto/rea/commit/ecc67cab2d85cacda245890ffe84b80ac395d79e))
## [6.2.0](https://github.com/morluto/rea/compare/rea-agents-6.1.0...rea-agents-6.2.0) (2026-10-09)
### ⚠ BREAKING CHANGES
Read the [6.1 to 6.2 migration guide](docs/migration-6.2.md) before upgrading. REA's `always-bump-minor` policy includes breaking changes; 6.2 is not a backward-compatibility promise. Preserve original saved files and regenerate missing observations rather than fabricating identities or facts.
* **MCP / Evidence / snapshots / artifacts:** Success results are direct canonical Evidence; read `normalized_result` rather than the old `result`/`evidence` wrapper. Evidence requires nullable `analysis_profile`, session provider aliases are removed, snapshots require complete profile-bound query records, and artifact roles/permissions belong to occurrences. Recreate incompatible saved data; adding fields without recomputing their semantic identity is invalid. ([63bf914](https://github.com/morluto/rea/commit/63bf91405cf97b114a84f337fb1272d98a267999))
* **Process captures:** Legacy v3 conversion is removed. Explicit executable identity and `event_journal` are required; retain old captures and recapture when current comparisons are needed instead of inventing launch identity or event order. ([2a77469](https://github.com/morluto/rea/commit/2a7746998d47446c4db6d4f524e0f183d6803f3f))
* **Cleanup and evaluation:** A one-shot analysis reports cleanup failure while preserving the completed observation or primary diagnostic. Handle `cleanup_incomplete` and retained observations/resources. Configured agent-evaluation fixtures require Evidence-backed correctness, not routing or answer wording alone. ([#1211](https://github.com/morluto/rea/pull/1211), [27a9cea](https://github.com/morluto/rea/commit/27a9ceade7232c1c9a24dc7d454ae060948183a1))
* **JavaScript:** Return-field projections require explicit presence; export-shape changes carry both sides' presence and property inventory coverage. Semantic object operations retain complete `property_path` segments. Regenerate old analysis and distinguish unknown values from unknown presence. ([475a0f8](https://github.com/morluto/rea/commit/475a0f84dac63d710e032bc7f731c1a3bda624ec))
* **Function comparisons:** Remove the unreachable `truncated` dimension state and `summary.truncated` counter; update enum and display consumers while retaining explicit `unknown` facts. ([5510b27](https://github.com/morluto/rea/commit/5510b27d7f863a3df26212fba4a59f8df0da3712))
* **Historical sources:** Unreadable/unknown symlink targets require `target: null`; external targets retain the observed absolute target. Reimport graphs containing display placeholders such as `<outside-root>` and handle nullable targets. ([b7b4333](https://github.com/morluto/rea/commit/b7b433370310c3ffe33d5027d8393151d5e862da))
### Features
* **javascript:** report observed export property presence ([#1160](https://github.com/morluto/rea/issues/1160)) ([45e3edc](https://github.com/morluto/rea/commit/45e3edc17f48954c89d8db86f7313c479bd39344))
* **mcp:** select views of retained analysis results ([#1180](https://github.com/morluto/rea/issues/1180)) ([db675f1](https://github.com/morluto/rea/commit/db675f1d52acda62b6f57b5a8773532f49b259e7))
* **website:** add an Aegis APK code-generation showcase ([0270dd5](https://github.com/morluto/rea/commit/0270dd5739480acced62e045b5890ec0ebde2631))
* **website:** add an Android showcase and clearer project prompts ([6cc817e](https://github.com/morluto/rea/commit/6cc817e8bd377b064b3568ef1eacb27eaefcb4c1))
* **website:** add beginner examples and synchronized publishing ([0fec65d](https://github.com/morluto/rea/commit/0fec65d06b2f5431e704c472e53015d4b3cc967c))
* **website:** add beginner examples and synchronized publishing ([#1203](https://github.com/morluto/rea/issues/1203)) ([0fec65d](https://github.com/morluto/rea/commit/0fec65d06b2f5431e704c472e53015d4b3cc967c))
* **website:** add Discord link beside GitHub badge ([cc39fc5](https://github.com/morluto/rea/commit/cc39fc53b829a349ae199823472990a53014c507))
* **website:** add homepage navigation and faster reading paths ([863674b](https://github.com/morluto/rea/commit/863674b2e92dd7c699768db82d521ccc88b7ebe4))
* **website:** add homepage navigation and faster reading paths ([c94f06d](https://github.com/morluto/rea/commit/c94f06d98f895eb8b6c5ffa5e999ef1d4bb5eea2))
* **website:** add homepage navigation and faster reading paths ([#1213](https://github.com/morluto/rea/issues/1213)) ([863674b](https://github.com/morluto/rea/commit/863674b2e92dd7c699768db82d521ccc88b7ebe4))
* **website:** add search metadata and automatic sitemap ([99f257b](https://github.com/morluto/rea/commit/99f257bbf03c27327e5e0a232fefd3c792acd5bc))
* **website:** add search metadata and automatic sitemap ([b8851cb](https://github.com/morluto/rea/commit/b8851cb977cfdd608798d32bf5877f645b960831)), closes [#1283](https://github.com/morluto/rea/issues/1283)
* **website:** clarify reverse engineering and showcase goals ([e750c26](https://github.com/morluto/rea/commit/e750c262fbf37100369ab25bf8659daa1a2c4cc7))
* **website:** explain REA through a first investigation ([5160d9b](https://github.com/morluto/rea/commit/5160d9b717d0207a357c754bdf72e215e59d19d1))
* **website:** explain REA with Calculator and a playable dinosaur lab ([11b9f03](https://github.com/morluto/rea/commit/11b9f0346cf5413045b41ff552a024e11ba46ccc))
* **website:** lead with the playable dinosaur example ([19c52f5](https://github.com/morluto/rea/commit/19c52f5e3f42fb754fc154bbd16552c5111df0c5))
* **website:** show manual analysis beside a one-prompt workflow ([291bc6f](https://github.com/morluto/rea/commit/291bc6fb70f47d28d23440f03a8a7fa49eb9a391))
### Bug Fixes
* **dev:** accept formatter-ignored staged documentation without failing the commit hook; malformed JSON remains rejected. ([bd2db2f](https://github.com/morluto/rea/commit/bd2db2f0fa495fb08dea443cd16d7683d4b86e6a))
* **release:** publish reviewed release-PR merges from their exact reviewed source. ([c12bad7](https://github.com/morluto/rea/commit/c12bad7f139431fc0db7a8b7c9db1eab95f96dc2))
* **android:** support owned JADX stdio on Windows ([#1276](https://github.com/morluto/rea/issues/1276)) ([636b245](https://github.com/morluto/rea/commit/636b245f1badf2a7ecfa63c6e2378ac2f7673cc3)), closes [#1262](https://github.com/morluto/rea/issues/1262)
* **android:** validate engine archive prerequisites ([#1145](https://github.com/morluto/rea/issues/1145)) ([e9ebfb9](https://github.com/morluto/rea/commit/e9ebfb94eff0699b1ea84bba000c4467fa1cb998))
* **apple:** report unusable dylib-resolution roots as invalid input ([6a1e558](https://github.com/morluto/rea/commit/6a1e558db3ec2b69561e91ea817f1c2065dfc676))
* **apple:** report unusable dylib-resolution roots as invalid input ([24a30fd](https://github.com/morluto/rea/commit/24a30fd91c144b7f2533e5f5de8c91268773519c))
* **artifacts:** keep cancellation and the caller path in extraction refusals ([37025cc](https://github.com/morluto/rea/commit/37025cc09f12d49f46e61eedc3564c710089146b))
* **artifacts:** keep cancellation and the caller path in extraction refusals ([eacf846](https://github.com/morluto/rea/commit/eacf8461dad6bab11a3d5438e6db001a10f33a9b))
* **artifacts:** match lipo arm64e variant names to their FAT slices ([de5bfec](https://github.com/morluto/rea/commit/de5bfec79fe862816350b2deeb42a12c0734d855))
* **artifacts:** match lipo arm64e variant names to their FAT slices ([0b32577](https://github.com/morluto/rea/commit/0b32577a90aef97e36adf2a7af4f3eccd5d82357)), closes [#1168](https://github.com/morluto/rea/issues/1168)
* **artifacts:** name only host-available workflows for non-archive plists ([f4c99ab](https://github.com/morluto/rea/commit/f4c99ab8a53806dd57dc24b3d5a600905bcb4686))
* **artifacts:** name only host-available workflows for non-archive plists ([2295855](https://github.com/morluto/rea/commit/22958558eafdfccf71a7d5bbbcf360574a6b2e3c))
* **artifacts:** recheck failed DMG detaches before reporting cleanup failure ([#1155](https://github.com/morluto/rea/issues/1155)) ([58a91f0](https://github.com/morluto/rea/commit/58a91f03d72162849991caf537ab058ccc918594))
* **artifacts:** refuse unsupported extraction formats before scanning ([8e74c9c](https://github.com/morluto/rea/commit/8e74c9c62fb44556b90f20bb6c12771ac05a18f2))
* **artifacts:** report encrypted archive entries as unsupported extraction ([de43da7](https://github.com/morluto/rea/commit/de43da71ae982dd0f3d7b5ae49c914729db3a6ec))
* **artifacts:** report non-archive keyed-archive selections as unsupported targets ([fef38e4](https://github.com/morluto/rea/commit/fef38e4d22ee859ec43fb591d53e8b9973c69958))
* **artifacts:** report non-archive keyed-archive selections as unsupported targets ([8c5088c](https://github.com/morluto/rea/commit/8c5088c8cdf32a9f96f6c479c6e70a71fa360168))
* **artifacts:** report wrong target kinds as unsupported targets ([b34bdcd](https://github.com/morluto/rea/commit/b34bdcdb2877be394c59c9cbf70269dc1841ff78))
* **artifacts:** report wrong target kinds as unsupported targets ([637bcb5](https://github.com/morluto/rea/commit/637bcb5e4182b6c60e922b18688642d8e1008e90))
* **browser:** classify export-web-scripts capture selection failures by cause ([ddaa183](https://github.com/morluto/rea/commit/ddaa18301ab9c67e7a6f7ce66076075e8a4d5017))
* **browser:** classify export-web-scripts capture selection failures by cause ([8c5e34c](https://github.com/morluto/rea/commit/8c5e34cd379392ca40f651ca5eeb6a947b44aa33))
* **browser:** report Windows HAR heap exhaustion ([#1147](https://github.com/morluto/rea/issues/1147)) ([1393507](https://github.com/morluto/rea/commit/13935077ba039f6e342f9c11ab5eea935a335ae6))
* **browser:** retain scenario observations across failures ([614e0c2](https://github.com/morluto/rea/commit/614e0c2e74819bb5e3ef3d2e16ff31ee6cab76ae))
* **browser:** retain scenario resources until cleanup succeeds ([88640f6](https://github.com/morluto/rea/commit/88640f60fe566edbe2320688df62c7ef46c4c61c))
* **ci:** pass selected environment to Windows Ghidra fixture ([#1281](https://github.com/morluto/rea/issues/1281)) ([f085589](https://github.com/morluto/rea/commit/f085589957922eaf421db814399e88e415712050))
* **cli:** advertise defaulted inputs as optional in --schema and help ([#1175](https://github.com/morluto/rea/issues/1175)) ([b4927a0](https://github.com/morluto/rea/commit/b4927a0a4fa7e8935b101d214b396bfa78208281)), closes [#1169](https://github.com/morluto/rea/issues/1169)
* **cli:** cancel routed JavaScript analysis in rea analyze ([#1156](https://github.com/morluto/rea/issues/1156)) ([089bbf5](https://github.com/morluto/rea/commit/089bbf58f3561e3f465c544bbcf8c307287b1256))
* **cli:** complete cleanup after relayed interrupts ([#1202](https://github.com/morluto/rea/issues/1202)) ([911152a](https://github.com/morluto/rea/commit/911152a04d3aeb0d361141a8d54959009b269e49))
* **cli:** list the read failure cause for an unreadable JSON input file ([db0afce](https://github.com/morluto/rea/commit/db0afce5f344268271c59acee04e96f986c5619a))
* **cli:** list the read failure cause for an unreadable JSON input file ([6020df5](https://github.com/morluto/rea/commit/6020df53d9cd44845cf3b6b416db2d7802925578))
* **cli:** resolve xrefs symbol selectors after address validation ([#1209](https://github.com/morluto/rea/issues/1209)) ([7e9c911](https://github.com/morluto/rea/commit/7e9c91199ecd133d26a51cb33b6e63e1f942df7e))
* **config:** name the rejected setting and its constraint in configuration errors ([c3acc34](https://github.com/morluto/rea/commit/c3acc34475ca22387ea674839acfa1891b0b9f66))
* **config:** name the rejected setting and its constraint in configuration errors ([0a0244d](https://github.com/morluto/rea/commit/0a0244db4212bc1f59dec4b925fa90b3b473136a)), closes [#1184](https://github.com/morluto/rea/issues/1184)
* **doctor:** find the Homebrew Hopper cask without writing Homebrew caches ([98b07d0](https://github.com/morluto/rea/commit/98b07d07ddd20bea2c3bdf8d55ac2776a263bcf4))
* **doctor:** find the Homebrew Hopper cask without writing Homebrew caches ([a503376](https://github.com/morluto/rea/commit/a503376b2f9d9ba14d1602e58e0e93059e9d9181)), closes [#1165](https://github.com/morluto/rea/issues/1165)
* **domain:** report target read-permission denials as access_denied ([f36c10f](https://github.com/morluto/rea/commit/f36c10f9e8dc45a298d668e608f8e945bde487cf))
* **domain:** report target read-permission denials as access_denied ([d0ff57a](https://github.com/morluto/rea/commit/d0ff57a45c8da8938e7ae16d00bfd5ec63310af3)), closes [#1188](https://github.com/morluto/rea/issues/1188)
* **electron:** resolve effective preload after option overrides ([#1286](https://github.com/morluto/rea/issues/1286)) ([411498d](https://github.com/morluto/rea/commit/411498d45f860eba2fbc9d7051af20237b7a4cb1))
* emit v-mode-compatible patterns for tool schemas ([#1220](https://github.com/morluto/rea/issues/1220)) ([f0da05f](https://github.com/morluto/rea/commit/f0da05f67fff1411cf2f7a48a752ee7b348c71ff))
* **errors:** report caller-selected evidence path failures as invalid input ([d4a598e](https://github.com/morluto/rea/commit/d4a598e93649607dd293a9c81bbf79c211bc8dd4))
* **errors:** report caller-selected evidence path failures as invalid input ([db177c9](https://github.com/morluto/rea/commit/db177c91b83adb0c3edc4f9f6f06e31ac7523d53))
* **evidence:** cancel exports before atomic publication ([16624f1](https://github.com/morluto/rea/commit/16624f1324e156d14025b2c346596c9781c07488))
* **ghidra:** classify modern Swift manglings in swift type analysis ([#1208](https://github.com/morluto/rea/issues/1208)) ([6935dc7](https://github.com/morluto/rea/commit/6935dc7fe1258b340bb9cdfb8cecae66ef7bc0d4))
* **ghidra:** do not run Java from a relative JAVA_HOME in doctor and setup ([04a516b](https://github.com/morluto/rea/commit/04a516b1e369f7e57e08d0653cc08292ac497e07))
* **ghidra:** do not run Java from a relative JAVA_HOME in doctor and setup ([c3f1698](https://github.com/morluto/rea/commit/c3f169823f690371ecfdd2d1b3b07a5749438cf1))
* **ghidra:** keep and name a runtime directory that close could not remove ([5b769d3](https://github.com/morluto/rea/commit/5b769d3a781c645ed8885e4fabf01a00f0bbc89b))
* **ghidra:** keep and name a runtime directory that close could not remove ([b79d379](https://github.com/morluto/rea/commit/b79d379c25bcc8ed61571c41a94b912b5704a067)), closes [#1190](https://github.com/morluto/rea/issues/1190)
* **ghidra:** keep the NativeAOT target refusal's own recovery advice ([f198993](https://github.com/morluto/rea/commit/f198993f418e6aaa9755e7e6413abcb27c6cd684))
* **ghidra:** preserve decoded return flow evidence ([b189c3c](https://github.com/morluto/rea/commit/b189c3ceb175dd9fa089eada9e9ca54e76307cb3))
* **ghidra:** preserve decoded return flow evidence ([bcc8a77](https://github.com/morluto/rea/commit/bcc8a773e2a714e4899755b786a4fef1539bbace))
* **ghidra:** reject relative installation and Java paths in doctor and setup ([8998438](https://github.com/morluto/rea/commit/8998438c23aa19e68f4ffa7574c5d341aa419165))
* **ghidra:** reject relative installation and Java paths in doctor and setup ([5356856](https://github.com/morluto/rea/commit/53568568bf32b36274ba3a532f1e2cfb2daed271)), closes [#1183](https://github.com/morluto/rea/issues/1183)
* **ghidra:** report NativeAOT host and target refusals as unsupported, not failures ([cfb49eb](https://github.com/morluto/rea/commit/cfb49eb8a88fc51f460907024c51e05a2f272502))
* **ghidra:** report NativeAOT host and target refusals as unsupported, not failures ([42c276a](https://github.com/morluto/rea/commit/42c276af1ec02473a7b6700a31292aae9e53d53e)), closes [#1185](https://github.com/morluto/rea/issues/1185)
* **ghidra:** resolve secondary symbols at function entries ([#1195](https://github.com/morluto/rea/issues/1195)) ([6fbdbd6](https://github.com/morluto/rea/commit/6fbdbd682038d012b04f0fe92c470cf1789fb101))
* **ghidra:** stop dereferencing the removed error payload in address verification ([b80bd2d](https://github.com/morluto/rea/commit/b80bd2db966731fd3cfddfff7e92704053dbe955))
* **ghidra:** stop dereferencing the removed error payload in address verification ([59fbaa2](https://github.com/morluto/rea/commit/59fbaa2d33359216534407f99f49705ac04a3426))
* **ghidra:** use dot-free private session paths ([c3fc6c3](https://github.com/morluto/rea/commit/c3fc6c3aedc202e8ade015c4039a63e9f91cac6d))
* **hopper:** keep the OS error when the FAT64 source cannot be reopened ([9f5dc52](https://github.com/morluto/rea/commit/9f5dc52be8420fb5e874595d63312bf80d07a3a2))
* **hopper:** reserve Linux demo application before launch ([#1158](https://github.com/morluto/rea/issues/1158)) ([33d5ae0](https://github.com/morluto/rea/commit/33d5ae0b52b8684634ecf14d4e9469968c69d462))
* **javascript:** allow cancellation during semantic graph commitment ([#1218](https://github.com/morluto/rea/issues/1218)) ([9405bd6](https://github.com/morluto/rea/commit/9405bd660def9946afaa5fcc1d99921a816911bf))
* **javascript:** classify application input selection failures by cause ([fe5291e](https://github.com/morluto/rea/commit/fe5291e9166977a6ebbfa6ffcf7850af57192b34))
* **javascript:** classify application input selection failures by cause ([0a14bbb](https://github.com/morluto/rea/commit/0a14bbbf05e0e61c98e06326fe7136e52fa4fb3c))
* **javascript:** keep Wakaru version stderr out of the refusal message ([6489d58](https://github.com/morluto/rea/commit/6489d58851d055fd7ce621000d960bb42a0e4ce0))
* **javascript:** match source-map originals that name parent directories ([#1215](https://github.com/morluto/rea/issues/1215)) ([889fb37](https://github.com/morluto/rea/commit/889fb374df0f8986f49e9d61b0fefd536327f781))
* **javascript:** omit self-referential static references with disclosure ([#1157](https://github.com/morluto/rea/issues/1157)) ([b620e2a](https://github.com/morluto/rea/commit/b620e2a2bdcf3683b494d137bc409813735d5572))
* **javascript:** preserve alias and container uncertainty ([73e98b2](https://github.com/morluto/rea/commit/73e98b2516dd792ea7b510aeed6b71f384bea21d))
* **javascript:** preserve graphs with async chunk self-references ([#1152](https://github.com/morluto/rea/issues/1152)) ([7220166](https://github.com/morluto/rea/commit/72201668ed88c2cc822a07c08cf35a1e5ba88f35))
* **javascript:** preserve property paths and uncertain slot presence ([475a0f8](https://github.com/morluto/rea/commit/475a0f84dac63d710e032bc7f731c1a3bda624ec))
* **javascript:** reject encoded separators joined by HTML URL whitespace ([2ddd945](https://github.com/morluto/rea/commit/2ddd9456cd405f081784a4b3cb02cb77cd90fbd6))
* **javascript:** reject encoded separators joined by HTML URL whitespace ([fb57c86](https://github.com/morluto/rea/commit/fb57c8643fb8b4733cbac9090ef58fd13a3b5347))
* **javascript:** report located sources with differing digests as modified ([#1216](https://github.com/morluto/rea/issues/1216)) ([01174c4](https://github.com/morluto/rea/commit/01174c4a81fea109ae712ea1a746a83996f928ac))
* **javascript:** resolve HTML script URLs after URL whitespace and percent decoding ([d601b80](https://github.com/morluto/rea/commit/d601b8016eaeb2955cea4e4c0aca10d17e7d12a7))
* **javascript:** resolve HTML script URLs after URL whitespace and percent decoding ([502528c](https://github.com/morluto/rea/commit/502528c58df54c7b34eefdb5837f36e58f473405)), closes [#1236](https://github.com/morluto/rea/issues/1236)
* **javascript:** resolve package exports targets only to the exact file ([#1181](https://github.com/morluto/rea/issues/1181)) ([2a620c0](https://github.com/morluto/rea/commit/2a620c06cdcaa32844c4a80aeb3df1793f1ce09e)), closes [#1174](https://github.com/morluto/rea/issues/1174)
* keep the Ghidra session root free of dot-prefixed path elements ([a8b8288](https://github.com/morluto/rea/commit/a8b8288396cf2e053db768ef03f4db756aa8f71e))
* **managed:** preserve literal library names during native matching ([81b70bc](https://github.com/morluto/rea/commit/81b70bc358031686c9d7afd049f21719c67a9525))
* **managed:** separate metadata and signature completeness ([2f02eff](https://github.com/morluto/rea/commit/2f02eff9887fc715c33f5d8770a6e6191ba70ca9))
* **mcp:** advertise input patterns without look-around ([1f099a6](https://github.com/morluto/rea/commit/1f099a6fc00b08fb0283dcabc5a238025d4c4c8b))
* **mcp:** advertise input patterns without look-around ([a8701ea](https://github.com/morluto/rea/commit/a8701eaf489692449739d5b2490502b1a14951c5)), closes [#1282](https://github.com/morluto/rea/issues/1282)
* **mcp:** deliver tool errors within advertised schema contracts ([da606ff](https://github.com/morluto/rea/commit/da606ff77718d9a3b10426fcf68c098138e6dcfa)), closes [#1261](https://github.com/morluto/rea/issues/1261)
* **mcp:** deliver typed errors without invalid structured output ([#1277](https://github.com/morluto/rea/issues/1277)) ([7e96f25](https://github.com/morluto/rea/commit/7e96f25f8b1380a13a086a68f8d5a70380468151))
* **mcp:** emit portable Unicode NUL patterns ([#1230](https://github.com/morluto/rea/issues/1230)) ([aa5750c](https://github.com/morluto/rea/commit/aa5750c263632d98d626c5ca3b985bb1519d2395))
* **mcp:** measure tool errors against their text-only delivery ([fe34ec2](https://github.com/morluto/rea/commit/fe34ec2ef3e2968eeb06f64a1a0fdb8b825f56c4))
* **mcp:** measure tool errors against their text-only delivery ([7b51121](https://github.com/morluto/rea/commit/7b51121f7cee21a5938f10ac3b5762e0bb41a58d))
* **mcp:** only recommend exporting retained evidence ([5f749c2](https://github.com/morluto/rea/commit/5f749c2096af2617d4b6b387ff19c13001af8e54))
* name host and tool requirements in optional adapter refusals ([68cb02f](https://github.com/morluto/rea/commit/68cb02fe8b123b9a0778c0065c13a15bcf0e577d))
* name host and tool requirements in optional adapter refusals ([170d0bf](https://github.com/morluto/rea/commit/170d0bf9e2d45b2512ad556c02f31bdc81ea03ca))
* **native:** distinguish batch selectors from resolved entries ([13c3b68](https://github.com/morluto/rea/commit/13c3b68730df80330fd867d921dea38770d5f880))
* **native:** distinguish batch selectors from resolved entries ([bfaa5a6](https://github.com/morluto/rea/commit/bfaa5a6c2c0ddc9e6fcf16cd11ad06f24db174a2))
* **native:** name the CLI flag that selects another plist ([9b69503](https://github.com/morluto/rea/commit/9b6950373cfaa1a2c0d28287bfadd4a421afb9e9))
* **native:** name the plist selection that works when Info.plist is missing ([5612496](https://github.com/morluto/rea/commit/5612496f6d34a462dcd0fb69fa38337592e2f72d))
* **native:** name the plist selection that works when Info.plist is missing ([a6fdf42](https://github.com/morluto/rea/commit/a6fdf426bd98c8cf7b7a7f589208d3193784062f))
* **native:** refuse truncated executable headers at target admission ([d39a450](https://github.com/morluto/rea/commit/d39a450bdfac425962c3a6a6f47b45600057a230))
* **native:** refuse truncated executable headers at target admission ([0b04d38](https://github.com/morluto/rea/commit/0b04d384cca4f22f271d60bcfe67f79cab89c8de)), closes [#1189](https://github.com/morluto/rea/issues/1189)
* **process:** apply one timeout rule to both execFileOutput modes ([3d32819](https://github.com/morluto/rea/commit/3d328193d69a63a355644c51bfb70f524d99bca9))
* **process:** await cleanup on CLI and MCP cancellation ([f6fe575](https://github.com/morluto/rea/commit/f6fe575094658e99ced78d45f385633fbfaaae32))
* **process:** keep ports before a chunk-final period ([184ed97](https://github.com/morluto/rea/commit/184ed970b9021552a5454ced20d202d10cabcbb8))
* **process:** localize capture truncation diagnostics ([#1284](https://github.com/morluto/rea/issues/1284)) ([33bf585](https://github.com/morluto/rea/commit/33bf585185ffcaea63d658e2d3145c900a680485))
* **process:** normalize ports that end a sentence ([098d769](https://github.com/morluto/rea/commit/098d76900effdbc682b0f97bcde7f8711380ecea))
* **process:** normalize ports that end a sentence ([db98a51](https://github.com/morluto/rea/commit/db98a51dd1750b09b3905e18efac526f7ebf90f7))
* **process:** preserve numeric output and original PTY evidence ([c5c75c3](https://github.com/morluto/rea/commit/c5c75c38c3a4ff0153513b8f8ad600d8a5bacc09))
* **process:** preserve numeric output and original PTY evidence ([00d8e44](https://github.com/morluto/rea/commit/00d8e44cbf82caa51709c2e0857fbaa69ea329b7))
* **process:** preserve unknown filesystem absence in partial captures ([c8544b1](https://github.com/morluto/rea/commit/c8544b1574a32838da6d4ed40f2b72582edb60dd))
* **process:** refuse malformed timeouts for stoppable commands ([136d4aa](https://github.com/morluto/rea/commit/136d4aab18d822f0f908096b8acfac556ef1873b))
* **process:** refuse malformed timeouts for stoppable commands ([59c91c8](https://github.com/morluto/rea/commit/59c91c88fe88210b4b22b9f1365a16567513da4a))
* **process:** require current captures and preserve cleanup failures ([2a77469](https://github.com/morluto/rea/commit/2a7746998d47446c4db6d4f524e0f183d6803f3f))
* **process:** retain known events from incomplete captures ([5eb0049](https://github.com/morluto/rea/commit/5eb0049a9f502b404f30e48c3fe3430a942bb0b5))
* **process:** stop cancelled Swift helper builds before removing their files ([cf41561](https://github.com/morluto/rea/commit/cf415619cadcfcb18cda59a54b26c9d164f750a4))
* **process:** stop cancelled Swift helper builds before removing their files ([c717204](https://github.com/morluto/rea/commit/c7172047951e7dbb9df58b57ff1b43ac9bd47909)), closes [#1173](https://github.com/morluto/rea/issues/1173)
* **process:** stop timed-out commands with the caller's stop signal ([4b38d18](https://github.com/morluto/rea/commit/4b38d1899566089d19b9fd137202f7d86b62fc6f))
* **process:** stop timed-out commands with the caller's stop signal ([063de50](https://github.com/morluto/rea/commit/063de5014f19e85c38b6bec5984de4f38e71adaa))
* **process:** treat non-ASCII letters as port continuations ([ad813e4](https://github.com/morluto/rea/commit/ad813e473b094ab0d3ab30798b7d252e2f4beb94))
* **process:** validate terminal byte totals against retained frames ([69833fb](https://github.com/morluto/rea/commit/69833fb0d0fe9b320b5745a992822342f2c54a92))
* **process:** validate terminal byte totals against retained frames ([39eb058](https://github.com/morluto/rea/commit/39eb0587c95ad028bb961c539ad1f326a1e8d81c))
* **providers:** preserve observations and primary cleanup failures ([0696bde](https://github.com/morluto/rea/commit/0696bde2660bb5d6538d8c01da15aa023312aa9f))
* **reference:** represent unreadable symlink targets explicitly ([b7b4333](https://github.com/morluto/rea/commit/b7b433370310c3ffe33d5027d8393151d5e862da))
* restore caching, preserve failures, and verify fixture claims ([#1211](https://github.com/morluto/rea/issues/1211)) ([27a9cea](https://github.com/morluto/rea/commit/27a9ceade7232c1c9a24dc7d454ae060948183a1))
* **server:** report 2025-era client identity and features in binary_session ([e6abaef](https://github.com/morluto/rea/commit/e6abaefbbc2bd81a6be34cbe71b87be801158c16))
* **server:** report 2025-era client identity and features in binary_session ([b8312fa](https://github.com/morluto/rea/commit/b8312fa8d184ba9f422d1f5592fb41e49811544a)), closes [#1167](https://github.com/morluto/rea/issues/1167)
* **session:** require an open target for session-bound native and artifact tools ([d8e314c](https://github.com/morluto/rea/commit/d8e314cb24e7a4a494347e45474234e0aad74ad1))
* **session:** require an open target for session-bound native and artifact tools ([cf77d07](https://github.com/morluto/rea/commit/cf77d073fc06ab95ce4181c30d68b1346e990b64)), closes [#1166](https://github.com/morluto/rea/issues/1166)
* **session:** retain failed provider cleanup for lifecycle retries ([#1260](https://github.com/morluto/rea/issues/1260)) ([24a3aa0](https://github.com/morluto/rea/commit/24a3aa08d1f69e25b441f086300ba3082d860a35))
* **setup:** keep Codex TOML comments when adding or removing REA ([f5539cf](https://github.com/morluto/rea/commit/f5539cfc2f6c0daf6c275fc97f3351e2cf89b2c3))
* **setup:** keep Codex TOML comments when adding or removing REA ([e9c48a6](https://github.com/morluto/rea/commit/e9c48a61e4c2c05c5b77ef4a815c5b2a65a9337e)), closes [#1163](https://github.com/morluto/rea/issues/1163)
* **setup:** preserve initial backups and Codex comments ([#1204](https://github.com/morluto/rea/issues/1204)) ([6051cb2](https://github.com/morluto/rea/commit/6051cb2c0c723d88dc43ee5ef8a96971bf84d49e))
* **setup:** stop remaining uninstall removals after a client fails ([fd975c7](https://github.com/morluto/rea/commit/fd975c75fa353840e6e887232ca68496cf8705ea))
* **setup:** stop uninstall before removals when a client config is unsafe ([4fb2f3e](https://github.com/morluto/rea/commit/4fb2f3e6ed0233505eada3cddeeff0ea0bfc6fe5))
* **setup:** stop uninstall before removals when a client config is unsafe ([5cc841d](https://github.com/morluto/rea/commit/5cc841d5c154f692bdc257e106cc4b212dc19dc0)), closes [#1164](https://github.com/morluto/rea/issues/1164)
* **snapshot:** report query workflow and Evidence counts separately ([04aef6d](https://github.com/morluto/rea/commit/04aef6df331634238cfc61f320ba4a4e720750a4))
* **snapshot:** report query workflow and Evidence counts separately ([0e77953](https://github.com/morluto/rea/commit/0e779533a9108a550b4d10dcb3920f91c7d48989))
* **website:** clarify Android host and JDK requirements ([5691606](https://github.com/morluto/rea/commit/5691606aa948bddc641e3ecbccf5375a12b65924))
* **website:** identify publication verifier requests ([e6905c1](https://github.com/morluto/rea/commit/e6905c18e09c41e04525fb1a84575483df789204))
* **windows:** retain runtime authority after cleanup failure ([af7a439](https://github.com/morluto/rea/commit/af7a43963351c655eb86197bf52ae798a04e9c22))
* **windows:** retain unsettled jobs for cleanup retry ([76b214e](https://github.com/morluto/rea/commit/76b214e45fa05fe723e216894327185b9b4e6f53))
### Performance Improvements
* **mcp:** share repeated output schema definitions. ([441813c](https://github.com/morluto/rea/commit/441813c0708dbee82ef554c91e973ae02964bf2e))
* **hopper:** resolve string search records once per query ([#1229](https://github.com/morluto/rea/issues/1229)) ([9426c3f](https://github.com/morluto/rea/commit/9426c3f1bbb94711d8b33097e604b9b8ed853b5e))
* **mcp:** reuse input schemas without losing caller guidance ([#1162](https://github.com/morluto/rea/issues/1162)) ([e1afbc1](https://github.com/morluto/rea/commit/e1afbc1914cc7ff90265313e942f34ea4a58a4fc))
* **snapshot:** avoid redundant result copies and serialization ([552634d](https://github.com/morluto/rea/commit/552634d634655a722b2204cfbc4b29f6d442c294))
* **snapshot:** avoid redundant result copies and serialization ([569d2bc](https://github.com/morluto/rea/commit/569d2bc6b9f600114267a4c69f8400393ea1bc2f))
### Code Refactoring
* **domain:** remove obsolete comparison representations ([5510b27](https://github.com/morluto/rea/commit/5510b27d7f863a3df26212fba4a59f8df0da3712))
* enforce canonical evidence and provider boundaries ([63bf914](https://github.com/morluto/rea/commit/63bf91405cf97b114a84f337fb1272d98a267999))
* remove forwarding exports and redundant aliases ([ad59531](https://github.com/morluto/rea/commit/ad59531a960a0c51ef6857fa1391270dda0fa7a4))
* **schemas:** share portable identifier and base64 patterns ([#1227](https://github.com/morluto/rea/issues/1227)) ([954badb](https://github.com/morluto/rea/commit/954badbaaadd24a210190ce3015e40c23d327567))
### Documentation
* add French README translation ([84094af](https://github.com/morluto/rea/commit/84094af54a4e0a6247445e59abff27bc4eca361b))
* add French README translation ([9664b2b](https://github.com/morluto/rea/commit/9664b2b101fe4ac334b2911f9210b50d58d90a89))
* celebrate 30,000 GitHub stars 🎉 ([6987cb0](https://github.com/morluto/rea/commit/6987cb066a5aa5e51480bb06a93a758e6f67cd1e))
* celebrate 30,000 GitHub stars 🎉 ([beca997](https://github.com/morluto/rea/commit/beca9977eb2b18fc7b9844cff0ca70004b6ff21a))
* clarify REA has no affiliated cryptocurrency or token ([#1214](https://github.com/morluto/rea/issues/1214)) ([c2d8146](https://github.com/morluto/rea/commit/c2d8146f94c7533eb87681c2405e93bdfef21b59))
* explain 6.2 contract and saved-data migration ([#1304](https://github.com/morluto/rea/issues/1304)) ([c267e99](https://github.com/morluto/rea/commit/c267e9922751c03df312655ebd623de1b480215c))
* **ghidra:** explain supported heap and CPU controls ([#1278](https://github.com/morluto/rea/issues/1278)) ([0c6852b](https://github.com/morluto/rea/commit/0c6852b392b34319a6fd2c6dffcac10cee51ab94)), closes [#1255](https://github.com/morluto/rea/issues/1255)
* keep the 30k milestone in Star History ([#1217](https://github.com/morluto/rea/issues/1217)) ([c399670](https://github.com/morluto/rea/commit/c399670653884673158f314ed38260aef74da593))
* require focused brittleness cleanup and executable examples ([d6832c3](https://github.com/morluto/rea/commit/d6832c3632847cf3e62d4082b4b8b8d9af554633))
* thank feature request contributors ([9db1fd0](https://github.com/morluto/rea/commit/9db1fd0bd7b17ed1dd21b9c72dabfa4ec6c23a3f))
* **website:** continue the Calculator example with reconstruction ([4578647](https://github.com/morluto/rea/commit/4578647c59a7487bce597a65be6eab8be0412e84))
* **website:** continue the Calculator example with reconstruction ([18a1e8c](https://github.com/morluto/rea/commit/18a1e8cd0efe14c06fd14aabe0c318d2ae390f78))
* **website:** explain SEO maintenance and indexing follow-up ([bb8ff2c](https://github.com/morluto/rea/commit/bb8ff2cfba638ee3a77f951c01e98340c757f525))
* **website:** introduce the worked homepage examples ([f6f5c16](https://github.com/morluto/rea/commit/f6f5c160979624cdcb33928f1a77cf000de403d4))
* **website:** invite deeper projects and reader feedback ([3fb9ffa](https://github.com/morluto/rea/commit/3fb9ffaa4d67685412873cbd3101c64fabbeaff3))
### Tests
* **apple:** verify compiled Mach-O root occurrence facts ([#1300](https://github.com/morluto/rea/issues/1300)) ([4bb4c6f](https://github.com/morluto/rea/commit/4bb4c6fe6d34525c7665a9d38b584b026dd5cdd9))
* **artifacts:** assert asset-catalog target refusal only on macOS ([44d5b4b](https://github.com/morluto/rea/commit/44d5b4b25e0831769c1bd4e5426ef498d0bd3c74))
* **artifacts:** pin per-occurrence roles for direct Mach-O roots and shared bytes ([701d90a](https://github.com/morluto/rea/commit/701d90aba48aaf4f23e1a73e46ebf9968fb85293))
* **artifacts:** pin per-occurrence roles for direct Mach-O roots and shared bytes ([b9e29c5](https://github.com/morluto/rea/commit/b9e29c52d483704c64cd88f87eaa117066288602)), closes [#1234](https://github.com/morluto/rea/issues/1234) [#1235](https://github.com/morluto/rea/issues/1235)
* **artifacts:** read /bin/ls slice layout from its FAT table ([#1223](https://github.com/morluto/rea/issues/1223)) ([c89b3a0](https://github.com/morluto/rea/commit/c89b3a00dce8df36ddb696b59c80e1adc6aceac1))
* **artifacts:** verify compiled Mach-O roles and permissions ([4bb4c6f](https://github.com/morluto/rea/commit/4bb4c6fe6d34525c7665a9d38b584b026dd5cdd9))
* consolidate redundant assertions into boundary workflows ([b71a591](https://github.com/morluto/rea/commit/b71a591a60e3fa5333889e3cf97e05f4ae03c686))
* **ghidra:** preserve selected verification resource limits ([1c3766a](https://github.com/morluto/rea/commit/1c3766a8bcc8a2b6af679cdaa92a73fec42b3372))
* **ghidra:** size oversized annotations for canonical delivery ([1e34197](https://github.com/morluto/rea/commit/1e341973cfad1dbf06755f3a086ffc23d42a723c))
* **ghidra:** use host-native absolute session root fixtures ([1e83d27](https://github.com/morluto/rea/commit/1e83d270c2098b1bcb59591698a257a05d2296fc))
* **javascript:** expect the invalid input_path code in the streamed CLI failure test ([d186ca7](https://github.com/morluto/rea/commit/d186ca7e41928fc2748de2631f5cb43115776571))
* **mcp:** read bundle failures from public error content ([69c3b32](https://github.com/morluto/rea/commit/69c3b32a21c90ea96194fb695f7b58992e8b3714))
* **mcp:** read typed errors in canonical Evidence regressions ([fd46cff](https://github.com/morluto/rea/commit/fd46cff017f0110aaab1216764cf01a71b341766))
* **mcp:** validate public error diagnostics in acceptance workflows ([09058eb](https://github.com/morluto/rea/commit/09058ebc4a68c76d865a92dbddb65811ba8344f7))
* **native:** assert batch identity in production registration ([933fcb3](https://github.com/morluto/rea/commit/933fcb33c1fa1eae109228b89c1200abb7745eb8))
* **native:** build the .app fixture executable with a complete Mach-O header ([facaae8](https://github.com/morluto/rea/commit/facaae865af243656ab8f557aeb42f5909748f2b))
* **process:** check malformed capture choices concurrently ([6020a0b](https://github.com/morluto/rea/commit/6020a0b3683ce16e1441963473605f870c247e29))
* **process:** check malformed capture choices concurrently ([48de11c](https://github.com/morluto/rea/commit/48de11ce2e5af9810fc97d1c2f89df56bf3a3d4d))
* remove duplicate workflow examples and self assertions ([d6d1cd2](https://github.com/morluto/rea/commit/d6d1cd248506015b59a2abdbbb84e3dbd02388fc))
### Continuous Integration
* **website:** allow explicitly requested Pages-only publication ([796b65e](https://github.com/morluto/rea/commit/796b65e1cd15f3cf819396716320db007655ee3f))
* **website:** allow explicitly requested Pages-only publication ([864160d](https://github.com/morluto/rea/commit/864160d8858fad3c0afebff81c31b090a1ebf823))
* **website:** allow explicitly requested Pages-only publication ([#1205](https://github.com/morluto/rea/issues/1205)) ([796b65e](https://github.com/morluto/rea/commit/796b65e1cd15f3cf819396716320db007655ee3f))
* **website:** publish Cloudflare and Pages from one artifact ([761881c](https://github.com/morluto/rea/commit/761881cec33b18d7228bae5e2093e5d44b96ceb1))
## [6.1.0](https://github.com/morluto/rea/compare/rea-agents-6.0.0...rea-agents-6.1.0) (2026-10-09)
@@ -159,6 +634,7 @@
### Performance Improvements
* **mcp:** advertise each tool JSON Schema once per target ([#1059](https://github.com/morluto/rea/issues/1059)) ([5ccb924](https://github.com/morluto/rea/commit/5ccb9241be15bb6a19b99fbbfb27ff3356ba157b))
* **build:** avoid duplicate documentation generation ([c701376](https://github.com/morluto/rea/commit/c701376777212ec9acfd10c97f45b1eaf0c885c6))
* **javascript:** index configuration and module lookups ([67252b2](https://github.com/morluto/rea/commit/67252b23b9e35e9526fed7842dab47a2c7c9fe5f))
* **javascript:** reuse validated immutable graphs ([#1112](https://github.com/morluto/rea/issues/1112)) ([ec6db0f](https://github.com/morluto/rea/commit/ec6db0f0630c4b0b35f0db84c0030784c1aa58a6))
+85 -100
View File
@@ -1,39 +1,30 @@
# Contributing to REA
REA welcomes focused bug fixes, documentation improvements, tests, and reverse-engineering workflow enhancements. Open an issue before a large contract or architecture change so its scope can be agreed before implementation.
REA welcomes focused bug fixes, documentation improvements, tests, and reverse-engineering workflows. For large contract or architecture changes, explain the intended scope and link the relevant issue or design discussion.
## Choosing a contribution
Small contributions are welcome when they solve a concrete problem, including
broken commands, misleading documentation, and missing regression coverage.
Explain the problem, keep the diff focused, and share how you checked the change.
Explain the concrete problem, keep related corrections together, and report
verification and unavailable coverage. Contributions should justify their review
and maintenance cost. Keep cosmetic polish with useful fixes; confusing or
incorrect user instructions warrant standalone corrections. Collect other
cosmetic-only suggestions in an issue rather than separate PRs.
Please avoid standalone cosmetic changes without a clear benefit, such as fixing
a typo in an internal comment, changing capitalization or punctuation in
already-clear prose, or reformatting unchanged code. Include related polish in a
useful fix when practical. For cosmetic-only suggestions, please open an issue
instead of a standalone PR so they can be collected and addressed together.
Corrections to confusing explanations or incorrect instructions are welcome.
Avoid speculative cleanup without a concrete problem to solve. Keep related
corrections in one PR.
Before requesting review, read the final diff and run the relevant checks. Be clear
about anything you couldn't test. You should be able to explain the changes you
submit.
We may decline changes when the benefit doesn't justify the review or maintenance
work.
For capability organization and provider composition, follow the incremental
[migration guide](docs/capability-migration.md). Run `npm run verify:test-discovery`
after adding or moving tests.
For capability organization and provider composition, use the
[architecture map](docs/architecture.mermaid). Production factories in
`src/composition/` construct fresh providers without starting engines or acquiring
targets; optional adapter failures must preserve successful peers. Run
`npm run verify:test-discovery` after adding or moving tests. Resolved import
boundaries are checked by `npm run verify:module-boundaries`, included in lint.
When adding or changing an MCP tool, follow the [tool design guide](docs/tool-design.md) and preserve the canonical contracts and generated catalog.
## Development setup
REA development requires Node.js 24.18.x and npm 11.16.x (pinned toolchain via `nvm use`; the supported runtime range is Node.js ^22.19 || ^24.11 || >=26, as the README badge states). Real-Hopper verification additionally requires either macOS 12+ or an officially supported Linux host (Ubuntu 24.04+, Fedora 41+, 64-bit Arch, or CachyOS) and an installed Hopper application. Linux demo verification uses its own private Xvfb display and does not require a desktop session. Run `nvm use` before installing dependencies.
Use the development toolchain pinned in `.nvmrc` and
`package.json#packageManager`. Run `nvm use` before installing dependencies;
installed-package runtime support is documented in
[installation](docs/installation.md#start-setup).
```bash
npm ci
@@ -42,12 +33,14 @@ npm run check:fast
`npm ci` installs the exact dependencies and prepares the Husky hooks without
building the project. Run `npm run build:cached` when you need the standalone
CLI or MCP server; `npm run build` remains the uncached compiler leaf used by
Turbo. Turbo caches deterministic builds and static checks across Git
worktrees. After a package, lockfile, or managed-skill version change, run
CLI or MCP server; it compiles the runtime and bundles the authored skill.
`npm run build` forces those tasks to rerun. Neither command generates test
catalogs, documentation projections, or managed verification evidence. Turbo
caches deterministic builds and static checks across Git worktrees. After a package, lockfile, or managed-skill version change, run
`npm run metadata:generate` before building.
Keep dependencies flowing inward through the existing domain, contracts, provider, application, server, and adapter layers. Parse unknown values at process and protocol boundaries, model expected failures with `Result`, and preserve the canonical tool inventory defined by `TOOL_CONTRACTS` unless a deliberate contract change updates every verifier, generated catalog artifact, and snapshot. Keep tool discovery complete and report capability- and session-scoped availability through `binary_session`.
Repository invariants live in [AGENTS.md](AGENTS.md). Keep provider-specific
protocols in adapters and shared CLI/MCP workflows in the application layer.
## Documentation website
@@ -73,105 +66,97 @@ The separate GitHub Pages host uses only the manual
## Development feedback and PR verification
For an ordinary edit, run the relevant regression and cached static checks:
Select checks for the behavior changed. For a source edit:
```bash
npm run test:focused -- src/config.test.ts
npm run check:fast
```
`test:local` selects dirty source tests without building; explicit source test
paths run even on a clean tree. `check:changed` adds source tests affected since
the branch merge base with `origin/main`. Use `npm run test:changed -- --base
REVISION` to choose another base. Changed-test selection follows the import
graph and is feedback, not complete correctness evidence. Inspect relevant
boundary and provider behavior explicitly; see [docs/testing.md](docs/testing.md).
`test:local` runs source tests without building. `check:changed` combines cached
static checks with source tests affected since the merge base with `origin/main`.
Import-graph selection can miss runtime registration, bridges, and generated data;
select relevant boundary tests explicitly. See [testing](docs/testing.md#developer-commands)
for commands, test placement, pruning, and real-provider prerequisites.
Before handing off a PR, run the relevant tests, `npm run check`, and
`npm run docs:check` when contracts or generated metadata change. Record which
checks ran. CI owns complete deterministic tests and aggregate coverage. Use
`npm run check:pr` for a deliberate full local gate on broad changes or when
investigating CI failures; it is not required after each edit, rebase, or push.
Packaging, setup, installation, or distribution changes also require
`npm run verify:package` and `npm pack --dry-run`. Provider behavior changes
require the matching real-provider `verify:*` lane.
Before requesting review, run relevant tests and `npm run check`; add
`npm run docs:check` when contracts or generated metadata change. Record the
checks and unavailable coverage. CI owns the full deterministic suite and
coverage. `npm run check:pr` is an optional full local gate for broad changes or
CI diagnosis. Packaging/setup/distribution changes additionally require
`npm run verify:package` and `npm pack --dry-run`; provider changes require the
matching real-provider lane. State which host/provider workflows ran.
`check:fast` runs cached typecheck and lint, reporting diagnostics on failure.
`check` adds formatting, dead-code, and package-metadata freshness checks.
Formatting uses Oxfmt and the committed `.oxfmtrc.json`; generated sources use
the same configuration. Pre-commit formats and lints staged files; pre-push runs
`check:fast`.
`docs:check` builds and validates generated metadata for the current checkout.
The product catalog (`docs/public/product-catalog.json`), portable managed
conformance projections (`docs/verification/managed-conformance-*.json`), and
packaged skill (`skills/`) are ignored build outputs. Edit skill instructions
and references in `skill-src/`; the build adds catalog-dependent metadata to
the packaged copy without rewriting authored files. The generated manifest
commits to that exact packaged skill bundle. It is a portable projection of
the deterministic managed verifier, not a record of optional real-provider runs.
CI validates these outputs and retains them as artifacts instead of pushing
generated-only commits onto feature branches. Reviewed source metadata such as
`src/generatedPackageMetadata.ts` and `docs/error-contract.schema.json` remains
tracked and checked for freshness. Do not commit ignored generated outputs.
The build-generated product catalog contains documented facts and their provider
identity, rather than full runtime schema hashes. The managed skill contains
instructions and inventory metadata; doctor compares its installed files with
the canonical bundle. Schema-only fixes should not change these outputs or the
skill commitment in the conformance manifest. Runtime schema identity remains
available through doctor and `binary_session`.
Real-provider execution remains uncached; deterministic builds use Turbo.
Pre-commit formats and lints staged files; pre-push runs `check:fast`.
Local `npm test` runs every deterministic Vitest project without coverage or
retries. CI runs four coverage shards and merges JUnit and timing reports.
CI cancels superseded PR runs and skips package, Windows, and full test lanes
for documentation-only PRs. Coverage thresholds remain in `vitest.config.ts`.
### Generated files and command ownership
Tests that need a temporary directory must use
`createTestTempDirectory` from `tests/fixtures/temporaryDirectory.ts`. The
helper binds exact-path, awaited cleanup to the current Vitest case, including
failure and timeout completion. Run `npm run verify:test-temp-hygiene` to build
REA, execute the complete suite under a fresh `TMPDIR`, and reject any remaining
REA-owned temporary path. Never add a glob cleanup for shared `/tmp/rea-*`
content.
`docs:generate` prepares documentation and portable managed evidence;
`evidence:generate` prepares only the managed commitment and its runtime/skill
dependencies. The ignored outputs are `docs/public/product-catalog.json`,
`docs/verification/managed-conformance-*.json`, and `skills/`. Edit authored
skill instructions in `.agents/skills/reverse-engineer-anything/`, where Skills
can discover the public bundle directly from a clean checkout. `verify:package`
installs that bundle with Skills 1.7.2 using default repository-root discovery
and checks every installed file, alongside the packaged setup checks.
CI validates generated outputs and retains them as artifacts; do not commit
them. Reviewed source metadata, including
`src/generatedPackageMetadata.ts` and `docs/error-contract.schema.json`, remains
tracked and checked for freshness.
Set `REA_LOG_LEVEL` to `trace`, `debug`, `info`, `warn`, `error`, `fatal`, or
`silent` to control structured JSON diagnostics. MCP mode defaults to `info` and
always writes logs to stderr so the stdio protocol remains intact. One-shot CLI
logging is opt-in and writes to stdout when a level is configured, preserving
machine-readable command output by default. Request arguments, bridge
authentication tokens, and environment data are redacted.
The packaged skill contains instructions and inventory metadata, not runtime
schema hashes. Its conformance commitment covers that exact bundle and portable
verification; it does not attest optional real-provider runs. Schema-only changes
should not alter that commitment. Doctor and `binary_session` expose runtime
schema identity.
Changes that claim real Hopper behavior must also be tested against the
source-owned, digest-bound conformance manifest. The verifier builds the
platform-native fixtures before starting Hopper:
Build/generation commands hold a SQLite transaction around the entire Turbo
graph, including cache restoration. `.cache/rea-command-locks/` databases identify
locks, not stale files; never remove them while commands run. POSIX cancellation
retains process-group ownership until settlement; Windows waits for completion.
Real-provider execution is uncached.
```bash
npm run verify:hopper
```
### Temporary files and diagnostics
On a self-hosted Linux runner with the setup-installed Xvfb dependencies, use:
Tests use `createTestTempDirectory` from `tests/fixtures/temporaryDirectory.ts`
for exact-path, awaited cleanup, including failures and timeouts.
`npm run verify:test-temp-hygiene` runs the suite under a fresh `TMPDIR` and
rejects remaining REA-owned paths. Never glob-clean shared `/tmp/rea-*` content.
```bash
npm run verify:hopper:linux
```
`REA_LOG_LEVEL` selects `trace`, `debug`, `info`, `warn`, `error`, `fatal`, or
`silent`. Logs go to stderr: MCP defaults to `info`, and one-shot CLI logging
is opt-in, so stdout carries only protocol messages and command results.
Request arguments, bridge tokens, and environment data are redacted from
diagnostic logs.
Set `REA_HOPPER_CONFORMANCE_MANIFEST_PATH` only to verify another source-built
manifest. The normal commands use `build/conformance/manifest.json`; generated
fixtures and manifests remain ignored and must not be committed.
## Real Hopper changes
The macOS and Linux real-Hopper workflows remain separate so a successful mock or package test cannot be reported as platform-runtime proof. Pull requests changing setup, launch, bridge, or Hopper behavior must state which real workflows ran and why either workflow was unavailable.
Run `npm run verify:hopper` on a supported macOS host or
`npm run verify:hopper:linux` on the supported Linux demo runner. These build
native fixtures and verify the installed engine through CLI/MCP; package or
simulated-provider checks do not establish engine behavior. See
[real-toolchain verification](docs/testing.md#end-to-end-integration-and-golden-evidence)
for prerequisites and scope, and [Hopper setup](docs/installation.md#hopper)
for supported hosts and unattended startup.
Describe the behavior change and verification performed in the pull request. Never commit binaries, Hopper documents, credentials, `dist/`, `node_modules/`, or local planning artifacts.
Use the default `build/conformance/manifest.json` unless explicitly verifying
another source-built manifest with `REA_HOPPER_CONFORMANCE_MANIFEST_PATH`.
Generated fixtures and manifests remain ignored.
## Maintainer release checklist
Use the [release guide](docs/releasing.md). Main pushes automatically refresh a
Release Please PR with the next version and changelog. Review its migration
notes, wait for the current CI checks to pass, and merge it into main to publish.
The Release workflow validates and tags that merge; both publishers build its
exact SHA. Ordinary main pushes cannot publish packages. An optional manual
`release/VERSION` checkpoint retains explicit preparation and publication.
For grouped release notes with verified contributor thanks, use the repository's
`rea-changelog-update` skill in `.agents/skills/rea-changelog-update/`. Its inventory,
credit checks, and finalization process are described in the release guide.
Keep new implementation commits on main for the next release. The workflow
owns packaged-artifact verification, npm publication, the published CLI/MCP
canary, and MCP Registry publication. Sync manual checkpoint metadata back to
+29 -26
View File
@@ -1,6 +1,6 @@
<div align="center">
**English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
**English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Reverse Engineer Anything
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#what-you-can-analyze)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA launching its analysis bridge inside Hopper while inspecting a native binary" width="1200" />
<br />
<br /><br />
<table aria-label="REA community">
<tr>
@@ -52,7 +52,7 @@ See a feature in an app that you want in your own product? Ask your agent to inv
REA connects your agent to tools for inspecting native binaries, JavaScript and Electron apps, .NET assemblies, and websites. You can also use the same tools from your terminal. Analysis runs locally, and results include the evidence and limitations behind each conclusion.
Setup registers REA with your agent and installs matching workflow instructions. Native analysis can use an existing Hopper or Ghidra installation; setup can optionally install Hopper with approval. Static JavaScript analysis needs neither engine.
Setup registers REA with your agent and installs matching workflow instructions. Native analysis can use an existing Hopper, Ghidra, or IDA installation; setup can optionally install Hopper with approval. Static JavaScript analysis needs no native analysis engine.
> **[Visit the REA website](https://rea.tools/)** for setup instructions, illustrated guides, and real case studies.
@@ -151,13 +151,16 @@ Additional tools and host support depend on the target:
| ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](https://rea.tools/guides/native/) |
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier; [offline EVM guide](docs/evm-bytecode.md) |
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; [application analysis](https://rea.tools/guides/javascript/) |
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](https://rea.tools/guides/browser/) |
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR; mitmdump on Linux for native mitmproxy captures; [capture guide](docs/web-network-captures.md) |
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | Static inspection; [managed-code guide](docs/managed-code-analysis.md) |
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS; [Android guide](docs/android-analysis.md) |
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | None (static only); [managed-code guide](docs/managed-code-analysis.md) |
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
| Android devices | Devices, packages, processes, logs, dumps, screen captures, and APK/file transfers | Caller-supplied adb (emulator or hardware); [ADB guide](docs/adb-device-analysis.md) |
| JEB projects | Engine-backed project units, artifact digests and type/method pseudo-code | A caller-started JEB client serving MCP, selected with REA_JEB_MCP_URL; [JEB guide](docs/jeb-analysis.md) |
| Android resources | Decoded manifest, string tables, locales and version facts | Caller-supplied Apktool launcher; [resource guide](docs/apktool-resource-analysis.md) |
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
| Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
@@ -181,6 +184,8 @@ for features added since the latest npm release.
## Showcases
[![Illustrations of the DX-Ball sound-pan, Notion clipboard-bridge, and TH04 bullet-ring showcases](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: reconstruct a sound-pan calculation
Follow a sound call into its position-to-pan helper, inspect the instructions,
@@ -243,7 +248,7 @@ ask you to choose demo mode or activate your license. See
<details>
<summary><strong>What does installing the skill from skills.sh do?</strong></summary>
The skill supplies investigation instructions for your agent. Use `rea setup`
The skill supplies investigation instructions for your agent. Use `npx rea-agents setup`
to register REA's MCP server and install the matching instructions, then restart
your agent. See [skill-only installation](docs/installation.md#skill-only-installation).
@@ -298,30 +303,16 @@ For exact options, prerequisites and result contracts:
- [Readiness and troubleshooting](docs/installation.md#check-readiness-for-your-task): diagnose one agent or analysis engine.
- [CLI and Evidence](docs/cli.md): commands, provider selection, snapshots, import/export and exit statuses.
- [MCP contracts](docs/mcp-contracts.md) and [agent prompts](docs/mcp-prompts.md): tool results, sessions and guided investigations.
- [Tool catalog](docs/mcp-contracts.md#generated-catalog): build-generated inventory of tools, providers and CLI commands.
- [Tool catalog](docs/mcp-contracts.md#generated-catalog): generated inventory of tools, providers and CLI commands.
- [Roadmap](docs/roadmap.md): planned work and capability trackers.
Report vulnerabilities through [SECURITY.md](SECURITY.md).
## Contributing
We'd love your help with REA! [Open an issue](https://github.com/morluto/rea/issues) to
report a bug or suggest a feature, or [send a pull request](https://github.com/morluto/rea/pulls)
to improve the code or docs.
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
[testing](docs/testing.md) for verification lanes, and the
[architecture map](docs/architecture.mermaid) for the project structure.
## Project links
[Website](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Security](SECURITY.md)
## Star history
🎉 **20,000 GitHub stars — thank you!**
🎉 **60,000 GitHub stars — thank you!**
Thanks to everyone using REA, reporting bugs, testing builds, and contributing fixes.
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -335,6 +326,18 @@ Thanks to everyone using REA, reporting bugs, testing builds, and contributing f
REA provides tools for lawful reverse-engineering research, analysis, and reconstruction. You are responsible for obtaining any required authorization and complying with applicable laws. The project does not endorse illegal or unauthorized use.
REA is an open-source software project. We have not issued or endorsed any cryptocurrency or token. Tokens using the REA name are not affiliated with the project.
## Contributing
We'd love your help with REA! [Open an issue](https://github.com/morluto/rea/issues) to
report a bug or suggest a feature, or [send a pull request](https://github.com/morluto/rea/pulls)
to improve the code or docs.
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
[testing](docs/testing.md) for verification lanes, and the
[architecture map](docs/architecture.mermaid) for the project structure.
## License
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · **العربية** · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · **العربية** · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: هندسة عكسية لأي شيء
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA يشغّل جسر التحليل داخل Hopper لفحص ملف ثنائي للشيفرة الأصلية" width="1200" />
<br />
<br /><br />
<table aria-label="مجتمع REA">
<tr>
@@ -135,13 +135,16 @@ npx rea-agents@latest setup
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| الملفات الثنائية للشيفرة الأصلية | شيفرة شبه برمجية، وتعليمات تجميع، وسلاسل نصية، ورموز، واستدعاءات، ومراجع | Hopper أو Ghidra أو IDA؛ [تحليل الشيفرة الأصلية](https://rea.tools/guides/native/) |
| بنية ELF دون تشغيل | الأقسام والمقاطع والرموز ومعلومات إعادة التموضع الأصلية، وآليات الحماية المحتملة المستدلّ عليها بالفحص الثابت | pwntools يوفّره المستدعي على Linux x64؛ [تشخيص الملفات الثنائية](docs/binary-diagnostics.md) |
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا؛ [دليل EVM دون تشغيل](docs/evm-bytecode.md) |
| أعطال Linux المسجّلة | سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة | pwntools يوفّره المستدعي؛ GDB/pwndbg اختياريان؛ [الأعطال المسجّلة](docs/recorded-crashes.md) |
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا على Linux x64؛ [دليل EVM دون تشغيل](docs/evm-bytecode.md) |
| أعطال Linux المسجّلة | سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة | pwntools يوفّره المستدعي على Linux x64؛ GDB/pwndbg اختياريان؛ [الأعطال المسجّلة](docs/recorded-crashes.md) |
| JavaScript / Electron | الوحدات، وعمليات الاستيراد، وخرائط المصدر، والمسارات، وIPC، وعلاقات إضافات الشيفرة الأصلية | Node.js وnpm؛ [تحليل التطبيقات](https://rea.tools/guides/javascript/) |
| المواقع | بنية الصفحة، والسكربتات، وملاحظات الشبكة، ولقطات الشاشة المطلوبة | متصفح من عائلة Chrome؛ [تحليل المتصفح](https://rea.tools/guides/browser/) |
| تسجيلات الشبكة المحفوظة | الطلبات، والاستجابات، ومحتويات الحمولة المتاحة، ومواضعها في المصدر | HAR؛ وmitmdump على Linux لتسجيلات mitmproxy بصيغتها الأصلية؛ [دليل تسجيلات الشبكة](docs/web-network-captures.md) |
| تجميعات .NET | البيانات الوصفية، وتعليمات CIL، واعتماديات الشيفرة الأصلية المعلنة، ومقارنات البناء | فحص ثابت؛ [دليل الشيفرة المُدارة](docs/managed-code-analysis.md) |
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS؛ [دليل Android](docs/android-analysis.md) |
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS/Windows x64؛ [دليل Android](docs/android-analysis.md) |
| أجهزة Android | الأجهزة والحزم والعمليات والسجلات والدامبات ولقطات الشاشة ونقل APK/الملفات | adb يوفّره المُستدعي (محاكي أو جهاز)؛ [دليل ADB](docs/adb-device-analysis.md) |
| مشاريع JEB | وحدات المشروع من المحرك وبصمات المصنّفات والكود الزائف للأنواع/الدوال | عميل JEB يبدأه المُستدعي ويقدّم MCP، ويُختار عبر REA_JEB_MCP_URL؛ [دليل JEB](docs/jeb-analysis.md) |
| موارد Android | البيان المفكوك الترميز وجداول السلاسل واللغات وحقائق الإصدار | مُشغّل Apktool يوفّره المُستدعي؛ [دليل الموارد](docs/apktool-resource-analysis.md) |
| البرامج الثابتة | المناطق، ونتائج الاستخراج، وما يُمرّر إلى تحليل الشيفرة الأصلية | Binwalk / Unblob على Linux؛ [دليل البرامج الثابتة](docs/firmware-analysis.md) |
| الحزم والموارد | قوائم الملفات، والبصمات، وملفات plist، وبنية حزم Apple، والموارد المستخرجة | [دليل تحليل الملفات وJavaScript](docs/javascript-artifact-reconstruction.md)، [تطبيقات Apple](docs/apple-application-analysis.md) |
| سلوك العمليات | مخرجات الطرفية، والتفاعلات، وملاحظات الخروج ونظام الملفات، ومقارنات التشغيل | Linux/macOS مع PTY أصلي؛ [تسجيل سلوك العمليات](docs/process-capture.md) |
@@ -154,6 +157,8 @@ npx rea-agents@latest setup
## دراسات الحالة
[![رسوم توضيحية لأمثلة توزيع الصوت في DX-Ball وجسر الحافظة في Notion وحلقة الطلقات في TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: إعادة بناء حساب توزيع الصوت بين القناتين
تتبّع استدعاء صوت إلى الدالة المساعدة التي تحوّل الموضع إلى توزيع بين القناتين، وافحص التعليمات، وحوّل الشيفرة شبه البرمجية غير المكتملة إلى C. تجتاز إعادة البناء 3,205 حالات اختبار على x86 الأصلي، وتعيد إنتاج جميع بايتات الدالة المترجمة البالغ عددها 63 بايتًا.
@@ -202,7 +207,7 @@ npx rea-agents@latest setup
<details>
<summary><strong>ماذا يفعل تثبيت المهارة من skills.sh؟</strong></summary>
توفّر المهارة تعليمات الاستقصاء لوكيلك. استخدم `rea setup` لتسجيل خادم MCP الخاص بـ REA وتثبيت التعليمات المطابقة، ثم أعد تشغيل وكيلك. راجع [تثبيت المهارة وحدها](docs/installation.md#skill-only-installation).
توفّر المهارة تعليمات الاستقصاء لوكيلك. استخدم `npx rea-agents setup` لتسجيل خادم MCP الخاص بـ REA وتثبيت التعليمات المطابقة، ثم أعد تشغيل وكيلك. راجع [تثبيت المهارة وحدها](docs/installation.md#skill-only-installation).
</details>
@@ -254,21 +259,11 @@ npx rea-agents@latest setup
أبلغ عن الثغرات وفق [SECURITY.md](SECURITY.md).
## المساهمة
نرحّب بمساعدتك في تطوير REA! [افتح issue](https://github.com/morluto/rea/issues) للإبلاغ عن خطأ أو اقتراح ميزة، أو [أرسل pull request](https://github.com/morluto/rea/pulls) لتحسين الشيفرة أو التوثيق.
راجع [CONTRIBUTING.md](CONTRIBUTING.md) لإعداد بيئة التطوير والفحوص، و[دليل الاختبار](docs/testing.md) لمسارات التحقق، و[خريطة البنية](docs/architecture.mermaid) لهيكل المشروع.
## روابط المشروع
[الموقع](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [الأمان](SECURITY.md)
## سجل النجوم
🎉 **20,000 نجمة على GitHub — شكرًا لكم!**
🎉 **50,000 نجمة على GitHub — شكرًا لكم!**
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -282,6 +277,12 @@ npx rea-agents@latest setup
يوفّر REA أدوات لأبحاث الهندسة العكسية والتحليل وإعادة البناء المشروعة. أنت مسؤول عن الحصول على أي تفويض مطلوب والالتزام بالقوانين المعمول بها. لا يؤيد المشروع الاستخدام غير القانوني أو غير المصرّح به.
## المساهمة
نرحّب بمساعدتك في تطوير REA! [افتح issue](https://github.com/morluto/rea/issues) للإبلاغ عن خطأ أو اقتراح ميزة، أو [أرسل pull request](https://github.com/morluto/rea/pulls) لتحسين الشيفرة أو التوثيق.
راجع [CONTRIBUTING.md](CONTRIBUTING.md) لإعداد بيئة التطوير والفحوص، و[دليل الاختبار](docs/testing.md) لمسارات التحقق، و[خريطة البنية](docs/architecture.mermaid) لهيكل المشروع.
## الترخيص
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · **Deutsch** · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · **Deutsch** · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Alles reverse-engineeren
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA startet seine Analysebrücke in Hopper und untersucht eine native Binärdatei" width="1200" />
<br />
<br /><br />
<table aria-label="REA-Community">
<tr>
@@ -135,13 +135,16 @@ REA benötigt Node.js 22.x (>=22.19), 24.x (>=24.11) oder 26+ sowie npm. Zusätz
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Native Binärdateien | Pseudocode, Assemblercode, Zeichenketten, Symbole, Aufrufe und Verweise | Hopper, Ghidra oder IDA; [native Analyse](https://rea.tools/guides/native/) |
| Offline-ELF-Struktur | Sektionen, Segmente, ursprüngliche Symbole/Relokationen und mögliche Schutzmaßnahmen aus statischer Analyse | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; [Binärdiagnostik](docs/binary-diagnostics.md) |
| EVM-Bytecode | Dispatch-Selektoren, Byte-Offsets, abgeleitete Argumente und Veränderbarkeit des Zustands | Lokale Eingabe mit Rohbytes oder Hexdarstellung; [Offline-EVM-Leitfaden](docs/evm-bytecode.md) |
| Aufgezeichnete Linux-Abstürze | Unverarbeitete Note-Einträge, Register/Signale aller aufgezeichneten Threads und optionale Zuordnungskandidaten | Vom Aufrufer bereitgestelltes pwntools; optional GDB/pwndbg; [aufgezeichnete Abstürze](docs/recorded-crashes.md) |
| EVM-Bytecode | Dispatch-Selektoren, Byte-Offsets, abgeleitete Argumente und Veränderbarkeit des Zustands | Lokale Eingabe mit Rohbytes oder Hexdarstellung unter Linux x64; [Offline-EVM-Leitfaden](docs/evm-bytecode.md) |
| Aufgezeichnete Linux-Abstürze | Unverarbeitete Note-Einträge, Register/Signale aller aufgezeichneten Threads und optionale Zuordnungskandidaten | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; optional GDB/pwndbg; [aufgezeichnete Abstürze](docs/recorded-crashes.md) |
| JavaScript / Electron | Module, Imports, Source Maps, Routen, IPC und Beziehungen zu nativen Add-ons | Node.js und npm; [Anwendungsanalyse](https://rea.tools/guides/javascript/) |
| Websites | Seitenstruktur, Skripte, Netzwerkbeobachtungen und angeforderte Screenshots | Ein Browser aus der Chrome-Familie; [Browseranalyse](https://rea.tools/guides/browser/) |
| Gespeicherte Netzwerkaufzeichnungen | Anfragen, Antworten, zugängliche Nutzdaten und Quellpositionen | HAR; mitmdump unter Linux für Aufzeichnungen im nativen mitmproxy-Format; [Leitfaden zu Netzwerkaufzeichnungen](docs/web-network-captures.md) |
| .NET-Assemblies | Metadaten, CIL-Anweisungen, deklarierte native Abhängigkeiten und Build-Vergleiche | Statische Untersuchung; [Leitfaden für verwalteten Code](docs/managed-code-analysis.md) |
| Android-APKs | Manifest-Deklarationen, Klassen, dekompilierte Methoden und Verweise | JADX ohne grafische Oberfläche und ein vollständiges JDK unter Linux/macOS; [Android-Leitfaden](docs/android-analysis.md) |
| Android-APKs | Manifest-Deklarationen, Klassen, dekompilierte Methoden und Verweise | JADX ohne grafische Oberfläche und ein vollständiges JDK unter Linux/macOS/Windows x64; [Android-Leitfaden](docs/android-analysis.md) |
| Android-Geräte | Geräte, Pakete, Prozesse, Logs, Dumps, Bildschirmaufnahmen sowie APK- und Dateiübertragungen | Vom Aufrufer bereitgestelltes adb (Emulator oder Gerät); [ADB-Leitfaden](docs/adb-device-analysis.md) |
| JEB-Projekte | Engine-gestützte Projekteinheiten, Artefakt-Prüfsummen und Pseudokode von Typen/Methoden | Ein vom Aufrufer gestarteter JEB-Client mit MCP, ausgewählt über REA_JEB_MCP_URL; [JEB-Leitfaden](docs/jeb-analysis.md) |
| Android-Ressourcen | Dekodiertes Manifest, String-Tabellen, Sprachen und Versionsfakten | Vom Aufrufer bereitgestellter Apktool-Starter; [Ressourcen-Leitfaden](docs/apktool-resource-analysis.md) |
| Firmware | Bereiche, Extraktionsergebnisse und Übergaben an die native Analyse | Binwalk / Unblob unter Linux; [Firmware-Leitfaden](docs/firmware-analysis.md) |
| Pakete und Ressourcen | Dateiinventare, Hashwerte, plists, Aufbau von Apple-Bundles und extrahierte Ressourcen | [Artefakt- und JavaScript-Leitfaden](docs/javascript-artifact-reconstruction.md), [Apple-Anwendungen](docs/apple-application-analysis.md) |
| Prozessverhalten | Terminalausgabe, Interaktionen, Beobachtungen zu Prozessende und Dateisystem sowie Laufvergleiche | Linux/macOS mit nativer PTY; [Prozessaufzeichnung](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Native Formate und unterstützte Hostsysteme unterscheiden sich je nach Provider
## Fallstudien
[![Illustrationen der Fallstudien zu DX-Balls Klangbalance, Notions Zwischenablage-Brücke und TH04s Geschossring](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: Eine Stereo-Panning-Berechnung rekonstruieren
Verfolge einen Sound-Aufruf zur Hilfsfunktion, die Positionen in Panning-Werte umrechnet, untersuche die Anweisungen und überführe unvollständigen Pseudocode in C. Die Rekonstruktion besteht 3.205 Tests mit dem ursprünglichen x86-Code und reproduziert alle 63 Bytes der kompilierten Funktion.
@@ -200,7 +205,7 @@ REA startet Hopper, wenn eine Operation es benötigt. Unter macOS kann beim erst
<details>
<summary><strong>Was bewirkt die Installation des Skills über skills.sh?</strong></summary>
Der Skill stellt Untersuchungsanweisungen für deinen Agenten bereit. Verwende `rea setup`, um den MCP-Server von REA zu registrieren und passende Anweisungen zu installieren. Starte deinen Agenten anschließend neu. Siehe [Installation nur des Skills](docs/installation.md#skill-only-installation).
Der Skill stellt Untersuchungsanweisungen für deinen Agenten bereit. Verwende `npx rea-agents setup`, um den MCP-Server von REA zu registrieren und passende Anweisungen zu installieren. Starte deinen Agenten anschließend neu. Siehe [Installation nur des Skills](docs/installation.md#skill-only-installation).
</details>
@@ -252,21 +257,11 @@ Beginne mit den [praxisnahen Anleitungen](https://rea.tools/guides/) auf der Web
Melde Sicherheitslücken gemäß [SECURITY.md](SECURITY.md).
## Mitwirken
Wir freuen uns über deine Hilfe bei REA! [Öffne ein Issue](https://github.com/morluto/rea/issues), um einen Fehler zu melden oder eine Funktion vorzuschlagen, oder [sende einen Pull Request](https://github.com/morluto/rea/pulls), um Code oder Dokumentation zu verbessern.
Die Entwicklungsumgebung und Prüfungen beschreibt [CONTRIBUTING.md](CONTRIBUTING.md), die Verifikationspfade der [Testleitfaden](docs/testing.md) und die Projektstruktur die [Architekturübersicht](docs/architecture.mermaid).
## Projektlinks
[Website](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Sicherheit](SECURITY.md)
## Sternverlauf
🎉 **20.000 GitHub-Sterne – vielen Dank!**
🎉 **50.000 GitHub-Sterne – vielen Dank!**
Danke an alle, die REA nutzen, Fehler melden, Builds testen und Fehlerbehebungen beitragen.
Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds testen und Fehlerbehebungen beitragen.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ Danke an alle, die REA nutzen, Fehler melden, Builds testen und Fehlerbehebungen
REA stellt Werkzeuge für rechtmäßige Reverse-Engineering-Forschung, Analyse und Rekonstruktion bereit. Du bist dafür verantwortlich, erforderliche Genehmigungen einzuholen und geltendes Recht einzuhalten. Das Projekt unterstützt keine rechtswidrige oder unbefugte Nutzung.
## Mitwirken
Wir freuen uns über deine Hilfe bei REA! [Öffne ein Issue](https://github.com/morluto/rea/issues), um einen Fehler zu melden oder eine Funktion vorzuschlagen, oder [sende einen Pull Request](https://github.com/morluto/rea/pulls), um Code oder Dokumentation zu verbessern.
Die Entwicklungsumgebung und Prüfungen beschreibt [CONTRIBUTING.md](CONTRIBUTING.md), die Verifikationspfade der [Testleitfaden](docs/testing.md) und die Projektstruktur die [Architekturübersicht](docs/architecture.mermaid).
## Lizenz
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · **Español** · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · **Español** · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Ingeniería inversa de cualquier cosa
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA inicia su puente de análisis dentro de Hopper mientras inspecciona un binario nativo" width="1200" />
<br />
<br /><br />
<table aria-label="Comunidad REA">
<tr>
@@ -135,13 +135,16 @@ REA requiere Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, además de npm. Las h
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Binarios nativos | Pseudocódigo, ensamblador, cadenas, símbolos, llamadas y referencias | Hopper, Ghidra o IDA; [análisis nativo](https://rea.tools/guides/native/) |
| Estructura ELF sin ejecutar | Secciones, segmentos, símbolos/reubicaciones originales y posibles medidas de mitigación detectadas mediante análisis estático | pwntools proporcionado por quien llama, en Linux x64; [diagnóstico de binarios](docs/binary-diagnostics.md) |
| Bytecode EVM | Selectores de despacho, desplazamientos en bytes, argumentos inferidos y mutabilidad | Entrada local con bytes sin procesar o representación hexadecimal; [guía de EVM sin ejecutar](docs/evm-bytecode.md) |
| Fallos de Linux registrados | Registros note sin procesar, registros/señales de cada hilo registrado y posibles correspondencias de memoria opcionales | pwntools proporcionado por quien llama; GDB/pwndbg opcionales; [fallos registrados](docs/recorded-crashes.md) |
| Bytecode EVM | Selectores de despacho, desplazamientos en bytes, argumentos inferidos y mutabilidad | Entrada local con bytes sin procesar o representación hexadecimal, en Linux x64; [guía de EVM sin ejecutar](docs/evm-bytecode.md) |
| Fallos de Linux registrados | Registros note sin procesar, registros/señales de cada hilo registrado y posibles correspondencias de memoria opcionales | pwntools proporcionado por quien llama, en Linux x64; GDB/pwndbg opcionales; [fallos registrados](docs/recorded-crashes.md) |
| JavaScript / Electron | Módulos, importaciones, mapas de código fuente, rutas, IPC y relaciones con complementos nativos | Node.js y npm; [análisis de aplicaciones](https://rea.tools/guides/javascript/) |
| Sitios web | Estructura de la página, scripts, observaciones de red y capturas de pantalla solicitadas | Un navegador de la familia Chrome; [análisis del navegador](https://rea.tools/guides/browser/) |
| Capturas de red guardadas | Solicitudes, respuestas, contenido accesible de las cargas útiles y ubicaciones de origen | HAR; mitmdump en Linux para capturas en formato nativo de mitmproxy; [guía de capturas](docs/web-network-captures.md) |
| Ensamblados .NET | Metadatos, instrucciones CIL, dependencias nativas declaradas y comparaciones de compilaciones | Inspección estática; [guía de código administrado](docs/managed-code-analysis.md) |
| APK de Android | Declaraciones del manifiesto, clases, métodos descompilados y referencias | JADX sin interfaz gráfica y un JDK completo en Linux/macOS; [guía de Android](docs/android-analysis.md) |
| APK de Android | Declaraciones del manifiesto, clases, métodos descompilados y referencias | JADX sin interfaz gráfica y un JDK completo en Linux/macOS/Windows x64; [guía de Android](docs/android-analysis.md) |
| Dispositivos Android | Dispositivos, paquetes, procesos, registros, volcados, capturas de pantalla y transferencias de APK/archivos | adb suministrado por el autor de la llamada (emulador o dispositivo); [guía de ADB](docs/adb-device-analysis.md) |
| Proyectos JEB | Unidades de proyecto del motor, resúmenes de artefactos y pseudocódigo de tipos/métodos | Un cliente JEB iniciado por el autor de la llamada que sirve MCP, seleccionado con REA_JEB_MCP_URL; [guía de JEB](docs/jeb-analysis.md) |
| Recursos de Android | Manifiesto decodificado, tablas de cadenas, idiomas y datos de versión | Lanzador de Apktool suministrado por el autor de la llamada; [guía de recursos](docs/apktool-resource-analysis.md) |
| Firmware | Regiones, resultados de extracción y derivaciones al análisis nativo | Binwalk / Unblob en Linux; [guía de firmware](docs/firmware-analysis.md) |
| Paquetes y recursos | Inventarios de archivos, resúmenes criptográficos, plists, estructura de paquetes de Apple y recursos extraídos | [Guía de artefactos y JavaScript](docs/javascript-artifact-reconstruction.md), [aplicaciones de Apple](docs/apple-application-analysis.md) |
| Comportamiento de procesos | Salida de la terminal, interacciones, observaciones de salida y del sistema de archivos, y comparaciones entre ejecuciones | Linux/macOS con una PTY nativa; [captura de procesos](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Los formatos nativos y los sistemas anfitriones compatibles varían según el pr
## Casos prácticos
[![Ilustraciones de los casos de panoramización de sonido de DX-Ball, el puente del portapapeles de Notion y el anillo de proyectiles de TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: reconstruir un cálculo de panoramización de sonido
Sigue una llamada de sonido hasta la función auxiliar que convierte la posición en panoramización, inspecciona las instrucciones y transforma el pseudocódigo incompleto en C. La reconstrucción supera 3.205 casos con el x86 original y reproduce los 63 bytes de la función compilada.
@@ -200,7 +205,7 @@ REA inicia Hopper cuando una operación lo necesita. En macOS, puede aparecer un
<details>
<summary><strong>¿Qué hace la instalación de la skill desde skills.sh?</strong></summary>
La skill proporciona instrucciones de investigación a tu agente. Usa `rea setup` para registrar el servidor MCP de REA e instalar las instrucciones correspondientes; después reinicia tu agente. Consulta [instalación solo de la skill](docs/installation.md#skill-only-installation).
La skill proporciona instrucciones de investigación a tu agente. Usa `npx rea-agents setup` para registrar el servidor MCP de REA e instalar las instrucciones correspondientes; después reinicia tu agente. Consulta [instalación solo de la skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,21 +257,11 @@ Empieza con las [guías prácticas](https://rea.tools/guides/) del sitio web. Pa
Informa de vulnerabilidades siguiendo [SECURITY.md](SECURITY.md).
## Contribuir
¡Nos encantaría que ayudaras con REA! [Abre una issue](https://github.com/morluto/rea/issues) para comunicar un error o proponer una función, o [envía una pull request](https://github.com/morluto/rea/pulls) para mejorar el código o la documentación.
Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para preparar el entorno de desarrollo y las comprobaciones, la [guía de pruebas](docs/testing.md) para los procesos de verificación y el [mapa de arquitectura](docs/architecture.mermaid) para la estructura del proyecto.
## Enlaces del proyecto
[Sitio web](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Seguridad](SECURITY.md)
## Historial de estrellas
🎉 **20.000 estrellas en GitHub: ¡gracias!**
🎉 **50.000 estrellas en GitHub: ¡gracias!**
Gracias a quienes usan REA, informan de errores, prueban compilaciones y contribuyen con correcciones.
Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban compilaciones y contribuyen con correcciones.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ Gracias a quienes usan REA, informan de errores, prueban compilaciones y contrib
REA proporciona herramientas para la investigación, el análisis y la reconstrucción mediante ingeniería inversa conforme a la ley. Eres responsable de obtener las autorizaciones necesarias y cumplir las leyes aplicables. El proyecto no respalda usos ilegales ni no autorizados.
## Contribuir
¡Nos encantaría que ayudaras con REA! [Abre una issue](https://github.com/morluto/rea/issues) para comunicar un error o proponer una función, o [envía una pull request](https://github.com/morluto/rea/pulls) para mejorar el código o la documentación.
Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para preparar el entorno de desarrollo y las comprobaciones, la [guía de pruebas](docs/testing.md) para los procesos de verificación y el [mapa de arquitectura](docs/architecture.mermaid) para la estructura del proyecto.
## Licencia
[MIT](LICENSE)
+31 -30
View File
@@ -1,6 +1,6 @@
<div align="center" dir="rtl">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · **فارسی**
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · **فارسی** · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: مهندسی معکوس هر چیزی
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="اجرای پل تحلیل REA در Hopper هنگام بررسی یک فایل باینری بومی" width="1200" />
<br />
<br /><br />
<table aria-label="انجمن REA"><tr><td align="center" width="360"><a href="https://discord.gg/GkcryMnJDM"><img src="docs/assets/discord.svg" height="42" alt="Discord" /><br /><strong>به انجمن مهندسی معکوس بپیوندید</strong></a><br /><sub>دیسکورد · پرسش و پاسخ · نمایش دستاوردها</sub></td></tr></table>
@@ -123,20 +123,23 @@ npx rea-agents@latest setup
REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، به‌همراه npm نیاز دارد. ابزارهای اضافی و پشتیبانی سیستم میزبان به نوع هدف بستگی دارند:
| هدف | خروجی REA | پیش‌نیازها و راهنما |
| --------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| باینری‌های بومی | شبه‌کد، اسمبلی، رشته‌ها، نمادها، فراخوانی‌ها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](https://rea.tools/guides/native/) |
| ساختار ELF آفلاین | بخش‌ها، سگمنت‌ها، نمادها و relocationهای اصلی و گزینه‌های احتمالی کاهش آسیب‌پذیری ایستا | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](docs/binary-diagnostics.md) |
| بایت‌کد EVM | selectorهای dispatch، offsetهای بایتی، آرگومان‌های استنباط‌شده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی؛ [راهنمای EVM آفلاین](docs/evm-bytecode.md) |
| کرش‌های ثبت‌شدهٔ لینوکس | یادداشت‌های خام، رجیسترها/سیگنال‌های تمام threadهای ثبت‌شده و گزینه‌های احتمالی نگاشت | pwntools تأمین‌شده توسط فراخواننده؛ GDB/pwndbg اختیاری؛ [کرش‌های ثبت‌شده](docs/recorded-crashes.md) |
| JavaScript / Electron | ماژول‌ها، importها، source mapها، مسیرها، IPC و ارتباط افزونه‌های بومی | Node.js و npm؛ [تحلیل برنامه](https://rea.tools/guides/javascript/) |
| وب‌سایت‌ها | ساختار صفحه، اسکریپت‌ها، مشاهدات شبکه و اسکرین‌شات‌های درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](https://rea.tools/guides/browser/) |
| داده‌های ضبط‌شدهٔ شبکه | درخواست‌ها، پاسخ‌ها، payloadهای آشکارشده و مکان آن‌ها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبط‌های بومی mitmproxy؛ [راهنمای ضبط شبکه](docs/web-network-captures.md) |
| اسمبلی‌های .NET | فراداده، دستورالعمل‌های CIL، وابستگی‌های بومی اعلام‌شده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریت‌شده](docs/managed-code-analysis.md) |
| فایل‌های APK اندروید | تعاریف Manifest، کلاس‌ها، متدهای دیکامپایل‌شده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS؛ [راهنمای اندروید](docs/android-analysis.md) |
| Firmware | ناحیه‌ها، نتایج استخراج و تحویل به ابزارهای تحلیل بومی | Binwalk / Unblob در لینوکس؛ [راهنمای Firmware](docs/firmware-analysis.md) |
| بسته‌ها و منابع | فهرست فایل‌ها، digestها، فایل‌های plist، ساختار bundle اپل و منابع استخراج‌شده | [راهنمای آرتیفکت و JavaScript](docs/javascript-artifact-reconstruction.md)، [برنامه‌های اپل](docs/apple-application-analysis.md) |
| رفتار فرایند | خروجی ترمینال، تعاملات، وضعیت خروج، مشاهدات سیستم فایل و مقایسهٔ اجراها | Linux/macOS با PTY بومی؛ [ضبط فرایند](docs/process-capture.md) |
| هدف | خروجی REA | پیش‌نیازها و راهنما |
| --------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| باینری‌های بومی | شبه‌کد، اسمبلی، رشته‌ها، نمادها، فراخوانی‌ها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](https://rea.tools/guides/native/) |
| ساختار ELF آفلاین | بخش‌ها، سگمنت‌ها، نمادها و relocationهای اصلی و گزینه‌های احتمالی کاهش آسیب‌پذیری ایستا | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](docs/binary-diagnostics.md) |
| بایت‌کد EVM | selectorهای dispatch، offsetهای بایتی، آرگومان‌های استنباط‌شده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](docs/evm-bytecode.md) |
| کرش‌های ثبت‌شدهٔ لینوکس | یادداشت‌های خام، رجیسترها/سیگنال‌های تمام threadهای ثبت‌شده و گزینه‌های احتمالی نگاشت | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ GDB/pwndbg اختیاری؛ [کرش‌های ثبت‌شده](docs/recorded-crashes.md) |
| JavaScript / Electron | ماژول‌ها، importها، source mapها، مسیرها، IPC و ارتباط افزونه‌های بومی | Node.js و npm؛ [تحلیل برنامه](https://rea.tools/guides/javascript/) |
| وب‌سایت‌ها | ساختار صفحه، اسکریپت‌ها، مشاهدات شبکه و اسکرین‌شات‌های درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](https://rea.tools/guides/browser/) |
| داده‌های ضبط‌شدهٔ شبکه | درخواست‌ها، پاسخ‌ها، payloadهای آشکارشده و مکان آن‌ها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبط‌های بومی mitmproxy؛ [راهنمای ضبط شبکه](docs/web-network-captures.md) |
| اسمبلی‌های .NET | فراداده، دستورالعمل‌های CIL، وابستگی‌های بومی اعلام‌شده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریت‌شده](docs/managed-code-analysis.md) |
| فایل‌های APK اندروید | تعاریف Manifest، کلاس‌ها، متدهای دیکامپایل‌شده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS/Windows x64؛ [راهنمای اندروید](docs/android-analysis.md) |
| دستگاه‌های اندروید | دستگاه‌ها، بسته‌ها، فرایندها، لاگ‌ها، دامپ‌ها، اسکرین‌شات‌ها و انتقال APK/فایل | adb تأمین‌شده توسط فراخوان‌کننده (شبیه‌ساز یا دستگاه)؛ [راهنمای ADB](docs/adb-device-analysis.md) |
| پروژه‌های JEB | واحدهای پروژه از موتور، هش‌های مصنوع و شبه‌کدِ نوع/متد | یک کلاینت JEB که توسط فراخوان‌کننده اجرا شده و MCP ارائه می‌دهد و با REA_JEB_MCP_URL انتخاب می‌شود؛ [راهنمای JEB](docs/jeb-analysis.md) |
| منابع اندروید | مانیفست رمزگشایی‌شده، جداول رشته‌ها، زبان‌ها و اطلاعات نسخه | راه‌انداز Apktool تأمین‌شده توسط فراخوان‌کننده؛ [راهنمای منابع](docs/apktool-resource-analysis.md) |
| Firmware | ناحیه‌ها، نتایج استخراج و تحویل به ابزارهای تحلیل بومی | Binwalk / Unblob در لینوکس؛ [راهنمای Firmware](docs/firmware-analysis.md) |
| بسته‌ها و منابع | فهرست فایل‌ها، digestها، فایل‌های plist، ساختار bundle اپل و منابع استخراج‌شده | [راهنمای آرتیفکت و JavaScript](docs/javascript-artifact-reconstruction.md)، [برنامه‌های اپل](docs/apple-application-analysis.md) |
| رفتار فرایند | خروجی ترمینال، تعاملات، وضعیت خروج، مشاهدات سیستم فایل و مقایسهٔ اجراها | Linux/macOS با PTY بومی؛ [ضبط فرایند](docs/process-capture.md) |
بررسی ایستای JavaScript و .NET فایل‌های ارائه‌شده را بدون اجرای برنامه می‌خواند. ضبط زمان اجرا، هدف انتخاب‌شده را با مجوزهای کاربری شما اجرا می‌کند یا با آن تعامل دارد؛ آثار این عملیات در راهنمای مربوط به هر نوع ضبط توضیح داده شده‌اند.
@@ -146,6 +149,8 @@ REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، به‌همراه np
## نمونه‌های عملی
[![تصویرهایی از نمونه‌های پنینگ صدای DX-Ball، پل کلیپ‌بورد Notion و حلقهٔ گلوله‌های TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: بازسازی محاسبهٔ موقعیت استریوی صدا
یک فراخوانی صوتی را تا تابع کمکی تبدیل موقعیت به pan دنبال کنید، دستورالعمل‌ها را بررسی کنید و شبه‌کد ناقص را به C تبدیل کنید. بازسازی حاصل، هر ۳٬۲۰۵ مورد آزمایش x86 اصلی را با موفقیت پشت سر می‌گذارد و هر ۶۳ بایت تابع کامپایل‌شده را دقیقاً بازتولید می‌کند.
@@ -188,7 +193,7 @@ REA زمانی که عملیاتی به Hopper نیاز داشته باشد آن
<details><summary><strong>نصب skill از skills.sh چه کاری انجام می‌دهد؟</strong></summary>
این skill دستورالعمل‌های بررسی را برای ایجنت فراهم می‌کند. برای ثبت سرور MCP مربوط به REA و نصب دستورالعمل‌های متناظر، `rea setup` را اجرا کنید و سپس ایجنت را مجدداً راه‌اندازی کنید. [نصب مستقل skill](docs/installation.md#skill-only-installation) را ببینید.
این skill دستورالعمل‌های بررسی را برای ایجنت فراهم می‌کند. برای ثبت سرور MCP مربوط به REA و نصب دستورالعمل‌های متناظر، `npx rea-agents setup` را اجرا کنید و سپس ایجنت را مجدداً راه‌اندازی کنید. [نصب مستقل skill](docs/installation.md#skill-only-installation) را ببینید.
</details>
@@ -237,21 +242,11 @@ npx rea-agents@latest setup
آسیب‌پذیری‌ها را از طریق [SECURITY.md](SECURITY.md) گزارش کنید.
## مشارکت
از کمک شما به REA استقبال می‌کنیم! برای گزارش خطا یا پیشنهاد قابلیت، یک [issue باز کنید](https://github.com/morluto/rea/issues) یا برای بهبود کد و مستندات [pull request بفرستید](https://github.com/morluto/rea/pulls).
برای راه‌اندازی محیط توسعه و بررسی‌ها، [CONTRIBUTING.md](CONTRIBUTING.md)، برای مراحل اعتبارسنجی [آزمایش‌ها](docs/testing.md) و برای ساختار پروژه [نقشهٔ معماری](docs/architecture.mermaid) را ببینید.
## لینک‌های پروژه
[وب‌سایت](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [امنیت](SECURITY.md)
## تاریخچهٔ ستاره‌ها
🎉 **۲۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
🎉 **۵۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
از همهٔ کسانی که از REA استفاده می‌کنند، خطاها را گزارش می‌دهند، buildها را آزمایش می‌کنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
از همهٔ کسانی که از REA استفاده می‌کنند، خطاها را گزارش می‌دهند، قابلیت‌های جدید پیشنهاد می‌کنند، buildها را آزمایش می‌کنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date"><picture><source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date&amp;theme=dark&amp;legend=top-left" /><source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" /><img alt="تاریخچهٔ ستاره‌های GitHub پروژهٔ REA" src="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" /></picture></a>
@@ -259,6 +254,12 @@ npx rea-agents@latest setup
REA ابزارهایی برای پژوهش، تحلیل و بازسازی قانونی در حوزهٔ مهندسی معکوس فراهم می‌کند. مسئولیت دریافت مجوزهای لازم و رعایت قوانین مربوط بر عهدهٔ شماست. این پروژه استفادهٔ غیرقانونی یا بدون مجوز را تأیید نمی‌کند.
## مشارکت
از کمک شما به REA استقبال می‌کنیم! برای گزارش خطا یا پیشنهاد قابلیت، یک [issue باز کنید](https://github.com/morluto/rea/issues) یا برای بهبود کد و مستندات [pull request بفرستید](https://github.com/morluto/rea/pulls).
برای راه‌اندازی محیط توسعه و بررسی‌ها، [CONTRIBUTING.md](CONTRIBUTING.md)، برای مراحل اعتبارسنجی [آزمایش‌ها](docs/testing.md) و برای ساختار پروژه [نقشهٔ معماری](docs/architecture.mermaid) را ببینید.
## مجوز
[MIT](LICENSE)
+287
View File
@@ -0,0 +1,287 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · **Français** · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA : rétro-ingénierie de tout
### Un seul MCP pour la rétro-ingénierie des binaires, des applications et du comportement à l'exécution.
**Repérez une fonctionnalité qui vous plaît. Comprenez son fonctionnement, jusqu'au niveau du binaire.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
**[Site web](https://rea.tools/) · [Guides](https://rea.tools/guides/) · [Études de cas](https://rea.tools/showcase/)**
[Démarrage rapide](#démarrage-rapide) · [Comment fonctionne REA](#comment-fonctionne-rea) · [Ce que vous pouvez analyser](#ce-que-vous-pouvez-analyser) · [Études de cas](#études-de-cas) · [Questions fréquentes](#questions-fréquentes) · [Documentation](#documentation)
<code>npx rea-agents setup</code>
<br />
<img src="docs/assets/rea-hopper-analysis.png" alt="REA lance son pont d'analyse dans Hopper pendant l'inspection d'un binaire natif" width="1200" />
<br /><br />
<table aria-label="REA community">
<tr>
<td align="center" width="360">
<a href="https://discord.gg/GkcryMnJDM">
<img src="docs/assets/discord.svg" height="42" alt="Discord" /><br />
<strong>Rejoignez la communauté de rétro-ingénierie</strong>
</a><br />
<sub>Discord · Questions et réponses · Partage de projets</sub>
</td>
</tr>
</table>
<br />
</div>
---
Vous avez repéré dans une application une fonctionnalité que vous aimeriez avoir dans votre propre produit ? Demandez à votre agent de l'étudier avec REA. Il peut inspecter l'application sans son code source, expliquer le fonctionnement de la fonctionnalité, présenter les preuves et en construire une version pour votre projet.
REA connecte votre agent à des outils d'inspection de binaires natifs, d'applications JavaScript et Electron, d'assemblys .NET et de sites web. Les mêmes outils sont aussi disponibles depuis votre terminal. L'analyse s'exécute localement, et chaque conclusion s'accompagne des preuves et des limites sur lesquelles elle repose.
Setup enregistre REA auprès de votre agent et installe les instructions de workflow correspondantes. L'analyse native peut utiliser une installation existante de Hopper ou de Ghidra ; Setup peut aussi installer Hopper après votre accord. L'analyse statique JavaScript ne nécessite aucun de ces moteurs.
> **[Visitez le site web de REA](https://rea.tools/)** pour les instructions d'installation, des guides illustrés et des études de cas réelles.
## Démarrage rapide
### Configurer votre agent
Une fois Node.js et npm installés, exécutez :
```bash
npx rea-agents setup
```
Choisissez vos agents, vérifiez les modifications proposées et approuvez-les. Setup ajoute le serveur MCP de REA et les instructions de workflow correspondantes, et sauvegarde la configuration existante. Redémarrez ensuite votre agent.
Setup prend en charge Claude Code, Codex, Cursor, Gemini CLI, Grok Build et [d'autres agents](docs/installation.md#supported-agents). Consultez [Installation et configuration](docs/installation.md) pour la configuration des fournisseurs et l'enregistrement MCP manuel.
### Interroger votre agent
```text
Comprends comment fonctionne la recherche dans l'app Notes, montre-moi les preuves
et construis une fonctionnalité similaire pour mon projet.
```
Remplacez Notes par votre application cible et la fonctionnalité que vous voulez comprendre.
### Utiliser le terminal
Inspectez le répertoire extrait ou l'archive ASAR d'une application JavaScript/Electron :
```bash
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
```
Le résultat comprend les modules, les imports, les frontières Electron et les preuves associées. Remplacez le chemin par votre cible, par exemple `"D:/apps/example"` sous Windows.
Pour installer la commande `rea` pour un usage régulier :
```bash
npm install --global rea-agents
rea --help
```
Pour l'analyse native, configurez d'abord un fournisseur. Consultez le [guide CLI et Evidence](docs/cli.md) pour les commandes natives, le choix du fournisseur, les snapshots et l'utilisation dans des scripts.
### Mettre à jour REA
REA évolue rapidement, et les nouvelles versions apportent fréquemment des corrections de bugs. Maintenez votre installation à jour.
Pour une CLI installée avec npm :
```bash
rea update
```
Pour actualiser les enregistrements de vos agents et le skill, exécutez la commande setup affichée par la mise à jour.
Si vous utilisez `npx`, mettez à jour la configuration de votre agent avec :
```bash
npx rea-agents@latest setup
```
Vérifiez les modifications proposées par Setup et redémarrez votre agent. Pour des commandes CLI ponctuelles, utilisez `npx rea-agents@latest` suivi de la commande.
## Comment fonctionne REA
Votre agent appelle REA via MCP pour inspecter la cible et suivre le code pertinent. REA renvoie ses constatations avec les preuves correspondantes. L'agent s'en sert pour poser des questions complémentaires, expliquer le comportement, ou écrire et tester une implémentation. Les commandes CLI utilisent les mêmes workflows.
![Flux d'investigation de REA : votre agent pose une question sur une cible locale, REA l'inspecte et la trace avec des outils d'analyse, et l'agent utilise le code, les références et les inconnues renvoyés pour expliquer, implémenter et tester.](website/public/assets/figures/rea-investigation-flow.svg)
[Ouvrir la figure en taille réelle](website/public/assets/figures/rea-investigation-flow.svg).
<a id="current-status"></a>
## Ce que vous pouvez analyser
REA nécessite Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, ainsi que npm. Les outils supplémentaires et les hôtes pris en charge dépendent de la cible :
| Cible | Ce que REA renvoie | Prérequis et guide |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Binaires natifs | Pseudo-code, assembleur, chaînes, symboles, appels et références | Hopper, Ghidra ou IDA ; [analyse native](https://rea.tools/guides/native/) |
| Structure ELF hors ligne | Sections, segments, symboles et relocations d'origine, et protections statiques candidates | pwntools fourni par l'utilisateur sous Linux x64 ; [diagnostics binaires](docs/binary-diagnostics.md) |
| Bytecode EVM | Sélecteurs de dispatch, offsets en octets, arguments inférés et mutabilité | Fichier local brut ou hexadécimal sous Linux x64 ; [guide EVM hors ligne](docs/evm-bytecode.md) |
| Crashs Linux enregistrés | Notes brutes, registres et signaux de chaque thread enregistré, et correspondances de mappings facultatives | pwntools fourni par l'utilisateur sous Linux x64 ; GDB/pwndbg en option ; [crashs enregistrés](docs/recorded-crashes.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC et relations avec les modules natifs | Node.js et npm ; [analyse d'applications](https://rea.tools/guides/javascript/) |
| Sites web | Structure des pages, scripts, observations réseau et captures d'écran demandées | Un navigateur de la famille Chrome ; [analyse du navigateur](https://rea.tools/guides/browser/) |
| Captures réseau enregistrées | Requêtes, réponses, payloads exposés et emplacements dans le code source | HAR ; mitmdump sous Linux pour les captures mitmproxy natives ; [guide des captures](docs/web-network-captures.md) |
| Assemblys .NET | Métadonnées, instructions CIL, dépendances natives déclarées et comparaisons de builds | Inspection statique ; [guide du code managé](docs/managed-code-analysis.md) |
| APK Android | Déclarations du manifeste, classes, méthodes décompilées et références | JADX headless et un JDK complet sous Linux/macOS/Windows x64 ; [guide Android](docs/android-analysis.md) |
| Appareils Android | Appareils, paquets, processus, journaux, dumps, captures d'écran et transferts d'APK/fichiers | adb fourni par l'appelant (émulateur ou appareil) ; [guide ADB](docs/adb-device-analysis.md) |
| Projets JEB | Unités de projet fournies par le moteur, condensés d'artefacts et pseudo-code de types/méthodes | Un client JEB démarré par l'appelant servant MCP, sélectionné via REA_JEB_MCP_URL ; [guide JEB](docs/jeb-analysis.md) |
| Ressources Android | Manifeste décodé, tables de chaînes, langues et faits de version | Lanceur Apktool fourni par l'appelant ; [guide des ressources](docs/apktool-resource-analysis.md) |
| Firmware | Régions, résultats d'extraction et passage de relais vers l'analyse native | Binwalk / Unblob sous Linux ; [guide firmware](docs/firmware-analysis.md) |
| Paquets et ressources | Inventaires de fichiers, empreintes, plists, anatomie des bundles Apple et ressources extraites | [Guide artefacts et JavaScript](docs/javascript-artifact-reconstruction.md), [applications Apple](docs/apple-application-analysis.md) |
| Comportement des processus | Sortie du terminal, interactions, code de sortie, observations du système de fichiers et comparaisons | Linux/macOS avec un PTY natif ; [capture de processus](docs/process-capture.md) |
L'inspection statique JavaScript et .NET lit les fichiers fournis sans exécuter l'application. La capture à l'exécution lance la cible choisie ou interagit avec elle avec vos permissions utilisateur ; chaque guide d'exécution décrit ses effets.
<a id="choosing-a-deep-analysis-provider"></a>
Les formats natifs et les hôtes pris en charge varient selon le fournisseur. Consultez [la configuration de Hopper et Ghidra](docs/installation.md#hopper), le [guide IDA](docs/ida-provider.md) et [la prise en charge expérimentale de Ghidra sous Windows](docs/windows-ghidra-p0.md). Ghidra prend aussi en charge [l'analyse DOS 16 bits](docs/ghidra-dos.md). Pour les gros binaires, augmentez son délai de démarrage avec `REA_GHIDRA_STARTUP_TIMEOUT_MS`. Pour le choix du fournisseur, consultez le [guide CLI](docs/cli.md#choose-a-provider). Vérifiez la [disponibilité dans les versions publiées](docs/installation.md#released-package-and-main) pour les fonctionnalités ajoutées depuis la dernière version npm.
## Études de cas
[![Illustrations des études sur la spatialisation sonore de DX-Ball, le pont du presse-papiers de Notion et le cercle de projectiles de TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball : reconstruire un calcul de panoramique sonore
Suivez un appel sonore jusqu'à la fonction qui convertit une position en panoramique, inspectez ses instructions et transformez un pseudo-code incomplet en C. La reconstruction réussit 3 205 cas issus du x86 d'origine et reproduit à l'identique les 63 octets de la fonction compilée.
[Lire l'étude de cas](https://rea.tools/showcase/dx-ball/) · [Dépôt de la reconstruction](https://github.com/N0zoM1z0/dx-ball)
### Notion : suivre le pont du presse-papiers d'Electron
Trouvez l'API de presse-papiers du renderer, suivez-la à travers le preload et l'IPC jusqu'au processus principal, puis inspectez le format de presse-papiers enrichi.
[Lire l'étude de cas](https://rea.tools/showcase/notion/)
### TH04 : retrouver un calcul d'anneau de projectiles sous DOS
Inspectez les instructions 16 bits du jeu PC-98 d'origine, retrouvez les calculs d'angles fixes et visés, et comparez le C++ reconstruit avec la sortie du compilateur d'époque.
[Lire l'étude de cas](https://rea.tools/showcase/th04/) · [Dépôt de la reconstruction](https://github.com/N0zoM1z0/th04)
Si vous avez utilisé REA sur un projet intéressant, nous serions ravis de le découvrir. Partagez votre cas dans une [issue](https://github.com/morluto/rea/issues) ou une [pull request](https://github.com/morluto/rea/pulls), en précisant la cible, votre question, la manière dont REA vous a aidé et ce que vous avez découvert.
## Questions fréquentes
<details>
<summary><strong>Quels agents peuvent utiliser REA ?</strong></summary>
Tout agent compatible avec les serveurs MCP locaux. Setup configure les [agents pris en charge](docs/installation.md#supported-agents) ; les autres clients peuvent utiliser [l'enregistrement MCP manuel](docs/installation.md#mcp-registry).
</details>
<details>
<summary><strong>Ai-je besoin de Hopper, Ghidra ou IDA ?</strong></summary>
L'analyse native approfondie utilise l'un d'eux. L'inspection statique JavaScript et .NET fonctionne sans moteur d'analyse native. Setup peut installer Hopper après votre accord ; Ghidra et IDA utilisent vos installations existantes. Consultez [la configuration des fournisseurs](docs/installation.md#hopper).
</details>
<details>
<summary><strong>Dois-je lancer Hopper au préalable ?</strong></summary>
REA lance Hopper lorsqu'une opération en a besoin. Sous macOS, une boîte de dialogue de premier lancement peut vous demander de choisir le mode démo ou d'activer votre licence. Consultez [Démarrage et dépannage de Hopper](docs/installation.md#launcher-paths-and-troubleshooting).
</details>
<details>
<summary><strong>Que fait l'installation du skill depuis skills.sh ?</strong></summary>
Le skill fournit des instructions d'investigation à votre agent. Utilisez `npx rea-agents setup` pour enregistrer le serveur MCP de REA et installer les instructions correspondantes, puis redémarrez votre agent. Consultez [l'installation du skill seul](docs/installation.md#skill-only-installation).
</details>
<details>
<summary><strong>Quel code REA renvoie-t-il ?</strong></summary>
L'analyse native renvoie du pseudo-code et de l'assembleur. L'analyse JavaScript/Electron récupère les modules et leurs relations. Votre agent s'appuie sur ces résultats pour écrire et tester une implémentation ; les [études de cas](#études-de-cas) en donnent des exemples concrets.
</details>
<details>
<summary><strong>REA envoie-t-il mon application en ligne ?</strong></summary>
REA analyse les cibles localement. Votre agent reçoit les résultats des outils, et son fournisseur de modèle applique sa propre politique de données.
</details>
<details>
<summary><strong>Que faire si je rencontre un bug ?</strong></summary>
Commencez par mettre à jour ; une version récente l'a peut-être déjà corrigé.
Pour une CLI installée avec npm :
```bash
rea update
```
Pour une configuration d'agent via `npx` :
```bash
npx rea-agents@latest setup
```
Si vous utilisez un agent, terminez l'[actualisation de la configuration](#mettre-à-jour-rea) et redémarrez-le. Relancez la même tâche. Si le problème persiste, [ouvrez une issue](https://github.com/morluto/rea/issues) en indiquant votre version de REA, le type de cible, les étapes pour reproduire le problème et la sortie d'erreur.
</details>
## Documentation
Commencez par les [guides pas à pas](https://rea.tools/guides/) du site web. Pour les options exactes, les prérequis et les contrats de résultats :
- [Installation et configuration](docs/installation.md) : enregistrement des agents, configuration des fournisseurs, mises à jour et désinstallation.
- [Vérification et dépannage](docs/installation.md#check-readiness-for-your-task) : diagnostiquer un agent ou un moteur d'analyse précis.
- [CLI et Evidence](docs/cli.md) : commandes, choix du fournisseur, snapshots, import/export et codes de sortie.
- [Contrats MCP](docs/mcp-contracts.md) et [prompts pour agents](docs/mcp-prompts.md) : résultats des outils, sessions et investigations guidées.
- [Catalogue des outils](docs/mcp-contracts.md#generated-catalog) : inventaire des outils, fournisseurs et commandes CLI, généré lors du build.
- [Feuille de route](docs/roadmap.md) : travaux prévus et suivi des capacités.
Signalez les vulnérabilités via [SECURITY.md](SECURITY.md).
## Historique des étoiles
🎉 **50 000 étoiles GitHub — merci !**
Merci à toutes les personnes qui utilisent REA, signalent des bugs, proposent des fonctionnalités, testent les builds et contribuent des correctifs.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date&amp;theme=dark&amp;legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
<img alt="Historique des étoiles GitHub de REA" src="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
</picture>
</a>
## Avertissement
REA fournit des outils destinés à la recherche, à l'analyse et à la reconstruction légales en rétro-ingénierie. Il vous appartient d'obtenir toute autorisation nécessaire et de respecter les lois applicables. Le projet n'encourage aucune utilisation illégale ou non autorisée.
## Contribuer
Votre aide sur REA est la bienvenue ! [Ouvrez une issue](https://github.com/morluto/rea/issues) pour signaler un bug ou proposer une fonctionnalité, ou [envoyez une pull request](https://github.com/morluto/rea/pulls) pour améliorer le code ou la documentation.
Consultez [CONTRIBUTING.md](CONTRIBUTING.md) pour l'environnement de développement et les vérifications, la page [tests](docs/testing.md) pour les filières de vérification, et la [carte de l'architecture](docs/architecture.mermaid) pour la structure du projet.
## Licence
[MIT](LICENSE)
+310
View File
@@ -0,0 +1,310 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · **Bahasa Indonesia** · [Italiano](README_it.md)
# REA: Rekayasa Balik Apa Pun
### Satu MCP untuk rekayasa balik pada berbagai biner, aplikasi, dan perilaku saat runtime.
**Melihat fitur yang Anda sukai. Pahami cara kerjanya hingga ke tingkat biner.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
**[Situs Web](https://rea.tools/) · [Panduan](https://rea.tools/guides/) · [Contoh Penggunaan](https://rea.tools/showcase/)**
[Mulai Cepat](#mulai-cepat) · [Cara Kerja REA](#cara-kerja-rea) · [Hal yang Dapat Anda Analisis](#hal-yang-dapat-anda-analisis) · [Contoh Penggunaan](#contoh-penggunaan) · [FAQ](#faq) · [Dokumentasi](#dokumentasi)
<code>npx rea-agents setup</code>
<br />
<img src="docs/assets/rea-hopper-analysis.png" alt="REA menjalankan jembatan analisisnya di dalam Hopper saat memeriksa biner native" width="1200" />
<br /><br />
<table aria-label="Komunitas REA">
<tr>
<td align="center" width="360">
<a href="https://discord.gg/GkcryMnJDM">
<img src="docs/assets/discord.svg" height="42" alt="Discord" /><br />
<strong>Bergabunglah dengan Komunitas Rekayasa Balik</strong>
</a><br />
<sub>Discord · Tanya Jawab · Berbagi Hasil</sub>
</td>
</tr>
</table>
<br />
</div>
---
Melihat fitur dalam suatu aplikasi yang ingin Anda hadirkan di produk sendiri? Minta agen Anda menyelidikinya menggunakan REA. REA dapat memeriksa aplikasi tanpa kode sumbernya, menjelaskan cara kerja fitur tersebut, menunjukkan bukti, dan membangun versi untuk proyek Anda.
REA menghubungkan agen Anda dengan berbagai alat untuk memeriksa biner native, aplikasi JavaScript dan Electron, assembly .NET, serta situs web. Anda juga dapat menggunakan alat yang sama dari terminal. Analisis dijalankan secara lokal, dan hasilnya mencakup bukti serta keterbatasan yang mendasari setiap kesimpulan.
Proses penyiapan mendaftarkan REA ke agen Anda dan memasang instruksi alur kerja yang sesuai. Analisis native dapat menggunakan instalasi Hopper, Ghidra, atau IDA yang sudah ada. Proses penyiapan juga dapat memasang Hopper secara opsional setelah mendapatkan persetujuan. Analisis JavaScript statis tidak memerlukan mesin analisis native.
> **[Kunjungi situs web REA](https://rea.tools/)** untuk mendapatkan petunjuk penyiapan, panduan bergambar, dan studi kasus nyata.
## Mulai Cepat
### Siapkan agen Anda
Dengan Node.js dan npm yang telah terpasang, jalankan:
```bash
npx rea-agents setup
```
Pilih agen yang ingin digunakan, tinjau perubahan yang diusulkan, lalu setujui perubahan tersebut. Proses penyiapan menambahkan server MCP REA dan instruksi alur kerja yang sesuai, serta membuat cadangan konfigurasi yang sudah ada. Setelah itu, mulai ulang agen Anda.
Penyiapan mendukung Claude Code, Codex, Cursor, Gemini CLI, Grok Build, dan [agen lainnya](docs/installation.md#supported-agents). Lihat [instalasi dan penyiapan](docs/installation.md) untuk konfigurasi penyedia dan pendaftaran MCP secara manual.
### Minta agen Anda
```text
Pahami cara kerja pencarian di aplikasi Notes, tunjukkan buktinya, dan buat fitur serupa untuk proyek saya.
```
Ganti Notes dengan aplikasi target dan fitur yang ingin Anda pahami.
### Gunakan terminal
Periksa direktori aplikasi JavaScript/Electron yang telah diekstrak atau berkas ASAR:
```bash
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
```
Hasilnya mencakup modul, impor, batas antarkomponen Electron, dan bukti yang mendasarinya. Ganti jalur tersebut dengan lokasi target Anda, misalnya `"D:/apps/example"` di Windows.
Untuk memasang perintah `rea` agar dapat digunakan secara rutin:
```bash
npm install --global rea-agents
rea --help
```
Untuk analisis native, konfigurasikan penyedia terlebih dahulu. Lihat [Panduan CLI dan Bukti](docs/cli.md) untuk perintah native, pemilihan penyedia, snapshot, dan pembuatan skrip.
### Perbarui REA
REA berkembang dengan cepat, dan rilis baru sering menyertakan perbaikan bug. Pastikan instalasi Anda selalu diperbarui.
Untuk CLI yang dipasang melalui npm:
```bash
rea update
```
Untuk memperbarui pendaftaran agen dan skill Anda, jalankan perintah penyiapan yang ditampilkan oleh proses pembaruan.
Jika Anda menggunakan `npx`, perbarui penyiapan agen dengan:
```bash
npx rea-agents@latest setup
```
Tinjau perubahan penyiapan dan mulai ulang agen Anda. Untuk menjalankan perintah CLI sekali pakai, gunakan `npx rea-agents@latest` diikuti dengan perintah yang diinginkan.
## Cara Kerja REA
Agen Anda memanggil REA melalui MCP untuk memeriksa target dan menelusuri kode yang relevan. REA mengembalikan temuan beserta bukti pendukungnya. Agen kemudian menggunakan temuan tersebut untuk mengajukan pertanyaan lanjutan, menjelaskan perilaku, atau menulis dan menguji implementasi.
Perintah CLI menggunakan alur kerja yang sama.
![Alur investigasi REA: agen Anda menanyakan sesuatu tentang target lokal, REA memeriksa dan menelusurinya menggunakan alat analisis, lalu agen menggunakan kode, referensi, dan hal-hal yang belum diketahui dari hasil tersebut untuk menjelaskan, mengimplementasikan, dan menguji.](website/public/assets/figures/rea-investigation-flow.svg)
[Buka ilustrasi dalam ukuran penuh](website/public/assets/figures/rea-investigation-flow.svg).
<a id="current-status"></a>
## Hal yang Dapat Anda Analisis
REA memerlukan Node.js 22.x (>=22.19), 24.x (>=24.11), atau 26+, beserta npm.
Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
| Target | Hasil yang diberikan REA | Persyaratan dan panduan |
| -------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Biner native | Pseudocode, assembly, string, simbol, pemanggilan, dan referensi | Hopper, Ghidra, atau IDA; [analisis native](https://rea.tools/guides/native/) |
| Tata letak ELF offline | Bagian, segmen, simbol/relokasi asli, dan kandidat mitigasi statis | pwntools yang disediakan pemanggil pada Linux x64; [diagnostik biner](docs/binary-diagnostics.md) |
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal; [panduan EVM offline](docs/evm-bytecode.md) |
| Crash Linux yang direkam | Catatan mentah, register/sinyal setiap thread yang direkam, dan kandidat pemetaan opsional | pwntools yang disediakan pemanggil; GDB/pwndbg opsional; [crash yang direkam](docs/recorded-crashes.md) |
| JavaScript / Electron | Modul, impor, source map, rute, IPC, dan hubungan add-on native | Node.js dan npm; [analisis aplikasi](https://rea.tools/guides/javascript/) |
| Situs web | Struktur halaman, skrip, pengamatan jaringan, dan tangkapan layar yang diminta | Peramban berbasis Chrome; [analisis peramban](https://rea.tools/guides/browser/) |
| Rekaman jaringan tersimpan | Permintaan, respons, payload yang terekspos, dan lokasi sumber | HAR; mitmdump di Linux untuk rekaman native mitmproxy; [panduan rekaman](docs/web-network-captures.md) |
| Assembly .NET | Metadata, instruksi CIL, dependensi native yang dideklarasikan, dan perbandingan build | Tidak ada (hanya analisis statis); [panduan kode terkelola](docs/managed-code-analysis.md) |
| APK Android | Deklarasi manifest, kelas, metode hasil dekompilasi, dan referensi | JADX mode headless dan JDK lengkap di Linux/macOS/Windows x64; [panduan Android](docs/android-analysis.md) |
| Perangkat Android | Perangkat, paket, proses, log, dump, tangkapan layar, serta transfer APK/berkas | adb buatan pemanggil (emulator atau perangkat); [panduan ADB](docs/adb-device-analysis.md) |
| Proyek JEB | Unit proyek bertenaga mesin, hash artefak, dan pseudokode tipe/metode | Klien JEB yang dijalankan pemanggil dan menyajikan MCP, dipilih dengan REA_JEB_MCP_URL; [panduan JEB](docs/jeb-analysis.md) |
| Resource Android | Manifest terdekode, tabel string, lokal, dan fakta versi | Peluncur Apktool buatan pemanggil; [panduan resource](docs/apktool-resource-analysis.md) |
| Firmware | Wilayah, hasil ekstraksi, dan pengalihan ke analisis native | Binwalk / Unblob di Linux; [panduan firmware](docs/firmware-analysis.md) |
| Paket dan sumber daya | Inventaris berkas, digest, plist, struktur paket Apple, dan sumber daya yang diekstrak | [Panduan artefak dan JavaScript](docs/javascript-artifact-reconstruction.md), [aplikasi Apple](docs/apple-application-analysis.md) |
| Perilaku proses | Keluaran terminal, interaksi, pengamatan proses keluar dan sistem berkas, serta perbandingan eksekusi | Linux/macOS dengan PTY native; [perekaman proses](docs/process-capture.md) |
Pemeriksaan JavaScript dan .NET statis membaca berkas yang disediakan tanpa menjalankan aplikasinya. Perekaman runtime menjalankan atau berinteraksi dengan target yang dipilih menggunakan izin pengguna Anda. Setiap panduan runtime menjelaskan dampaknya.
<a id="choosing-a-deep-analysis-provider"></a>
Format native dan dukungan sistem host berbeda-beda menurut penyedia. Lihat [penyiapan Hopper dan Ghidra](docs/installation.md#hopper), [panduan IDA](docs/ida-provider.md), dan [dukungan eksperimental Ghidra di Windows](docs/windows-ghidra-p0.md).
Ghidra juga mendukung [analisis DOS 16-bit](docs/ghidra-dos.md).
Untuk biner berukuran besar, tingkatkan batas waktu startup menggunakan `REA_GHIDRA_STARTUP_TIMEOUT_MS`.
Untuk memilih penyedia, lihat [panduan CLI](docs/cli.md#choose-a-provider).
Periksa [ketersediaan rilis](docs/installation.md#released-package-and-main) untuk mengetahui fitur yang ditambahkan setelah rilis npm terbaru.
## Contoh Penggunaan
[![Ilustrasi contoh penggunaan DX-Ball sound-pan, Notion clipboard-bridge, dan TH04 bullet-ring](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: merekonstruksi perhitungan sound-pan
Ikuti pemanggilan suara hingga ke fungsi pembantu yang mengubah posisi menjadi nilai pan, periksa instruksinya, lalu ubah pseudocode yang belum lengkap menjadi C. Hasil rekonstruksi tersebut lolos pada 3.205 kasus x86 asli dan mereproduksi seluruh 63 byte fungsi hasil kompilasi.
[Baca studi kasus](https://rea.tools/showcase/dx-ball/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/dx-ball)
### Notion: menelusuri jembatan clipboard Electron
Temukan API clipboard pada renderer, telusuri jalurnya melalui preload dan IPC hingga ke proses utama, lalu periksa format clipboard kaya.
[Baca studi kasus](https://rea.tools/showcase/notion/)
### TH04: memulihkan perhitungan bullet-ring DOS
Periksa instruksi 16-bit dari gim PC-98 asli, pulihkan perhitungan sudut tetap dan sudut yang diarahkan, lalu bandingkan C++ hasil rekonstruksi dengan keluaran historis kompiler.
[Baca studi kasus](https://rea.tools/showcase/th04/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/th04)
Jika Anda telah menggunakan REA untuk menganalisis sesuatu yang menarik, kami ingin melihat hasilnya. Bagikan kasus Anda melalui [issue](https://github.com/morluto/rea/issues) atau [pull request](https://github.com/morluto/rea/pulls), sertakan target, pertanyaan Anda, bagaimana REA membantu, dan apa yang Anda temukan.
## FAQ
<details>
<summary><strong>Agen apa saja yang dapat menggunakan REA?</strong></summary>
Agen apa pun yang mendukung server MCP lokal dapat menggunakan REA. Proses penyiapan mengonfigurasi [agen yang didukung](docs/installation.md#supported-agents). Klien lain dapat menggunakan [pendaftaran MCP manual](docs/installation.md#mcp-registry).
</details>
<details>
<summary><strong>Apakah saya memerlukan Hopper, Ghidra, atau IDA?</strong></summary>
Analisis native mendalam menggunakan salah satu dari ketiganya. Pemeriksaan JavaScript dan .NET statis dapat dilakukan tanpa mesin analisis native.
Proses penyiapan dapat memasang Hopper setelah memperoleh persetujuan. Ghidra dan IDA menggunakan instalasi yang sudah tersedia. Lihat [penyiapan penyedia](docs/installation.md#hopper).
</details>
<details>
<summary><strong>Apakah saya harus menjalankan Hopper terlebih dahulu?</strong></summary>
REA akan menjalankan Hopper saat suatu operasi membutuhkannya. Di macOS, dialog saat pertama kali dijalankan mungkin meminta Anda memilih mode demo atau mengaktifkan lisensi.
Lihat [startup dan pemecahan masalah Hopper](docs/installation.md#launcher-paths-and-troubleshooting).
</details>
<details>
<summary><strong>Apa fungsi memasang skill dari skills.sh?</strong></summary>
Skill tersebut menyediakan instruksi investigasi untuk agen Anda. Gunakan `npx rea-agents setup` untuk mendaftarkan server MCP REA dan memasang instruksi yang sesuai, lalu mulai ulang agen Anda.
Lihat [instalasi khusus skill](docs/installation.md#skill-only-installation).
</details>
<details>
<summary><strong>Kode seperti apa yang dihasilkan REA?</strong></summary>
Analisis native menghasilkan pseudocode dan assembly. Analisis JavaScript/Electron memulihkan modul dan hubungan antarmodulnya. Agen Anda menggunakan temuan tersebut untuk menulis dan menguji implementasi. [Contoh penggunaan](#contoh-penggunaan) menyediakan contoh yang telah dikerjakan.
</details>
<details>
<summary><strong>Apakah REA mengunggah aplikasi saya?</strong></summary>
REA menganalisis target secara lokal. Agen Anda menerima hasil alat, sedangkan penyedia model yang digunakannya memiliki kebijakan datanya sendiri.
</details>
<details>
<summary><strong>Apa yang harus saya lakukan jika menemukan bug?</strong></summary>
Perbarui terlebih dahulu. Rilis terbaru mungkin sudah memperbaiki masalah tersebut.
Untuk CLI yang dipasang melalui npm:
```bash
rea update
```
Untuk penyiapan agen melalui `npx`:
```bash
npx rea-agents@latest setup
```
Jika Anda menggunakan agen, selesaikan [pembaruan penyiapan](#perbarui-rea) dan mulai ulang agen tersebut.
Coba kembali tugas yang sama. Jika masalah masih terjadi, [buat issue](https://github.com/morluto/rea/issues) dengan menyertakan versi REA, jenis target, langkah-langkah untuk mereproduksi masalah, dan keluaran kesalahan.
</details>
## Dokumentasi
Mulailah dengan [panduan praktik di situs web](https://rea.tools/guides/).
Untuk mengetahui opsi, prasyarat, dan kontrak hasil secara tepat:
- [Instalasi dan penyiapan](docs/installation.md): pendaftaran agen, konfigurasi penyedia, pembaruan, dan penghapusan instalasi.
- [Kesiapan dan pemecahan masalah](docs/installation.md#check-readiness-for-your-task): mendiagnosis satu agen atau mesin analisis.
- [CLI dan Bukti](docs/cli.md): perintah, pemilihan penyedia, snapshot, impor/ekspor, dan status keluar.
- [Kontrak MCP](docs/mcp-contracts.md) dan [prompt agen](docs/mcp-prompts.md): hasil alat, sesi, dan investigasi terpandu.
- [Katalog alat](docs/mcp-contracts.md#generated-catalog): inventaris alat, penyedia, dan perintah CLI yang dibuat secara otomatis.
- [Peta jalan](docs/roadmap.md): pekerjaan yang direncanakan dan pelacak kemampuan.
Laporkan kerentanan melalui [SECURITY.md](SECURITY.md).
## Riwayat Bintang
🎉 **50.000 bintang GitHub, terima kasih!**
Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fitur, menguji build, dan berkontribusi dalam perbaikan.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date&amp;theme=dark&amp;legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
<img alt="Riwayat bintang GitHub REA" src="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
</picture>
</a>
## Penafian
REA menyediakan alat untuk penelitian, analisis, dan rekonstruksi rekayasa balik yang sah. Anda bertanggung jawab untuk memperoleh otorisasi yang diperlukan dan mematuhi hukum yang berlaku. Proyek ini tidak mendukung penggunaan ilegal atau tanpa izin.
REA adalah proyek perangkat lunak sumber terbuka. Kami tidak menerbitkan atau mendukung mata uang kripto maupun token apa pun. Token yang menggunakan nama REA tidak berafiliasi dengan proyek ini.
## Kontribusi
Kami sangat menghargai bantuan Anda untuk REA! [Buat issue](https://github.com/morluto/rea/issues) untuk melaporkan bug atau menyarankan fitur, atau [kirim pull request](https://github.com/morluto/rea/pulls) untuk meningkatkan kode atau dokumentasi.
Lihat [CONTRIBUTING.md](CONTRIBUTING.md) untuk penyiapan pengembangan dan pemeriksaan, [pengujian](docs/testing.md) untuk tahapan verifikasi, serta [peta arsitektur](docs/architecture.mermaid) untuk struktur proyek.
## Lisensi
[MIT](LICENSE)
+289
View File
@@ -0,0 +1,289 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · **Italiano**
# REA: Reverse Engineer Anything
### Un unico MCP per l'ingegneria inversa su binari, applicazioni e comportamento a runtime.
**Vedi una funzionalità che ti piace. Capisci come funziona, fino al livello binario.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#cosa-puoi-analizzare)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
**[Sito web](https://rea.tools/) · [Guide](https://rea.tools/guides/) · [Showcase](https://rea.tools/showcase/)**
[Quick start](#quick-start) · [Come funziona REA](#come-funziona-rea) · [Cosa puoi analizzare](#cosa-puoi-analizzare) · [Showcase](#showcase) · [FAQ](#faq) · [Documentazione](#documentazione)
<code>npx rea-agents setup</code>
<br />
<img src="docs/assets/rea-hopper-analysis.png" alt="REA che avvia il suo bridge di analisi dentro Hopper mentre ispeziona un binario nativo" width="1200" />
<br /><br />
<table aria-label="Community REA">
<tr>
<td align="center" width="360">
<a href="https://discord.gg/GkcryMnJDM">
<img src="docs/assets/discord.svg" height="42" alt="Discord" /><br />
<strong>Unisciti alla community di ingegneria inversa</strong>
</a><br />
<sub>Discord · Domande e risposte · Show and Tell</sub>
</td>
</tr>
</table>
<br />
</div>
---
Hai visto una funzionalità in un'app che vorresti nel tuo prodotto? Chiedi al tuo agente di analizzarla con REA. Può ispezionare l'app senza il suo codice sorgente, spiegare come funziona la funzionalità, mostrare le prove e realizzare una versione per il tuo progetto.
REA collega il tuo agente a strumenti per ispezionare binari nativi, app JavaScript ed Electron, assembly .NET e siti web. Puoi usare gli stessi strumenti anche dal terminale. L'analisi viene eseguita localmente e i risultati includono le prove e i limiti dietro ogni conclusione.
La configurazione registra REA con il tuo agente e installa le istruzioni di workflow corrispondenti. L'analisi nativa può usare un'installazione esistente di Hopper, Ghidra o IDA; la configurazione può installare opzionalmente Hopper previa approvazione. L'analisi statica JavaScript non richiede alcun motore di analisi nativo.
> **[Visita il sito web di REA](https://rea.tools/)** per istruzioni di configurazione, guide illustrate e veri casi studio.
## Quick start
### Configura il tuo agente
Con Node.js e npm installati, esegui:
```bash
npx rea-agents setup
```
Scegli i tuoi agenti, rivedi le modifiche proposte e approvale. La configurazione aggiunge il server MCP di REA e le istruzioni di workflow corrispondenti, con backup della configurazione esistente. Riavvia quindi il tuo agente.
La configurazione supporta Claude Code, Codex, Cursor, Gemini CLI, Grok Build e [altri agenti](docs/installation.md#supported-agents). Vedi [installazione e configurazione](docs/installation.md) per la configurazione dei provider e la registrazione manuale MCP.
### Chiedi al tuo agente
```text
Spiega come funziona la ricerca nell'app Note, mostrami le prove e realizza
una funzionalità simile per il mio progetto.
```
Sostituisci Note con la tua app di destinazione e la funzionalità che vuoi capire.
### Usa il terminale
Ispeziona una directory di app JavaScript/Electron estratta o un ASAR:
```bash
npx -y rea-agents@latest analyze-javascript-application /percorso/assoluto/verso/app --json
```
Il risultato include moduli, import, confini Electron e le relative prove. Sostituisci il percorso con il tuo bersaglio, ad esempio `"D:/apps/example"` su Windows.
Per installare il comando `rea` per un uso regolare:
```bash
npm install --global rea-agents
rea --help
```
Per l'analisi nativa, configura prima un provider. Vedi la [guida CLI ed Evidence](docs/cli.md) per i comandi nativi, la selezione del provider, gli snapshot e lo scripting.
### Aggiorna REA
REA cambia rapidamente e le nuove versioni includono correzioni di bug frequenti. Tieni aggiornata la tua installazione.
Per una CLI installata via npm:
```bash
rea update
```
Per aggiornare le registrazioni del tuo agente e lo skill, esegui il comando di configurazione mostrato dall'aggiornamento.
Se usi `npx`, aggiorna la configurazione del tuo agente con:
```bash
npx rea-agents@latest setup
```
Rivedi le modifiche di configurazione e riavvia il tuo agente. Per comandi CLI singoli, usa `npx rea-agents@latest` seguito dal comando.
## Come funziona REA
Il tuo agente chiama REA tramite MCP per ispezionare il bersaglio e tracciare il codice rilevante. REA restituisce i risultati con le relative prove. L'agente li usa per fare domande di approfondimento, spiegare il comportamento o scrivere e testare un'implementazione. Anche i comandi CLI usano gli stessi workflow.
![Flusso di indagine REA: il tuo agente pone domande su un bersaglio locale, REA lo ispeziona e ne traccia il codice usando strumenti di analisi, e l'agente usa il codice, i riferimenti e gli elementi sconosciuti restituiti per spiegare, implementare e testare.](website/public/assets/figures/rea-investigation-flow.svg)
[Apri la figura a dimensione intera](website/public/assets/figures/rea-investigation-flow.svg).
<a id="current-status"></a>
## Cosa puoi analizzare
REA richiede Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, oltre a npm. Strumenti aggiuntivi e supporto host dipendono dal bersaglio:
| Obiettivo | Cosa restituisce REA | Requisiti e guida |
| ---------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Binari nativi | Pseudocodice, assembly, stringhe, simboli, chiamate e riferimenti | Hopper, Ghidra o IDA; [analisi nativa](https://rea.tools/guides/native/) |
| Layout ELF offline | Sezioni, segmenti, simboli/relocazioni originali e candidati mitigazioni statiche | pwntools fornito dal chiamante su Linux x64; [diagnostica binaria](docs/binary-diagnostics.md) |
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale; [guida EVM offline](docs/evm-bytecode.md) |
| Crash Linux registrati | Note grezze, registri/segnai di ogni thread registrato e candidati mapping opzionali | pwntools fornito dal chiamante; GDB/pwndbg opzionale; [crash registrati](docs/recorded-crashes.md) |
| JavaScript / Electron | Moduli, import, source map, route, IPC e relazioni con add-on nativi | Node.js e npm; [analisi delle applicazioni](https://rea.tools/guides/javascript/) |
| Siti web | Struttura della pagina, script, osservazioni di rete e screenshot richiesti | Un browser della famiglia Chrome; [analisi browser](https://rea.tools/guides/browser/) |
| Acquisizioni di rete salvate | Richieste, risposte, payload esposti e posizioni sorgente | HAR; mitmdump su Linux per acquisizioni mitmproxy native; [guida alle acquisizioni](docs/web-network-captures.md) |
| Assembly .NET | Metadati, istruzioni CIL, dipendenze native dichiarate e confronti di build | Nessuno (solo statico); [guida managed-code](docs/managed-code-analysis.md) |
| APK Android | Dichiarazioni manifest, classi, metodi decompilati e riferimenti | JADX headless e un JDK completo su Linux/macOS/Windows x64; [guida Android](docs/android-analysis.md) |
| Dispositivi Android | Dispositivi, pacchetti, processi, log, dump, screenshot e trasferimenti APK/file | adb fornito dal chiamante (emulatore o hardware); [guida ADB](docs/adb-device-analysis.md) |
| Progetti JEB | Unità di progetto dal motore, digest degli artifact e pseudocodice di tipi/metodi | Client JEB avviato dal chiamante via MCP, selezionato con REA_JEB_MCP_URL; [guida JEB](docs/jeb-analysis.md) |
| Risorse Android | Manifest decodificato, tabelle stringhe, lingue e dati di versione | Launcher Apktool fornito dal chiamante; [guida alle risorse](docs/apktool-resource-analysis.md) |
| Firmware | Regioni, risultati di estrazione e passaggi all'analisi nativa | Binwalk / Unblob su Linux; [guida firmware](docs/firmware-analysis.md) |
| Pacchetti e risorse | Inventari file, digest, plist, anatomia dei bundle Apple e risorse estratte | [Guida artifact e JavaScript](docs/javascript-artifact-reconstruction.md), [Applicazioni Apple](docs/apple-application-analysis.md) |
| Comportamento dei processi | Output del terminale, interazioni, osservazioni su uscita e filesystem ed confronti di esecuzione | Linux/macOS con un PTY nativo; [cattura dei processi](docs/process-capture.md) |
L'ispezione statica di JavaScript e .NET legge i file forniti senza eseguire l'applicazione. La cattura a runtime esegue o interagisce con il bersaglio selezionato usando i tuoi permessi utente; ogni guida runtime descrive i suoi effetti.
<a id="choosing-a-deep-analysis-provider"></a>
I formati nativi e il supporto host variano in base al provider. Vedi la [configurazione di Hopper e Ghidra](docs/installation.md#hopper), la [guida IDA](docs/ida-provider.md) e il [supporto sperimentale Windows Ghidra](docs/windows-ghidra-p0.md). Ghidra supporta anche l'[analisi DOS a 16 bit](docs/ghidra-dos.md). Per binari di grandi dimensioni, aumenta il timeout di avvio con `REA_GHIDRA_STARTUP_TIMEOUT_MS`. Per la selezione del provider, vedi la [guida CLI](docs/cli.md#choose-a-provider). Controlla la [disponibilità delle release](docs/installation.md#released-package-and-main) per le funzionalità aggiunte dall'ultima release npm.
## Showcase
[![Illustrazioni degli showcase del sound-pan di DX-Ball, del clipboard-bridge di Notion e dell'anello di proiettili di TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: ricostruisci un calcolo sound-pan
Segui una chiamata sonora fino al suo helper posizione-to-pan, ispeziona le istruzioni e trasforma il pseudocodice incompleto in C. La ricostruzione supera 3.205 casi x86 originali e riproduce tutti i 63 byte di funzione compilati.
[Leggi il case study](https://rea.tools/showcase/dx-ball/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/dx-ball)
### Notion: traccia il clipboard bridge di Electron
Trova l'API clipboard del renderer, seguila attraverso preload e IPC fino al processo principale e ispeziona il formato rich clipboard.
[Leggi il case study](https://rea.tools/showcase/notion/)
### TH04: recupera un calcolo dell'anello di proiettili DOS
Ispeziona le istruzioni a 16 bit del gioco PC-98 originale, recupera i calcoli dell'angolo fisso e mirato e confronta il C++ ricostruito con l'output del compilatore storico.
[Leggi il case study](https://rea.tools/showcase/th04/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/th04)
Se hai usato REA su qualcosa di interessante, ci piacerebbe vederlo. Condividi il tuo caso in una [issue](https://github.com/morluto/rea/issues) o in una [pull request](https://github.com/morluto/rea/pulls), includendo il bersaglio, la tua domanda, come REA ti ha aiutato e cosa hai scoperto.
## FAQ
<details>
<summary><strong>Quali agenti possono usare REA?</strong></summary>
Qualsiasi agente che supporti server MCP locali. La configurazione configura gli [agenti supportati](docs/installation.md#supported-agents); altri client possono usare la [registrazione MCP manuale](docs/installation.md#mcp-registry).
</details>
<details>
<summary><strong>Ho bisogno di Hopper, Ghidra o IDA?</strong></summary>
L'analisi nativa profonda ne usa uno. L'ispezione statica di JavaScript e .NET funziona senza un motore di analisi nativo. La configurazione può installare Hopper previa approvazione; Ghidra e IDA usano le tue installazioni esistenti. Vedi [configurazione provider](docs/installation.md#hopper).
</details>
<details>
<summary><strong>Devo avviare Hopper per primo?</strong></summary>
REA avvia Hopper quando un'operazione ne ha bisogno. Su macOS, una finestra di dialogo al primo avvio potrebbe chiederti di scegliere la modalità demo o di attivare la licenza. Vedi [avvio di Hopper e risoluzione dei problemi](docs/installation.md#launcher-paths-and-troubleshooting).
</details>
<details>
<summary><strong>Cosa fa l'installazione dello skill da skills.sh?</strong></summary>
Lo skill fornisce istruzioni di indagine per il tuo agente. Usa `npx rea-agents setup` per registrare il server MCP di REA e installare le istruzioni corrispondenti, quindi riavvia il tuo agente. Vedi [installazione solo skill](docs/installation.md#skill-only-installation).
</details>
<details>
<summary><strong>Quale codice restituisce REA?</strong></summary>
L'analisi nativa restituisce pseudocodice e assembly. L'analisi JavaScript/Electron recupera moduli e le loro relazioni. Il tuo agente usa questi risultati per scrivere e testare un'implementazione; gli [showcase](#showcase) offrono esempi concreti.
</details>
<details>
<summary><strong>REA carica la mia app da qualche parte?</strong></summary>
REA analizza i bersagli localmente. Il tuo agente riceve i risultati degli strumenti e il suo provider di modello ha la propria politica sui dati.
</details>
<details>
<summary><strong>Cosa devo fare se trovo un bug?</strong></summary>
Aggiorna prima; una release recente potrebbe averlo già risolto.
Per una CLI installata via npm:
```bash
rea update
```
Per la configurazione dell'agente tramite `npx`:
```bash
npx rea-agents@latest setup
```
Se stai usando un agente, completa l'[aggiornamento della configurazione](#aggiorna-rea) e riavvialo. Riprova lo stesso task. Se il problema persiste, [apri un issue](https://github.com/morluto/rea/issues) con la tua versione di REA, il tipo di bersaglio, i passaggi per riprodurlo e l'output di errore.
</details>
## Documentazione
Inizia dalle [guide pratiche](https://rea.tools/guides/) del sito web. Per opzioni esatte, prerequisiti e contratti dei risultati:
- [Installazione e configurazione](docs/installation.md): registrazione agente, configurazione provider, aggiornamenti e disinstallazione.
- [Pronto all'uso e risoluzione dei problemi](docs/installation.md#check-readiness-for-your-task): diagnostica un agente o un motore di analisi.
- [CLI ed Evidence](docs/cli.md): comandi, selezione provider, snapshot, import/export e stati di uscita.
- [Contratti MCP](docs/mcp-contracts.md) e [prompt agente](docs/mcp-prompts.md): risultati degli strumenti, sessioni e indagini guidate.
- [Catalogo strumenti](docs/mcp-contracts.md#generated-catalog): inventario generato di strumenti, provider e comandi CLI.
- [Roadmap](docs/roadmap.md): lavoro pianificato e tracker delle capacità.
Segnala vulnerabilità tramite [SECURITY.md](SECURITY.md).
## Cronologia delle stelle
🎉 **50.000 stelle su GitHub — grazie!**
Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, testano le build e contribuiscono con correzioni.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date&amp;theme=dark&amp;legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
<img alt="Cronologia stelle GitHub di REA" src="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
</picture>
</a>
## Disclaimer
REA fornisce strumenti per la ricerca, l'analisi e la ricostruzione di ingegneria inversa lecita. Sei responsabile di ottenere le eventuali autorizzazioni richieste e di rispettare le leggi applicabili. Il progetto non approva l'uso illegale o non autorizzato.
REA è un progetto software open-source. Non abbiamo emesso né approvato alcuna criptovaluta o token. I token che usano il nome REA non sono affiliati al progetto.
## Contributing
Apprezzeremmo il tuo aiuto con REA! [Apri un issue](https://github.com/morluto/rea/issues) per segnalare un bug o suggerire una funzionalità, oppure [invia una pull request](https://github.com/morluto/rea/pulls) per migliorare il codice o la documentazione.
Vedi [CONTRIBUTING.md](CONTRIBUTING.md) per la configurazione di sviluppo e i controlli, [testing](docs/testing.md) per le lane di verifica e la [mappa dell'architettura](docs/architecture.mermaid) per la struttura del progetto.
## License
[MIT](LICENSE)
+31 -30
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · **日本語** · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · **日本語** · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA:あらゆるものをリバースエンジニアリング
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA が Hopper 内で分析ブリッジを起動し、ネイティブバイナリを調べる様子" width="1200" />
<br />
<br /><br />
<table aria-label="REA コミュニティ">
<tr>
@@ -131,20 +131,23 @@ npx rea-agents@latest setup
REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm が必要です。追加のツールや対応ホストは、対象によって異なります。
| 対象 | REA が返すもの | 要件とガイド |
| -------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、または IDA;[ネイティブ分析](https://rea.tools/guides/native/) |
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](docs/binary-diagnostics.md) |
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | ローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](docs/evm-bytecode.md) |
| 記録済みの Linux クラッシュ | 生の note レコード、記録された全スレッドのレジスター/シグナル、任意のマッピング候補 | 利用者が用意する pwntools;GDB/pwndbg は任意;[記録済みクラッシュ](docs/recorded-crashes.md) |
| JavaScript / Electron | モジュール、インポート、ソースマップ、ルート、IPC、ネイティブアドオンの関係 | Node.js と npm;[アプリケーション分析](https://rea.tools/guides/javascript/) |
| ウェブサイト | ページ構造、スクリプト、ネットワークの観測結果、依頼されたスクリーンショット | Chrome 系ブラウザー;[ブラウザー分析](https://rea.tools/guides/browser/) |
| 保存済みのネットワークキャプチャ | リクエスト、レスポンス、取得可能なペイロード、ソース内の位置 | HAR;mitmproxy ネイティブ形式のキャプチャには Linux 上の mitmdump;[キャプチャガイド](docs/web-network-captures.md) |
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](docs/managed-code-analysis.md) |
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS 上のヘッドレス JADX と完全な JDK;[Android ガイド](docs/android-analysis.md) |
| ファームウェア | 領域、抽出結果、ネイティブ分析への引き継ぎ | Linux 上の Binwalk / Unblob;[ファームウェアガイド](docs/firmware-analysis.md) |
| パッケージとリソース | ファイル一覧、ダイジェスト、plist、Apple バンドルの構造、抽出されたリソース | [アーティファクトと JavaScript のガイド](docs/javascript-artifact-reconstruction.md)、[Apple アプリケーション](docs/apple-application-analysis.md) |
| プロセスの動作 | ターミナル出力、対話、終了とファイルシステムの観測結果、実行の比較 | ネイティブ PTY を備えた Linux/macOS;[プロセスキャプチャ](docs/process-capture.md) |
| 対象 | REA が返すもの | 要件とガイド |
| -------------------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、または IDA;[ネイティブ分析](https://rea.tools/guides/native/) |
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](docs/binary-diagnostics.md) |
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | Linux x64 上のローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](docs/evm-bytecode.md) |
| 記録済みの Linux クラッシュ | 生の note レコード、記録された全スレッドのレジスター/シグナル、任意のマッピング候補 | Linux x64 で利用者が用意する pwntools;GDB/pwndbg は任意;[記録済みクラッシュ](docs/recorded-crashes.md) |
| JavaScript / Electron | モジュール、インポート、ソースマップ、ルート、IPC、ネイティブアドオンの関係 | Node.js と npm;[アプリケーション分析](https://rea.tools/guides/javascript/) |
| ウェブサイト | ページ構造、スクリプト、ネットワークの観測結果、依頼されたスクリーンショット | Chrome 系ブラウザー;[ブラウザー分析](https://rea.tools/guides/browser/) |
| 保存済みのネットワークキャプチャ | リクエスト、レスポンス、取得可能なペイロード、ソース内の位置 | HAR;mitmproxy ネイティブ形式のキャプチャには Linux 上の mitmdump;[キャプチャガイド](docs/web-network-captures.md) |
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](docs/managed-code-analysis.md) |
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS/Windows x64 上のヘッドレス JADX と完全な JDK;[Android ガイド](docs/android-analysis.md) |
| Android デバイス | デバイス、パッケージ、プロセス、ログ、ダンプ、スクリーンキャプチャ、APK/ファイル転送 | 呼び出し側が用意した adb(エミュレーターまたは実機);[ADB ガイド](docs/adb-device-analysis.md) |
| JEBプロジェクト | エンジンによるプロジェクトユニット、アーティファクトのダイジェスト、型/メソッドの擬似コード | 呼び出し側が起動し MCP を提供する JEB クライアント(REA_JEB_MCP_URL で選択);[JEB ガイド](docs/jeb-analysis.md) |
| Android リソース | デコードされたマニフェスト、文字列テーブル、ロケール、バージョン情報 | 呼び出し側が用意した Apktool ランチャー;[リソースガイド](docs/apktool-resource-analysis.md) |
| ファームウェア | 領域、抽出結果、ネイティブ分析への引き継ぎ | Linux 上の Binwalk / Unblob;[ファームウェアガイド](docs/firmware-analysis.md) |
| パッケージとリソース | ファイル一覧、ダイジェスト、plist、Apple バンドルの構造、抽出されたリソース | [アーティファクトと JavaScript のガイド](docs/javascript-artifact-reconstruction.md)、[Apple アプリケーション](docs/apple-application-analysis.md) |
| プロセスの動作 | ターミナル出力、対話、終了とファイルシステムの観測結果、実行の比較 | ネイティブ PTY を備えた Linux/macOS;[プロセスキャプチャ](docs/process-capture.md) |
静的な JavaScript と .NET の検査は、指定されたファイルを読み取り、アプリケーションを実行しません。実行時キャプチャは、あなたのユーザー権限で対象を実行したり、対象とやり取りしたりします。それぞれの実行時ガイドに、どのような操作が行われるかを記載しています。
@@ -154,6 +157,8 @@ REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm
## 事例
[![DX-Ball の音声パン、Notion のクリップボードブリッジ、TH04 の弾幕リングの事例を表すイラスト](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball:音声のパン計算を再構築する
音声の呼び出しから位置をパンに変換する補助関数をたどり、命令を調べ、不完全な疑似コードを C に書き直します。再構築した実装は、元の x86 に対する 3,205 ケースの検証を通過し、コンパイル後の関数の全 63 バイトを再現しています。
@@ -202,7 +207,7 @@ REA は必要な操作の際に Hopper を起動します。macOS では、初
<details>
<summary><strong>skills.sh からスキルをインストールすると何ができますか?</strong></summary>
スキルはエージェントに調査の手順を提供します。`rea setup` で REA の MCP サーバーを登録し、対応する手順をインストールしてから、エージェントを再起動してください。[スキルのみのインストール](docs/installation.md#skill-only-installation)を参照してください。
スキルはエージェントに調査の手順を提供します。`npx rea-agents setup` で REA の MCP サーバーを登録し、対応する手順をインストールしてから、エージェントを再起動してください。[スキルのみのインストール](docs/installation.md#skill-only-installation)を参照してください。
</details>
@@ -254,21 +259,11 @@ npx rea-agents@latest setup
脆弱性の報告は [SECURITY.md](SECURITY.md) に従ってください。
## 貢献する
REA への貢献を歓迎します![issue を作成](https://github.com/morluto/rea/issues)してバグや機能の提案を報告したり、[pull request を送信](https://github.com/morluto/rea/pulls)してコードやドキュメントを改善したりできます。
開発環境とチェックは [CONTRIBUTING.md](CONTRIBUTING.md)、検証レーンは[テストガイド](docs/testing.md)、プロジェクト構造は[アーキテクチャ図](docs/architecture.mermaid)を参照してください。
## プロジェクトリンク
[ウェブサイト](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [セキュリティ](SECURITY.md)
## スター履歴
🎉 **GitHub スター 20,000 件、ありがとうございます!**
🎉 **GitHub スター 50,000 件、ありがとうございます!**
REA の利用、バグ報告、ビルドのテスト、修正への貢献に感謝します。
REA の利用、バグ報告、機能の要望、ビルドのテスト、修正への貢献に感謝します。
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -282,6 +277,12 @@ REA の利用、バグ報告、ビルドのテスト、修正への貢献に感
REA は、合法的なリバースエンジニアリングの研究、分析、再構築のためのツールを提供します。必要な許可を得て、適用される法律に従う責任は利用者にあります。このプロジェクトは違法または無許可の利用を支持しません。
## 貢献する
REA への貢献を歓迎します![issue を作成](https://github.com/morluto/rea/issues)してバグや機能の提案を報告したり、[pull request を送信](https://github.com/morluto/rea/pulls)してコードやドキュメントを改善したりできます。
開発環境とチェックは [CONTRIBUTING.md](CONTRIBUTING.md)、検証レーンは[テストガイド](docs/testing.md)、プロジェクト構造は[アーキテクチャ図](docs/architecture.mermaid)を参照してください。
## ライセンス
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · **한국어** · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · **한국어** · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: 무엇이든 리버스 엔지니어링
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA가 Hopper 안에서 분석 브리지를 실행해 네이티브 바이너리를 검사하는 모습" width="1200" />
<br />
<br /><br />
<table aria-label="REA 커뮤니티">
<tr>
@@ -135,13 +135,16 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
| --------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra 또는 IDA; [네이티브 분석](https://rea.tools/guides/native/) |
| 오프라인 ELF 레이아웃 | 섹션, 세그먼트, 원본 심볼/재배치 정보, 정적 분석으로 얻은 보안 완화 기법 후보 | Linux x64에서 호출자가 제공하는 pwntools; [바이너리 진단](docs/binary-diagnostics.md) |
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](docs/evm-bytecode.md) |
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; [기록된 크래시](docs/recorded-crashes.md) |
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | Linux x64의 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](docs/evm-bytecode.md) |
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | Linux x64에서 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; [기록된 크래시](docs/recorded-crashes.md) |
| JavaScript / Electron | 모듈, 임포트, 소스 맵, 라우트, IPC, 네이티브 애드온 관계 | Node.js와 npm; [애플리케이션 분석](https://rea.tools/guides/javascript/) |
| 웹사이트 | 페이지 구조, 스크립트, 네트워크 관찰 결과, 요청한 스크린샷 | Chrome 계열 브라우저; [브라우저 분석](https://rea.tools/guides/browser/) |
| 저장된 네트워크 캡처 | 요청, 응답, 접근 가능한 페이로드, 소스 위치 | HAR; mitmproxy 네이티브 캡처에는 Linux의 mitmdump; [캡처 가이드](docs/web-network-captures.md) |
| .NET 어셈블리 | 메타데이터, CIL 명령, 선언된 네이티브 의존성, 빌드 비교 | 정적 검사; [관리 코드 가이드](docs/managed-code-analysis.md) |
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS의 헤드리스 JADX와 전체 JDK; [Android 가이드](docs/android-analysis.md) |
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS/Windows x64의 헤드리스 JADX와 전체 JDK; [Android 가이드](docs/android-analysis.md) |
| Android 기기 | 기기, 패키지, 프로세스, 로그, 덤프, 화면 캡처, APK/파일 전송 | 호출자 제공 adb(에뮬레이터 또는 실제 기기); [ADB 가이드](docs/adb-device-analysis.md) |
| JEB 프로젝트 | 엔진 기반 프로젝트 유닛, 아티팩트 해시, 타입/메서드 의사코드 | 호출자가 시작하고 MCP를 제공하는 JEB 클라이언트(REA_JEB_MCP_URL로 선택); [JEB 가이드](docs/jeb-analysis.md) |
| Android 리소스 | 디코딩된 매니페스트, 문자열 테이블, 로캘, 버전 정보 | 호출자 제공 Apktool 런처; [리소스 가이드](docs/apktool-resource-analysis.md) |
| 펌웨어 | 영역, 추출 결과, 네이티브 분석으로 전달할 정보 | Linux의 Binwalk / Unblob; [펌웨어 가이드](docs/firmware-analysis.md) |
| 패키지 및 리소스 | 파일 목록, 다이제스트, plist, Apple 번들 구조, 추출한 리소스 | [아티팩트 및 JavaScript 가이드](docs/javascript-artifact-reconstruction.md), [Apple 애플리케이션](docs/apple-application-analysis.md) |
| 프로세스 동작 | 터미널 출력, 상호작용, 종료 및 파일 시스템 관찰 결과, 실행 비교 | 네이티브 PTY를 지원하는 Linux/macOS; [프로세스 캡처](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
## 사례
[![DX-Ball 사운드 패닝, Notion 클립보드 브리지, TH04 탄환 고리 사례를 보여 주는 그림](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: 사운드 패닝 계산 재구현
사운드 호출에서 위치를 패닝 값으로 변환하는 보조 함수까지 추적하고, 명령을 검사하여 불완전한 의사 코드를 C로 옮깁니다. 재구현한 코드는 원본 x86에 대한 3,205개 테스트 케이스를 통과했으며, 컴파일된 함수의 63바이트 전체를 재현합니다.
@@ -202,7 +207,7 @@ REA는 작업에 필요할 때 Hopper를 실행합니다. macOS에서는 처음
<details>
<summary><strong>skills.sh에서 설치하는 스킬은 어떤 역할을 하나요?</strong></summary>
스킬은 에이전트에게 조사 지침을 제공합니다. `rea setup`으로 REA의 MCP 서버를 등록하고 버전에 맞는 지침을 설치한 뒤 에이전트를 다시 시작하세요. [스킬만 설치하기](docs/installation.md#skill-only-installation)를 참고하세요.
스킬은 에이전트에게 조사 지침을 제공합니다. `npx rea-agents setup`으로 REA의 MCP 서버를 등록하고 버전에 맞는 지침을 설치한 뒤 에이전트를 다시 시작하세요. [스킬만 설치하기](docs/installation.md#skill-only-installation)를 참고하세요.
</details>
@@ -254,21 +259,11 @@ npx rea-agents@latest setup
취약점은 [SECURITY.md](SECURITY.md)에 따라 보고하세요.
## 기여
REA에 도움을 보태 주세요! [issue를 등록](https://github.com/morluto/rea/issues)해 버그나 기능을 제안하거나, [pull request를 보내](https://github.com/morluto/rea/pulls) 코드와 문서를 개선할 수 있습니다.
개발 환경과 검사 항목은 [CONTRIBUTING.md](CONTRIBUTING.md), 검증 절차는 [테스트 가이드](docs/testing.md), 프로젝트 구조는 [아키텍처 지도](docs/architecture.mermaid)를 참고하세요.
## 프로젝트 링크
[웹사이트](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [보안](SECURITY.md)
## 스타 기록
🎉 **GitHub 스타 20,000개, 감사합니다!**
🎉 **GitHub 스타 50,000개, 감사합니다!**
REA를 사용하고, 버그를 보고하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -282,6 +277,12 @@ REA를 사용하고, 버그를 보고하고, 빌드를 테스트하고, 수정
REA는 합법적인 리버스 엔지니어링 연구, 분석, 재구성을 위한 도구를 제공합니다. 필요한 권한을 얻고 관련 법률을 준수할 책임은 사용자에게 있습니다. 이 프로젝트는 불법적이거나 허가받지 않은 사용을 지지하지 않습니다.
## 기여
REA에 도움을 보태 주세요! [issue를 등록](https://github.com/morluto/rea/issues)해 버그나 기능을 제안하거나, [pull request를 보내](https://github.com/morluto/rea/pulls) 코드와 문서를 개선할 수 있습니다.
개발 환경과 검사 항목은 [CONTRIBUTING.md](CONTRIBUTING.md), 검증 절차는 [테스트 가이드](docs/testing.md), 프로젝트 구조는 [아키텍처 지도](docs/architecture.mermaid)를 참고하세요.
## 라이선스
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · **Polski** · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · **Polski** · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Reverse Engineer Anything
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA uruchamia most analityczny w Hopperze podczas analizy natywnego pliku binarnego" width="1200" />
<br />
<br /><br />
<table aria-label="Społeczność REA">
<tr>
@@ -135,13 +135,16 @@ REA wymaga Node.js 22.x (>=22.19), 24.x (>=24.11) lub 26+ oraz npm. Dodatkowe na
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Natywne pliki binarne | Pseudokod, kod asemblera, ciągi znaków, symbole, wywołania i odwołania | Hopper, Ghidra lub IDA; [analiza kodu natywnego](https://rea.tools/guides/native/) |
| Układ pliku ELF w trybie offline | Sekcje, segmenty, oryginalne symbole/relokacje i potencjalne mechanizmy zabezpieczeń wskazane przez analizę statyczną | pwntools dostarczone przez użytkownika w systemie Linux x64; [diagnostyka plików binarnych](docs/binary-diagnostics.md) |
| Kod bajtowy EVM | Selektory wywołań, przesunięcia bajtowe, wywnioskowane argumenty i mutowalność | Lokalny plik z surowymi bajtami lub zapisem szesnastkowym; [przewodnik EVM offline](docs/evm-bytecode.md) |
| Zarejestrowane awarie systemu Linux | Surowe rekordy note, rejestry/sygnały każdego zarejestrowanego wątku i opcjonalni kandydaci na mapowania | pwntools dostarczone przez użytkownika; opcjonalnie GDB/pwndbg; [zarejestrowane awarie](docs/recorded-crashes.md) |
| Kod bajtowy EVM | Selektory wywołań, przesunięcia bajtowe, wywnioskowane argumenty i mutowalność | Lokalny plik z surowymi bajtami lub zapisem szesnastkowym w systemie Linux x64; [przewodnik EVM offline](docs/evm-bytecode.md) |
| Zarejestrowane awarie systemu Linux | Surowe rekordy note, rejestry/sygnały każdego zarejestrowanego wątku i opcjonalni kandydaci na mapowania | pwntools dostarczone przez użytkownika w systemie Linux x64; opcjonalnie GDB/pwndbg; [zarejestrowane awarie](docs/recorded-crashes.md) |
| JavaScript / Electron | Moduły, importy, mapy źródeł, trasy, IPC i powiązania z natywnymi dodatkami | Node.js i npm; [analiza aplikacji](https://rea.tools/guides/javascript/) |
| Strony internetowe | Struktura strony, skrypty, obserwacje sieciowe i zamówione zrzuty ekranu | Przeglądarka z rodziny Chrome; [analiza w przeglądarce](https://rea.tools/guides/browser/) |
| Zapisane przechwycenia ruchu sieciowego | Żądania, odpowiedzi, dostępne dane przesyłane i lokalizacje źródłowe | HAR; mitmdump w systemie Linux dla natywnych przechwyceń mitmproxy; [przewodnik przechwytywania](docs/web-network-captures.md) |
| Zestawy .NET | Metadane, instrukcje CIL, zadeklarowane zależności natywne i porównania kompilacji | Analiza statyczna; [przewodnik kodu zarządzanego](docs/managed-code-analysis.md) |
| Pakiety APK dla Androida | Deklaracje manifestu, klasy, zdekompilowane metody i odwołania | JADX bez interfejsu graficznego i pełny JDK w systemie Linux/macOS; [przewodnik Androida](docs/android-analysis.md) |
| Pakiety APK dla Androida | Deklaracje manifestu, klasy, zdekompilowane metody i odwołania | JADX bez interfejsu graficznego i pełny JDK w systemach Linux/macOS/Windows x64; [przewodnik Androida](docs/android-analysis.md) |
| Urządzenia z Androidem | Urządzenia, pakiety, procesy, logi, zrzuty, zrzuty ekranu oraz transfery APK/plików | adb dostarczony przez wywołującego (emulator lub urządzenie); [przewodnik ADB](docs/adb-device-analysis.md) |
| Projekty JEB | Jednostki projektu obsługiwane przez silnik, skróty artefaktów i pseudokod typów/metod | Uruchomiony przez wywołującego klient JEB udostępniający MCP, wybrany przez REA_JEB_MCP_URL; [przewodnik JEB](docs/jeb-analysis.md) |
| Zasoby Androida | Zdekodowany manifest, tablice ciągów, języki i informacje o wersji | Należący do wywołującego launcher Apktool; [przewodnik zasobów](docs/apktool-resource-analysis.md) |
| Oprogramowanie układowe | Regiony, wyniki wyodrębniania i przekazanie do analizy kodu natywnego | Binwalk / Unblob w systemie Linux; [przewodnik oprogramowania układowego](docs/firmware-analysis.md) |
| Pakiety i zasoby | Spisy plików, skróty, pliki plist, struktura pakietów Apple i wyodrębnione zasoby | [Przewodnik artefaktów i JavaScript](docs/javascript-artifact-reconstruction.md), [aplikacje Apple](docs/apple-application-analysis.md) |
| Zachowanie procesów | Wyjście terminala, interakcje, obserwacje zakończenia i systemu plików oraz porównania uruchomień | Linux/macOS z natywnym PTY; [przechwytywanie procesów](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Obsługiwane formaty natywne i platformy zależą od dostawcy analizy. Zobacz [k
## Przykłady zastosowań
[![Ilustracje studiów przypadku panoramowania dźwięku w DX-Ball, mostka schowka w Notion i pierścienia pocisków w TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: odtworzenie obliczania panoramy dźwięku
Prześledź wywołanie dźwięku do funkcji pomocniczej przeliczającej pozycję na panoramę, sprawdź instrukcje i przekształć niepełny pseudokod w C. Odtworzona implementacja przechodzi 3 205 przypadków dla oryginalnego x86 i odtwarza wszystkie 63 bajty skompilowanej funkcji.
@@ -200,7 +205,7 @@ REA uruchamia Hoppera, gdy wymaga tego operacja. W systemie macOS przy pierwszym
<details>
<summary><strong>Co daje zainstalowanie umiejętności z skills.sh?</strong></summary>
Umiejętność dostarcza agentowi instrukcje prowadzenia analizy. Użyj `rea setup`, aby zarejestrować serwer MCP REA i zainstalować pasujące instrukcje, a następnie uruchom agenta ponownie. Zobacz [instalację samej umiejętności](docs/installation.md#skill-only-installation).
Umiejętność dostarcza agentowi instrukcje prowadzenia analizy. Użyj `npx rea-agents setup`, aby zarejestrować serwer MCP REA i zainstalować pasujące instrukcje, a następnie uruchom agenta ponownie. Zobacz [instalację samej umiejętności](docs/installation.md#skill-only-installation).
</details>
@@ -252,21 +257,11 @@ Zacznij od [przewodników z przykładami](https://rea.tools/guides/) na stronie
Zgłaszaj podatności zgodnie z [SECURITY.md](SECURITY.md).
## Współtworzenie
Chętnie przyjmiemy Twoją pomoc w rozwoju REA! [Otwórz zgłoszenie](https://github.com/morluto/rea/issues), aby poinformować o błędzie lub zaproponować funkcję, albo [wyślij pull request](https://github.com/morluto/rea/pulls) z ulepszeniami kodu lub dokumentacji.
Zobacz [CONTRIBUTING.md](CONTRIBUTING.md), aby poznać konfigurację środowiska programistycznego i kontrole, [testowanie](docs/testing.md), aby poznać ścieżki weryfikacji, oraz [mapę architektury](docs/architecture.mermaid), aby poznać strukturę projektu.
## Linki projektu
[Strona internetowa](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Zgłoszenia](https://github.com/morluto/rea/issues) · [Bezpieczeństwo](SECURITY.md)
## Historia gwiazdek
🎉 **20 000 gwiazdek na GitHubie — dziękujemy!**
🎉 **50 000 gwiazdek na GitHubie — dziękujemy!**
Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, testują kompilacje i przesyłają poprawki.
Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują nowe funkcje, testują kompilacje i przesyłają poprawki.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, testują komp
REA dostarcza narzędzia do zgodnych z prawem badań z zakresu inżynierii wstecznej, analizy i odtwarzania. Odpowiadasz za uzyskanie wymaganych zezwoleń i przestrzeganie obowiązującego prawa. Projekt nie popiera działań nielegalnych ani nieautoryzowanych.
## Współtworzenie
Chętnie przyjmiemy Twoją pomoc w rozwoju REA! [Otwórz zgłoszenie](https://github.com/morluto/rea/issues), aby poinformować o błędzie lub zaproponować funkcję, albo [wyślij pull request](https://github.com/morluto/rea/pulls) z ulepszeniami kodu lub dokumentacji.
Zobacz [CONTRIBUTING.md](CONTRIBUTING.md), aby poznać konfigurację środowiska programistycznego i kontrole, [testowanie](docs/testing.md), aby poznać ścieżki weryfikacji, oraz [mapę architektury](docs/architecture.mermaid), aby poznać strukturę projektu.
## Licencja
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · **Português (Brasil)** · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · **Português (Brasil)** · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Faça engenharia reversa de qualquer coisa
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA inicia sua ponte de análise dentro do Hopper enquanto inspeciona um binário nativo" width="1200" />
<br />
<br /><br />
<table aria-label="Comunidade REA">
<tr>
@@ -135,13 +135,16 @@ O REA requer Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, além do npm. As fer
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Binários nativos | Pseudocódigo, assembly, strings, símbolos, chamadas e referências | Hopper, Ghidra ou IDA; [análise nativa](https://rea.tools/guides/native/) |
| Estrutura ELF sem execução | Seções, segmentos, símbolos/relocações originais e possíveis mecanismos de mitigação identificados por análise estática | pwntools fornecido pelo chamador no Linux x64; [diagnóstico de binários](docs/binary-diagnostics.md) |
| Bytecode EVM | Seletores de despacho, offsets de bytes, argumentos inferidos e mutabilidade | Entrada local com bytes brutos ou representação hexadecimal; [guia de EVM sem execução](docs/evm-bytecode.md) |
| Falhas do Linux registradas | Registros note brutos, registradores/sinais de cada thread registrada e candidatos opcionais a mapeamentos | pwntools fornecido pelo chamador; GDB/pwndbg opcionais; [falhas registradas](docs/recorded-crashes.md) |
| Bytecode EVM | Seletores de despacho, offsets de bytes, argumentos inferidos e mutabilidade | Entrada local com bytes brutos ou representação hexadecimal no Linux x64; [guia de EVM sem execução](docs/evm-bytecode.md) |
| Falhas do Linux registradas | Registros note brutos, registradores/sinais de cada thread registrada e candidatos opcionais a mapeamentos | pwntools fornecido pelo chamador no Linux x64; GDB/pwndbg opcionais; [falhas registradas](docs/recorded-crashes.md) |
| JavaScript / Electron | Módulos, importações, source maps, rotas, IPC e relações com complementos nativos | Node.js e npm; [análise de aplicativos](https://rea.tools/guides/javascript/) |
| Sites | Estrutura da página, scripts, observações de rede e capturas de tela solicitadas | Um navegador da família Chrome; [análise do navegador](https://rea.tools/guides/browser/) |
| Capturas de rede salvas | Requisições, respostas, payloads acessíveis e localizações de origem | HAR; mitmdump no Linux para capturas no formato nativo do mitmproxy; [guia de capturas](docs/web-network-captures.md) |
| Assemblies .NET | Metadados, instruções CIL, dependências nativas declaradas e comparações de builds | Inspeção estática; [guia de código gerenciado](docs/managed-code-analysis.md) |
| APKs Android | Declarações do manifesto, classes, métodos descompilados e referências | JADX sem interface gráfica e um JDK completo no Linux/macOS; [guia de Android](docs/android-analysis.md) |
| APKs Android | Declarações do manifesto, classes, métodos descompilados e referências | JADX sem interface gráfica e um JDK completo no Linux/macOS/Windows x64; [guia de Android](docs/android-analysis.md) |
| Dispositivos Android | Dispositivos, pacotes, processos, logs, despejos, capturas de tela e transferências de APK/arquivos | adb fornecido pelo chamador (emulador ou aparelho); [guia de ADB](docs/adb-device-analysis.md) |
| Projetos JEB | Unidades de projeto do motor, hashes de artefatos e pseudocódigo de tipos/métodos | Um cliente JEB iniciado pelo chamador servindo MCP, selecionado com REA_JEB_MCP_URL; [guia de JEB](docs/jeb-analysis.md) |
| Recursos do Android | Manifesto decodificado, tabelas de strings, idiomas e fatos de versão | Lançador do Apktool fornecido pelo chamador; [guia de recursos](docs/apktool-resource-analysis.md) |
| Firmware | Regiões, resultados de extração e encaminhamentos à análise nativa | Binwalk / Unblob no Linux; [guia de firmware](docs/firmware-analysis.md) |
| Pacotes e recursos | Inventários de arquivos, digests, plists, estrutura de bundles Apple e recursos extraídos | [Guia de artefatos e JavaScript](docs/javascript-artifact-reconstruction.md), [aplicativos Apple](docs/apple-application-analysis.md) |
| Comportamento de processos | Saída do terminal, interações, observações de encerramento e do sistema de arquivos, e comparações entre execuções | Linux/macOS com PTY nativo; [captura de processos](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Os formatos nativos e os sistemas anfitriões compatíveis variam por provedor.
## Casos de uso
[![Ilustrações dos estudos de panoramização de áudio do DX-Ball, da ponte da área de transferência do Notion e do anel de projéteis do TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: reconstruir um cálculo de panorâmica de áudio
Siga uma chamada de áudio até a função auxiliar que converte posição em panorâmica, inspecione as instruções e transforme pseudocódigo incompleto em C. A reconstrução passa em 3.205 casos com o x86 original e reproduz todos os 63 bytes da função compilada.
@@ -200,7 +205,7 @@ O REA inicia o Hopper quando uma operação precisa dele. No macOS, um diálogo
<details>
<summary><strong>O que faz a instalação da skill pelo skills.sh?</strong></summary>
A skill fornece instruções de investigação ao seu agente. Use `rea setup` para registrar o servidor MCP do REA e instalar as instruções correspondentes, depois reinicie seu agente. Consulte [instalação apenas da skill](docs/installation.md#skill-only-installation).
A skill fornece instruções de investigação ao seu agente. Use `npx rea-agents setup` para registrar o servidor MCP do REA e instalar as instruções correspondentes, depois reinicie seu agente. Consulte [instalação apenas da skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,21 +257,11 @@ Comece pelos [guias práticos](https://rea.tools/guides/) do site. Para opções
Relate vulnerabilidades conforme [SECURITY.md](SECURITY.md).
## Contribuir
Sua ajuda com o REA é bem-vinda! [Abra uma issue](https://github.com/morluto/rea/issues) para relatar um bug ou sugerir uma funcionalidade, ou [envie um pull request](https://github.com/morluto/rea/pulls) para melhorar o código ou a documentação.
Consulte [CONTRIBUTING.md](CONTRIBUTING.md) para configurar o ambiente de desenvolvimento e as verificações, o [guia de testes](docs/testing.md) para os fluxos de verificação e o [mapa da arquitetura](docs/architecture.mermaid) para a estrutura do projeto.
## Links do projeto
[Site](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Segurança](SECURITY.md)
## Histórico de estrelas
🎉 **20.000 estrelas no GitHub — muito obrigado!**
🎉 **50.000 estrelas no GitHub — muito obrigado!**
Obrigado a todos que usam o REA, relatam bugs, testam builds e contribuem com correções.
Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam builds e contribuem com correções.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ Obrigado a todos que usam o REA, relatam bugs, testam builds e contribuem com co
O REA fornece ferramentas para pesquisa, análise e reconstrução por engenharia reversa dentro da lei. Você é responsável por obter as autorizações necessárias e cumprir as leis aplicáveis. O projeto não apoia usos ilegais ou não autorizados.
## Contribuir
Sua ajuda com o REA é bem-vinda! [Abra uma issue](https://github.com/morluto/rea/issues) para relatar um bug ou sugerir uma funcionalidade, ou [envie um pull request](https://github.com/morluto/rea/pulls) para melhorar o código ou a documentação.
Consulte [CONTRIBUTING.md](CONTRIBUTING.md) para configurar o ambiente de desenvolvimento e as verificações, o [guia de testes](docs/testing.md) para os fluxos de verificação e o [mapa da arquitetura](docs/architecture.mermaid) para a estrutura do projeto.
## Licença
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · **Русский** · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · **Русский** · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Реверс-инжиниринг чего угодно
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA запускает мост анализа внутри Hopper при исследовании нативного бинарного файла" width="1200" />
<br />
<br /><br />
<table aria-label="Сообщество REA">
<tr>
@@ -135,13 +135,16 @@ REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а так
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](https://rea.tools/guides/native/) |
| Структура ELF без запуска | Секции, сегменты, исходные символы/релокации и возможные механизмы защиты по данным статического анализа | pwntools, предоставленный вызывающей стороной, в Linux x64; [диагностика бинарных файлов](docs/binary-diagnostics.md) |
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление; [руководство по EVM без запуска](docs/evm-bytecode.md) |
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной; необязательные GDB/pwndbg; [записанные сбои](docs/recorded-crashes.md) |
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](docs/evm-bytecode.md) |
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](docs/recorded-crashes.md) |
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](https://rea.tools/guides/javascript/) |
| Сайты | Структура страницы, скрипты, наблюдения за сетью и запрошенные снимки экрана | Браузер семейства Chrome; [анализ браузера](https://rea.tools/guides/browser/) |
| Сохранённые сетевые захваты | Запросы, ответы, доступные полезные данные и позиции в источнике | HAR; mitmdump в Linux для захватов в собственном формате mitmproxy; [руководство по сетевым захватам](docs/web-network-captures.md) |
| Сборки .NET | Метаданные, инструкции CIL, объявленные нативные зависимости и сравнения сборок | Статическое исследование; [руководство по управляемому коду](docs/managed-code-analysis.md) |
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS; [руководство по Android](docs/android-analysis.md) |
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS/Windows x64; [руководство по Android](docs/android-analysis.md) |
| Устройства Android | Устройства, пакеты, процессы, журналы, дампы, снимки экрана и передача APK/файлов | adb, предоставленный вызывающей стороной (эмулятор или устройство); [руководство по ADB](docs/adb-device-analysis.md) |
| Проекты JEB | Единицы проекта от движка, дайджесты артефактов и псевдокод типов/методов | Запущенный вызывающей стороной клиент JEB с интерфейсом MCP, выбирается через REA_JEB_MCP_URL; [руководство по JEB](docs/jeb-analysis.md) |
| Ресурсы Android | Декодированный манифест, таблицы строк, языки и сведения о версии | Запуск Apktool, предоставленный вызывающей стороной; [руководство по ресурсам](docs/apktool-resource-analysis.md) |
| Прошивки | Области, результаты извлечения и передача в нативный анализ | Binwalk / Unblob в Linux; [руководство по прошивкам](docs/firmware-analysis.md) |
| Пакеты и ресурсы | Списки файлов, хеши, plist, структура пакетов Apple и извлечённые ресурсы | [Руководство по артефактам и JavaScript](docs/javascript-artifact-reconstruction.md), [приложения Apple](docs/apple-application-analysis.md) |
| Поведение процессов | Вывод терминала, взаимодействия, наблюдения за завершением и файловой системой, сравнения запусков | Linux/macOS с нативным PTY; [захват процессов](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а так
## Примеры
[![Иллюстрации примеров панорамирования звука в DX-Ball, моста буфера обмена Notion и кольца пуль в TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: восстановление расчёта звуковой панорамы
Проследите звуковой вызов до функции, преобразующей координату в значение панорамы, изучите инструкции и превратите неполный псевдокод в C. Восстановленная реализация проходит 3 205 тестов с исходным x86-кодом и воспроизводит все 63 байта скомпилированной функции.
@@ -200,7 +205,7 @@ REA запускает Hopper, когда он нужен для операци
<details>
<summary><strong>Что даёт установка skill с skills.sh?</strong></summary>
Skill предоставляет агенту инструкции по исследованию. Используйте `rea setup`, чтобы зарегистрировать MCP-сервер REA и установить соответствующие инструкции, затем перезапустите агента. См. [установку только skill](docs/installation.md#skill-only-installation).
Skill предоставляет агенту инструкции по исследованию. Используйте `npx rea-agents setup`, чтобы зарегистрировать MCP-сервер REA и установить соответствующие инструкции, затем перезапустите агента. См. [установку только skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,21 +257,11 @@ npx rea-agents@latest setup
Сообщайте об уязвимостях согласно [SECURITY.md](SECURITY.md).
## Участие в проекте
Будем рады вашей помощи с REA! [Откройте issue](https://github.com/morluto/rea/issues), чтобы сообщить об ошибке или предложить функцию, либо [отправьте pull request](https://github.com/morluto/rea/pulls) с улучшениями кода или документации.
Настройка среды разработки и проверки описаны в [CONTRIBUTING.md](CONTRIBUTING.md), направления проверки — в [руководстве по тестированию](docs/testing.md), а структура проекта — на [схеме архитектуры](docs/architecture.mermaid).
## Ссылки проекта
[Сайт](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Безопасность](SECURITY.md)
## История звёзд
🎉 **20 000 звёзд на GitHub — спасибо!**
🎉 **50 000 звёзд на GitHub — спасибо!**
Спасибо всем, кто использует REA, сообщает об ошибках, тестирует сборки и помогает с исправлениями.
Спасибо всем, кто использует REA, сообщает об ошибках, предлагает новые функции, тестирует сборки и помогает с исправлениями.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ npx rea-agents@latest setup
REA предоставляет инструменты для законных исследований, анализа и реконструкции с помощью реверс-инжиниринга. Вы отвечаете за получение необходимых разрешений и соблюдение применимых законов. Проект не поддерживает незаконное или несанкционированное использование.
## Участие в проекте
Будем рады вашей помощи с REA! [Откройте issue](https://github.com/morluto/rea/issues), чтобы сообщить об ошибке или предложить функцию, либо [отправьте pull request](https://github.com/morluto/rea/pulls) с улучшениями кода или документации.
Настройка среды разработки и проверки описаны в [CONTRIBUTING.md](CONTRIBUTING.md), направления проверки — в [руководстве по тестированию](docs/testing.md), а структура проекта — на [схеме архитектуры](docs/architecture.mermaid).
## Лицензия
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · **ไทย** · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · **ไทย** · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Reverse Engineer Anything
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA เริ่มบริดจ์การวิเคราะห์ภายใน Hopper ขณะตรวจสอบไบนารีเนทีฟ" width="1200" />
<br />
<br /><br />
<table aria-label="ชุมชน REA">
<tr>
@@ -135,13 +135,16 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
| ---------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| ไบนารีเนทีฟ | โค้ดเทียม แอสเซมบลี สตริง สัญลักษณ์ การเรียก และการอ้างอิง | Hopper, Ghidra หรือ IDA; [การวิเคราะห์เนทีฟ](https://rea.tools/guides/native/) |
| โครงสร้าง ELF แบบออฟไลน์ | เซกชัน เซกเมนต์ สัญลักษณ์/รีโลเคชันต้นฉบับ และตัวเลือกกลไกป้องกันที่พบจากการวิเคราะห์แบบสถิต | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; [การวินิจฉัยไบนารี](docs/binary-diagnostics.md) |
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหก; [คู่มือ EVM แบบออฟไลน์](docs/evm-bytecode.md) |
| ข้อมูลการแครชของ Linux ที่บันทึกไว้ | ระเบียน note ดิบ รีจิสเตอร์/สัญญาณของทุกเธรดที่บันทึกไว้ และตัวเลือกการแมปเพิ่มเติม | pwntools ที่ผู้ใช้จัดเตรียม; เลือกใช้ GDB/pwndbg เพิ่มเติมได้; [การแครชที่บันทึกไว้](docs/recorded-crashes.md) |
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหกบน Linux x64; [คู่มือ EVM แบบออฟไลน์](docs/evm-bytecode.md) |
| ข้อมูลการแครชของ Linux ที่บันทึกไว้ | ระเบียน note ดิบ รีจิสเตอร์/สัญญาณของทุกเธรดที่บันทึกไว้ และตัวเลือกการแมปเพิ่มเติม | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; เลือกใช้ GDB/pwndbg เพิ่มเติมได้; [การแครชที่บันทึกไว้](docs/recorded-crashes.md) |
| JavaScript / Electron | โมดูล การนำเข้า ซอร์สแมป เส้นทาง IPC และความสัมพันธ์กับส่วนเสริมเนทีฟ | Node.js และ npm; [การวิเคราะห์แอปพลิเคชัน](https://rea.tools/guides/javascript/) |
| เว็บไซต์ | โครงสร้างหน้า สคริปต์ ข้อมูลเครือข่ายที่สังเกตได้ และภาพหน้าจอที่ร้องขอ | เบราว์เซอร์ในตระกูล Chrome; [การวิเคราะห์ผ่านเบราว์เซอร์](https://rea.tools/guides/browser/) |
| ข้อมูลเครือข่ายที่บันทึกไว้ | คำขอ คำตอบ เพย์โหลดที่ปรากฏ และตำแหน่งต้นทาง | HAR; mitmdump บน Linux สำหรับข้อมูลที่บันทึกในรูปแบบเนทีฟของ mitmproxy; [คู่มือการบันทึกข้อมูล](docs/web-network-captures.md) |
| แอสเซมบลี .NET | เมทาดาทา คำสั่ง CIL การพึ่งพาเนทีฟที่ประกาศไว้ และการเปรียบเทียบผลการบิลด์ | การตรวจสอบแบบสถิต; [คู่มือโค้ดแบบจัดการ](docs/managed-code-analysis.md) |
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS; [คู่มือ Android](docs/android-analysis.md) |
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS/Windows x64; [คู่มือ Android](docs/android-analysis.md) |
| อุปกรณ์ Android | อุปกรณ์ แพ็กเกจ โพรเซส บันทึก ดัมพ์ ภาพหน้าจอ และการถ่ายโอน APK/ไฟล์ | adb ที่ผู้เรียกจัดเตรียม (โปรแกรมจำลองหรืออุปกรณ์จริง); [คู่มือ ADB](docs/adb-device-analysis.md) |
| โปรเจกต์ JEB | หน่วยโปรเจกต์จากเอนจิน, แฮชของอาร์ติแฟกต์ และซูโดโค้ดของไทป์/เมท็อด | ไคลเอนต์ JEB ที่ผู้เรียกเริ่มและให้บริการ MCP เลือกด้วย REA_JEB_MCP_URL; [คู่มือ JEB](docs/jeb-analysis.md) |
| ทรัพยากร Android | ไฟล์ manifest ที่ถอดรหัสแล้ว ตารางสตริง ภาษา และข้อมูลเวอร์ชัน | ตัวเรียก Apktool ที่ผู้เรียกจัดเตรียม; [คู่มือทรัพยากร](docs/apktool-resource-analysis.md) |
| เฟิร์มแวร์ | พื้นที่ข้อมูล ผลการแตกไฟล์ และการส่งต่อไปวิเคราะห์เนทีฟ | Binwalk / Unblob บน Linux; [คู่มือเฟิร์มแวร์](docs/firmware-analysis.md) |
| แพ็กเกจและทรัพยากร | รายการไฟล์ ค่าแฮช plist โครงสร้างบันเดิลของ Apple และทรัพยากรที่แตกออกมา | [คู่มืออาร์ติแฟกต์และ JavaScript](docs/javascript-artifact-reconstruction.md), [แอปพลิเคชัน Apple](docs/apple-application-analysis.md) |
| พฤติกรรมของโปรเซส | เอาต์พุตเทอร์มินัล การโต้ตอบ ข้อมูลการสิ้นสุดและระบบไฟล์ที่สังเกตได้ และการเปรียบเทียบการรัน | Linux/macOS ที่มี PTY เนทีฟ; [การบันทึกโปรเซส](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
## ตัวอย่างการใช้งาน
[![ภาพประกอบกรณีศึกษาการแพนเสียงใน DX-Ball บริดจ์คลิปบอร์ดของ Notion และวงแหวนกระสุนใน TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: สร้างการคำนวณแพนเสียงขึ้นใหม่
ติดตามการเรียกเสียงไปยังฟังก์ชันช่วยแปลงตำแหน่งเป็นค่าแพน ตรวจสอบคำสั่ง และแปลงโค้ดเทียมที่ยังไม่สมบูรณ์เป็น C การสร้างขึ้นใหม่นี้ผ่านการทดสอบ 3,205 กรณีเทียบกับ x86 ต้นฉบับ และสร้างไบต์ทั้ง 63 ไบต์ของฟังก์ชันที่คอมไพล์แล้วได้ตรงกัน
@@ -200,7 +205,7 @@ REA เริ่ม Hopper เมื่อการดำเนินการ
<details>
<summary><strong>การติดตั้งสกิลจาก skills.sh ทำอะไร?</strong></summary>
สกิลให้คำแนะนำการตรวจสอบแก่เอเจนต์ ใช้ `rea setup` เพื่อลงทะเบียนเซิร์ฟเวอร์ MCP ของ REA และติดตั้งคำแนะนำที่ตรงกัน แล้วเริ่มเอเจนต์ใหม่ ดู[การติดตั้งเฉพาะสกิล](docs/installation.md#skill-only-installation)
สกิลให้คำแนะนำการตรวจสอบแก่เอเจนต์ ใช้ `npx rea-agents setup` เพื่อลงทะเบียนเซิร์ฟเวอร์ MCP ของ REA และติดตั้งคำแนะนำที่ตรงกัน แล้วเริ่มเอเจนต์ใหม่ ดู[การติดตั้งเฉพาะสกิล](docs/installation.md#skill-only-installation)
</details>
@@ -252,21 +257,11 @@ npx rea-agents@latest setup
รายงานช่องโหว่ผ่าน [SECURITY.md](SECURITY.md)
## การมีส่วนร่วม
เรายินดีรับความช่วยเหลือในการพัฒนา REA! [เปิด issue](https://github.com/morluto/rea/issues) เพื่อรายงานบั๊กหรือเสนอฟีเจอร์ หรือ[ส่ง pull request](https://github.com/morluto/rea/pulls) เพื่อปรับปรุงโค้ดหรือเอกสาร
ดู [CONTRIBUTING.md](CONTRIBUTING.md) สำหรับการตั้งค่าสภาพแวดล้อมพัฒนาและการตรวจสอบ ดู[การทดสอบ](docs/testing.md) สำหรับแนวทางการตรวจยืนยัน และ[แผนผังสถาปัตยกรรม](docs/architecture.mermaid) สำหรับโครงสร้างโปรเจกต์
## ลิงก์ของโปรเจกต์
[เว็บไซต์](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [ความปลอดภัย](SECURITY.md)
## ประวัติดาว
🎉 **20,000 ดาวบน GitHub — ขอบคุณทุกคน!**
🎉 **50,000 ดาวบน GitHub — ขอบคุณทุกคน!**
ขอบคุณทุกคนที่ใช้ REA รายงานบั๊ก ทดสอบบิลด์ และช่วยแก้ไข
ขอบคุณทุกคนที่ใช้ REA รายงานบั๊ก เสนอฟีเจอร์ ทดสอบบิลด์ และช่วยแก้ไข
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ npx rea-agents@latest setup
REA มีเครื่องมือสำหรับการวิจัยวิศวกรรมย้อนกลับ การวิเคราะห์ และการสร้างขึ้นใหม่อย่างถูกกฎหมาย คุณมีหน้าที่ขออนุญาตตามที่จำเป็นและปฏิบัติตามกฎหมายที่เกี่ยวข้อง โปรเจกต์นี้ไม่สนับสนุนการใช้งานที่ผิดกฎหมายหรือไม่ได้รับอนุญาต
## การมีส่วนร่วม
เรายินดีรับความช่วยเหลือในการพัฒนา REA! [เปิด issue](https://github.com/morluto/rea/issues) เพื่อรายงานบั๊กหรือเสนอฟีเจอร์ หรือ[ส่ง pull request](https://github.com/morluto/rea/pulls) เพื่อปรับปรุงโค้ดหรือเอกสาร
ดู [CONTRIBUTING.md](CONTRIBUTING.md) สำหรับการตั้งค่าสภาพแวดล้อมพัฒนาและการตรวจสอบ ดู[การทดสอบ](docs/testing.md) สำหรับแนวทางการตรวจยืนยัน และ[แผนผังสถาปัตยกรรม](docs/architecture.mermaid) สำหรับโครงสร้างโปรเจกต์
## สัญญาอนุญาต
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · **Türkçe** · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · **Türkçe** · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Her şeyi tersine mühendislikle inceleyin
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA, yerel bir ikili dosyayı incelerken Hopper içinde analiz köprüsünü başlatıyor" width="1200" />
<br />
<br /><br />
<table aria-label="REA topluluğu">
<tr>
@@ -135,13 +135,16 @@ REA; Node.js 22.x (>=22.19), 24.x (>=24.11) veya 26+ ve npm gerektirir. Ek araç
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Yerel makine kodu içeren ikili dosyalar | Sözde kod, assembly kodu, dizeler, semboller, çağrılar ve referanslar | Hopper, Ghidra veya IDA; [yerel kod analizi](https://rea.tools/guides/native/) |
| Çevrimdışı ELF yapısı | Bölümler, segmentler, özgün semboller/yeniden konumlandırmalar ve statik analizden olası güvenlik önlemleri | Linux x64 üzerinde çağıranın sağladığı pwntools; [ikili dosya tanılama](docs/binary-diagnostics.md) |
| EVM bayt kodu | Yönlendirme seçicileri, bayt ofsetleri, çıkarımla belirlenen argümanlar ve durum değiştirilebilirliği | Yerel ham bayt/onaltılık girdi; [çevrimdışı EVM rehberi](docs/evm-bytecode.md) |
| Kaydedilmiş Linux çökmeleri | Ham note kayıtları, kaydedilen her iş parçacığının yazmaçları/sinyalleri ve isteğe bağlı eşleme adayları | Çağıranın sağladığı pwntools; isteğe bağlı GDB/pwndbg; [kaydedilmiş çökmeler](docs/recorded-crashes.md) |
| EVM bayt kodu | Yönlendirme seçicileri, bayt ofsetleri, çıkarımla belirlenen argümanlar ve durum değiştirilebilirliği | Linux x64 üzerinde yerel ham bayt/onaltılık girdi; [çevrimdışı EVM rehberi](docs/evm-bytecode.md) |
| Kaydedilmiş Linux çökmeleri | Ham note kayıtları, kaydedilen her iş parçacığının yazmaçları/sinyalleri ve isteğe bağlı eşleme adayları | Linux x64 üzerinde çağıranın sağladığı pwntools; isteğe bağlı GDB/pwndbg; [kaydedilmiş çökmeler](docs/recorded-crashes.md) |
| JavaScript / Electron | Modüller, içe aktarmalar, kaynak haritaları, rotalar, IPC ve yerel eklenti ilişkileri | Node.js ve npm; [uygulama analizi](https://rea.tools/guides/javascript/) |
| Web siteleri | Sayfa yapısı, betikler, ağ gözlemleri ve istenen ekran görüntüleri | Chrome ailesinden bir tarayıcı; [tarayıcı analizi](https://rea.tools/guides/browser/) |
| Kaydedilmiş ağ yakalamaları | İstekler, yanıtlar, erişilebilir yük içerikleri ve kaynak konumları | HAR; mitmproxy'nin kendi biçimindeki yakalamalar için Linux üzerinde mitmdump; [ağ yakalama rehberi](docs/web-network-captures.md) |
| .NET derlemeleri | Meta veriler, CIL talimatları, bildirilmiş yerel bağımlılıklar ve derleme karşılaştırmaları | Statik inceleme; [yönetilen kod rehberi](docs/managed-code-analysis.md) |
| Android APK'leri | Manifest bildirimleri, sınıflar, tersine derlenmiş metotlar ve referanslar | Linux/macOS üzerinde arayüzsüz JADX ve tam bir JDK; [Android rehberi](docs/android-analysis.md) |
| Android APK'leri | Manifest bildirimleri, sınıflar, tersine derlenmiş metotlar ve referanslar | Linux/macOS/Windows x64 üzerinde arayüzsüz JADX ve tam bir JDK; [Android rehberi](docs/android-analysis.md) |
| Android cihazları | Cihazlar, paketler, süreçler, günlükler, dökümler, ekran görüntüleri ve APK/dosya aktarımları | Çağıranın sağladığı adb (emülatör veya cihaz); [ADB rehberi](docs/adb-device-analysis.md) |
| JEB projeleri | Motor destekli proje birimleri, artefakt özetleri ve tür/metot sözdekodu | Çağıranın başlattığı, MCP sunan bir JEB istemcisi, REA_JEB_MCP_URL ile seçilir; [JEB rehberi](docs/jeb-analysis.md) |
| Android kaynakları | Çözülmüş manifest, dize tabloları, diller ve sürüm bilgileri | Çağıranın sağladığı Apktool başlatıcısı; [kaynak rehberi](docs/apktool-resource-analysis.md) |
| Donanım yazılımı | Bölgeler, çıkarma sonuçları ve yerel kod analizine devirler | Linux üzerinde Binwalk / Unblob; [donanım yazılımı rehberi](docs/firmware-analysis.md) |
| Paketler ve kaynaklar | Dosya envanterleri, özet değerleri, plist'ler, Apple paket yapısı ve çıkarılmış kaynaklar | [Artefakt ve JavaScript rehberi](docs/javascript-artifact-reconstruction.md), [Apple uygulamaları](docs/apple-application-analysis.md) |
| Süreç davranışı | Terminal çıktısı, etkileşimler, sonlanma ve dosya sistemi gözlemleri, çalıştırma karşılaştırmaları | Yerel PTY ile Linux/macOS; [süreç yakalama](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Yerel makine kodu içeren ikili dosya biçimleri ve ana bilgisayar desteği sağ
## Örnek çalışmalar
[![DX-Ball ses kaydırma, Notion pano köprüsü ve TH04 mermi halkası örneklerinin çizimleri](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: Sesin stereo konumlandırma hesabını yeniden oluşturma
Bir ses çağrısından konumu stereo konumlandırmaya dönüştüren yardımcı fonksiyona ilerleyin, talimatları inceleyin ve eksik sözde kodu C'ye dönüştürün. Yeniden oluşturulan kod, özgün x86 üzerinde 3.205 test durumunu geçer ve derlenmiş fonksiyonun 63 baytının tamamını yeniden üretir.
@@ -200,7 +205,7 @@ REA, bir işlem gerektirdiğinde Hopper'ı başlatır. macOS'ta ilk çalıştır
<details>
<summary><strong>skills.sh üzerinden skill yüklemek ne yapar?</strong></summary>
Skill, ajanınıza araştırma talimatları sağlar. REA'nın MCP sunucusunu kaydetmek ve uyumlu talimatları yüklemek için `rea setup` kullanın, ardından ajanınızı yeniden başlatın. [Yalnızca skill yükleme](docs/installation.md#skill-only-installation) belgesine bakın.
Skill, ajanınıza araştırma talimatları sağlar. REA'nın MCP sunucusunu kaydetmek ve uyumlu talimatları yüklemek için `npx rea-agents setup` kullanın, ardından ajanınızı yeniden başlatın. [Yalnızca skill yükleme](docs/installation.md#skill-only-installation) belgesine bakın.
</details>
@@ -252,21 +257,11 @@ Web sitesindeki [uygulamalı rehberlerden](https://rea.tools/guides/) başlayın
Güvenlik açıklarını [SECURITY.md](SECURITY.md) üzerinden bildirin.
## Katkıda bulunma
REA'ya katkınızı bekliyoruz! Hata bildirmek veya özellik önermek için bir [issue açın](https://github.com/morluto/rea/issues); kodu veya belgeleri geliştirmek için bir [pull request gönderin](https://github.com/morluto/rea/pulls).
Geliştirme ortamı ve kontroller için [CONTRIBUTING.md](CONTRIBUTING.md), doğrulama süreçleri için [test rehberi](docs/testing.md) ve proje yapısı için [mimari harita](docs/architecture.mermaid) belgelerine bakın.
## Proje bağlantıları
[Web sitesi](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Güvenlik](SECURITY.md)
## Yıldız geçmişi
🎉 **GitHub'da 20.000 yıldız — teşekkürler!**
🎉 **GitHub'da 50.000 yıldız — teşekkürler!**
REA'yı kullanan, hata bildiren, derlemeleri test eden ve düzeltmelere katkıda bulunan herkese teşekkürler.
REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve düzeltmelere katkıda bulunan herkese teşekkürler.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ REA'yı kullanan, hata bildiren, derlemeleri test eden ve düzeltmelere katkıda
REA, yasal tersine mühendislik araştırması, analizi ve yeniden oluşturma için araçlar sağlar. Gerekli izinleri almak ve geçerli yasalara uymak sizin sorumluluğunuzdadır. Proje yasa dışı veya yetkisiz kullanımı desteklemez.
## Katkıda bulunma
REA'ya katkınızı bekliyoruz! Hata bildirmek veya özellik önermek için bir [issue açın](https://github.com/morluto/rea/issues); kodu veya belgeleri geliştirmek için bir [pull request gönderin](https://github.com/morluto/rea/pulls).
Geliştirme ortamı ve kontroller için [CONTRIBUTING.md](CONTRIBUTING.md), doğrulama süreçleri için [test rehberi](docs/testing.md) ve proje yapısı için [mimari harita](docs/architecture.mermaid) belgelerine bakın.
## Lisans
[MIT](LICENSE)
+31 -30
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · **Українська** · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · **Українська** · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Реверс-інжиніринг будь-чого
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA запускає міст аналізу всередині Hopper під час дослідження нативного бінарного файла" width="1200" />
<br />
<br /><br />
<table aria-label="Спільнота REA">
<tr>
@@ -131,20 +131,23 @@ npx rea-agents@latest setup
REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а також npm. Додаткові інструменти й підтримувані системи залежать від цілі:
| Ціль | Що повертає REA | Вимоги й посібник |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Нативні бінарні файли | Псевдокод, асемблерний код, рядки, символи, виклики й посилання | Hopper, Ghidra або IDA; [нативний аналіз](https://rea.tools/guides/native/) |
| Структура ELF без запуску | Секції, сегменти, початкові символи/релокації та можливі захисні механізми за даними статичного аналізу | pwntools, наданий стороною, що викликає інструмент, у Linux x64; [діагностика бінарних файлів](docs/binary-diagnostics.md) |
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення; [посібник EVM без запуску](docs/evm-bytecode.md) |
| Записані аварійні завершення в Linux | Необроблені записи note, регістри/сигнали кожного записаного потоку й необов'язкові кандидати зіставлення пам'яті | pwntools, наданий стороною, що викликає інструмент; необов'язкові GDB/pwndbg; [записані аварійні завершення](docs/recorded-crashes.md) |
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](https://rea.tools/guides/javascript/) |
| Сайти | Структура сторінки, скрипти, мережеві спостереження й запитані знімки екрана | Браузер сімейства Chrome; [аналіз браузера](https://rea.tools/guides/browser/) |
| Збережені мережеві захоплення | Запити, відповіді, доступні корисні дані та місця в джерелі | HAR; mitmdump у Linux для захоплень у власному форматі mitmproxy; [посібник мережевих захоплень](docs/web-network-captures.md) |
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](docs/managed-code-analysis.md) |
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS; [посібник Android](docs/android-analysis.md) |
| Прошивки | Області, результати видобування й передавання до нативного аналізу | Binwalk / Unblob у Linux; [посібник прошивок](docs/firmware-analysis.md) |
| Пакети й ресурси | Переліки файлів, хеші, plist, структура пакетів Apple та видобуті ресурси | [Посібник артефактів і JavaScript](docs/javascript-artifact-reconstruction.md), [застосунки Apple](docs/apple-application-analysis.md) |
| Поведінка процесів | Вивід термінала, взаємодії, спостереження за завершенням і файловою системою та порівняння запусків | Linux/macOS із нативним PTY; [захоплення процесів](docs/process-capture.md) |
| Ціль | Що повертає REA | Вимоги й посібник |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Нативні бінарні файли | Псевдокод, асемблерний код, рядки, символи, виклики й посилання | Hopper, Ghidra або IDA; [нативний аналіз](https://rea.tools/guides/native/) |
| Структура ELF без запуску | Секції, сегменти, початкові символи/релокації та можливі захисні механізми за даними статичного аналізу | pwntools, наданий стороною, що викликає інструмент, у Linux x64; [діагностика бінарних файлів](docs/binary-diagnostics.md) |
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення у Linux x64; [посібник EVM без запуску](docs/evm-bytecode.md) |
| Записані аварійні завершення в Linux | Необроблені записи note, регістри/сигнали кожного записаного потоку й необов'язкові кандидати зіставлення пам'яті | pwntools, наданий стороною, що викликає інструмент, у Linux x64; необов'язкові GDB/pwndbg; [записані аварійні завершення](docs/recorded-crashes.md) |
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](https://rea.tools/guides/javascript/) |
| Сайти | Структура сторінки, скрипти, мережеві спостереження й запитані знімки екрана | Браузер сімейства Chrome; [аналіз браузера](https://rea.tools/guides/browser/) |
| Збережені мережеві захоплення | Запити, відповіді, доступні корисні дані та місця в джерелі | HAR; mitmdump у Linux для захоплень у власному форматі mitmproxy; [посібник мережевих захоплень](docs/web-network-captures.md) |
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](docs/managed-code-analysis.md) |
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS/Windows x64; [посібник Android](docs/android-analysis.md) |
| Пристрої Android | Пристрої, пакети, процеси, журнали, дампи, знімки екрана та передавання APK/файлів | adb, наданий викликаючою стороною (емулятор або пристрій); [підручник ADB](docs/adb-device-analysis.md) |
| Проєкти JEB | Єдиниці проєкту від рушія, дайджести артефактів і псевдокод типів/методів | Запущений викликаною стороною клієнт JEB з MCP, обирається через REA_JEB_MCP_URL; [посібник JEB](docs/jeb-analysis.md) |
| Ресурси Android | Декодований маніфест, таблиці рядків, мови та відомості про версію | Засіб запуску Apktool, наданий викликаючою стороною; [підручник ресурсів](docs/apktool-resource-analysis.md) |
| Прошивки | Області, результати видобування й передавання до нативного аналізу | Binwalk / Unblob у Linux; [посібник прошивок](docs/firmware-analysis.md) |
| Пакети й ресурси | Переліки файлів, хеші, plist, структура пакетів Apple та видобуті ресурси | [Посібник артефактів і JavaScript](docs/javascript-artifact-reconstruction.md), [застосунки Apple](docs/apple-application-analysis.md) |
| Поведінка процесів | Вивід термінала, взаємодії, спостереження за завершенням і файловою системою та порівняння запусків | Linux/macOS із нативним PTY; [захоплення процесів](docs/process-capture.md) |
Статична перевірка JavaScript і .NET читає надані файли, не запускаючи застосунок. Захоплення під час виконання запускає вибрану ціль або взаємодіє з нею з правами вашого користувача; відповідні посібники описують його вплив.
@@ -154,6 +157,8 @@ REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а та
## Приклади
[![Ілюстрації прикладів панорамування звуку в DX-Ball, мосту буфера обміну Notion та кільця куль у TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: відновлення розрахунку звукової панорами
Простежте звуковий виклик до допоміжної функції, що перетворює координату на панорамування, перевірте інструкції та перетворіть неповний псевдокод на C. Відновлена реалізація проходить 3 205 тестів з оригінальним x86-кодом і відтворює всі 63 байти скомпільованої функції.
@@ -200,7 +205,7 @@ REA запускає Hopper, коли він потрібен для опера
<details>
<summary><strong>Що дає встановлення skill із skills.sh?</strong></summary>
Skill надає агенту інструкції дослідження. Використовуйте `rea setup`, щоб зареєструвати MCP-сервер REA та встановити відповідні інструкції, а потім перезапустіть агента. Дивіться [встановлення лише skill](docs/installation.md#skill-only-installation).
Skill надає агенту інструкції дослідження. Використовуйте `npx rea-agents setup`, щоб зареєструвати MCP-сервер REA та встановити відповідні інструкції, а потім перезапустіть агента. Дивіться [встановлення лише skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,21 +257,11 @@ npx rea-agents@latest setup
Повідомляйте про вразливості згідно з [SECURITY.md](SECURITY.md).
## Участь у проєкті
Будемо раді вашій допомозі з REA! [Відкрийте issue](https://github.com/morluto/rea/issues), щоб повідомити про помилку чи запропонувати функцію, або [надішліть pull request](https://github.com/morluto/rea/pulls) з поліпшеннями коду чи документації.
Налаштування середовища розробки й перевірки описано в [CONTRIBUTING.md](CONTRIBUTING.md), шляхи верифікації — у [посібнику тестування](docs/testing.md), а структуру проєкту — на [схемі архітектури](docs/architecture.mermaid).
## Посилання проєкту
[Сайт](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Безпека](SECURITY.md)
## Історія зірок
🎉 **20 000 зірок на GitHub — дякуємо!**
🎉 **50 000 зірок на GitHub — дякуємо!**
Дякуємо всім, хто використовує REA, повідомляє про помилки, тестує збірки й допомагає з виправленнями.
Дякуємо всім, хто використовує REA, повідомляє про помилки, пропонує нові функції, тестує збірки й допомагає з виправленнями.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ npx rea-agents@latest setup
REA надає інструменти для законних досліджень, аналізу й реконструкції за допомогою реверс-інжинірингу. Ви відповідаєте за отримання необхідних дозволів і дотримання застосовних законів. Проєкт не підтримує незаконне або несанкціоноване використання.
## Участь у проєкті
Будемо раді вашій допомозі з REA! [Відкрийте issue](https://github.com/morluto/rea/issues), щоб повідомити про помилку чи запропонувати функцію, або [надішліть pull request](https://github.com/morluto/rea/pulls) з поліпшеннями коду чи документації.
Налаштування середовища розробки й перевірки описано в [CONTRIBUTING.md](CONTRIBUTING.md), шляхи верифікації — у [посібнику тестування](docs/testing.md), а структуру проєкту — на [схемі архітектури](docs/architecture.mermaid).
## Ліцензія
[MIT](LICENSE)
+20 -19
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · **Tiếng Việt** · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · **Tiếng Việt** · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA: Kỹ thuật dịch ngược cho mọi thứ
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA khởi chạy cầu nối phân tích bên trong Hopper khi kiểm tra tệp nhị phân mã máy" width="1200" />
<br />
<br /><br />
<table aria-label="Cộng đồng REA">
<tr>
@@ -135,13 +135,16 @@ REA yêu cầu Node.js 22.x (>=22.19), 24.x (>=24.11) hoặc 26+, cùng với np
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| Tệp nhị phân mã máy | Mã giả, hợp ngữ, chuỗi, ký hiệu, lời gọi và tham chiếu | Hopper, Ghidra hoặc IDA; [phân tích mã máy](https://rea.tools/guides/native/) |
| Bố cục ELF ngoại tuyến | Các section, segment, ký hiệu/thông tin tái định vị gốc và các biện pháp giảm thiểu có thể có từ phân tích tĩnh | pwntools do bên gọi cung cấp trên Linux x64; [chẩn đoán tệp nhị phân](docs/binary-diagnostics.md) |
| Bytecode EVM | Bộ chọn điều phối, độ lệch byte, tham số suy luận và khả năng thay đổi trạng thái | Đầu vào cục bộ chứa byte thô hoặc dạng thập lục phân; [hướng dẫn EVM ngoại tuyến](docs/evm-bytecode.md) |
| Sự cố Linux đã ghi lại | Bản ghi note thô, thanh ghi/tín hiệu của mọi luồng được ghi lại và các ứng viên ánh xạ tùy chọn | pwntools do bên gọi cung cấp; GDB/pwndbg tùy chọn; [sự cố đã ghi lại](docs/recorded-crashes.md) |
| Bytecode EVM | Bộ chọn điều phối, độ lệch byte, tham số suy luận và khả năng thay đổi trạng thái | Đầu vào cục bộ chứa byte thô hoặc dạng thập lục phân trên Linux x64; [hướng dẫn EVM ngoại tuyến](docs/evm-bytecode.md) |
| Sự cố Linux đã ghi lại | Bản ghi note thô, thanh ghi/tín hiệu của mọi luồng được ghi lại và các ứng viên ánh xạ tùy chọn | pwntools do bên gọi cung cấp trên Linux x64; GDB/pwndbg tùy chọn; [sự cố đã ghi lại](docs/recorded-crashes.md) |
| JavaScript / Electron | Mô-đun, các khai báo import, source map, tuyến, IPC và quan hệ với tiện ích mở rộng mã máy | Node.js và npm; [phân tích ứng dụng](https://rea.tools/guides/javascript/) |
| Trang web | Cấu trúc trang, script, quan sát mạng và ảnh chụp màn hình được yêu cầu | Trình duyệt thuộc họ Chrome; [phân tích trình duyệt](https://rea.tools/guides/browser/) |
| Bản ghi lưu lượng mạng đã lưu | Yêu cầu, phản hồi, payload có thể truy cập và vị trí nguồn | HAR; mitmdump trên Linux cho bản ghi định dạng gốc của mitmproxy; [hướng dẫn bản ghi mạng](docs/web-network-captures.md) |
| Assembly .NET | Siêu dữ liệu, lệnh CIL, các phụ thuộc mã máy được khai báo và so sánh bản dựng | Kiểm tra tĩnh; [hướng dẫn mã được quản lý](docs/managed-code-analysis.md) |
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS; [hướng dẫn Android](docs/android-analysis.md) |
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS/Windows x64; [hướng dẫn Android](docs/android-analysis.md) |
| Thiết bị Android | Thiết bị, gói, tiến trình, nhật ký, dump, ảnh chụp màn hình và truyền APK/tệp | adb do nơi gọi cung cấp (trình giả lập hoặc thiết bị); [hướng dẫn ADB](docs/adb-device-analysis.md) |
| Dự án JEB | Đơn vị dự án từ engine, hash của artifact và mã giả của kiểu/phương thức | Một ứng dụng JEB do nơi gọi khởi động, phục vụ MCP, chọn bằng REA_JEB_MCP_URL; [hướng dẫn JEB](docs/jeb-analysis.md) |
| Tài nguyên Android | Manifest đã giải mã, bảng chuỗi, ngôn ngữ và thông tin phiên bản | Trình khởi chạy Apktool do nơi gọi cung cấp; [hướng dẫn tài nguyên](docs/apktool-resource-analysis.md) |
| Phần sụn | Các vùng, kết quả trích xuất và dữ liệu chuyển sang phân tích mã máy | Binwalk / Unblob trên Linux; [hướng dẫn phần sụn](docs/firmware-analysis.md) |
| Gói và tài nguyên | Danh sách tệp, giá trị băm, plist, cấu trúc bundle Apple và tài nguyên được trích xuất | [Hướng dẫn hiện vật phần mềm và JavaScript](docs/javascript-artifact-reconstruction.md), [ứng dụng Apple](docs/apple-application-analysis.md) |
| Hành vi tiến trình | Đầu ra terminal, tương tác, quan sát khi thoát và hệ thống tệp, cùng so sánh các lần chạy | Linux/macOS có PTY gốc; [ghi lại tiến trình](docs/process-capture.md) |
@@ -154,6 +157,8 @@ Kiểm tra tĩnh JavaScript và .NET đọc các tệp được cung cấp mà k
## Các nghiên cứu điển hình
[![Minh họa các ví dụ về cân bằng âm thanh DX-Ball, cầu nối bảng nhớ tạm Notion và vòng đạn TH04](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: tái tạo phép tính phân bố âm thanh trái phải
Lần theo lời gọi âm thanh đến hàm hỗ trợ chuyển vị trí thành giá trị phân bố âm thanh, kiểm tra các lệnh và chuyển mã giả chưa đầy đủ sang C. Bản tái tạo vượt qua 3.205 trường hợp kiểm thử với x86 gốc và tái tạo đủ 63 byte của hàm đã biên dịch.
@@ -200,7 +205,7 @@ REA khởi chạy Hopper khi một thao tác cần đến nó. Trên macOS, hộ
<details>
<summary><strong>Cài skill từ skills.sh có tác dụng gì?</strong></summary>
Skill cung cấp hướng dẫn điều tra cho tác nhân. Dùng `rea setup` để đăng ký máy chủ MCP của REA và cài hướng dẫn tương ứng, sau đó khởi động lại tác nhân. Xem [chỉ cài skill](docs/installation.md#skill-only-installation).
Skill cung cấp hướng dẫn điều tra cho tác nhân. Dùng `npx rea-agents setup` để đăng ký máy chủ MCP của REA và cài hướng dẫn tương ứng, sau đó khởi động lại tác nhân. Xem [chỉ cài skill](docs/installation.md#skill-only-installation).
</details>
@@ -252,21 +257,11 @@ Bắt đầu với [hướng dẫn thực hành](https://rea.tools/guides/) trê
Báo cáo lỗ hổng theo [SECURITY.md](SECURITY.md).
## Đóng góp
Chúng tôi hoan nghênh bạn giúp phát triển REA! [Mở issue](https://github.com/morluto/rea/issues) để báo lỗi hoặc đề xuất tính năng, hoặc [gửi pull request](https://github.com/morluto/rea/pulls) để cải thiện mã hay tài liệu.
Xem [CONTRIBUTING.md](CONTRIBUTING.md) về thiết lập môi trường phát triển và các bước kiểm tra, [hướng dẫn kiểm thử](docs/testing.md) về các luồng xác minh và [sơ đồ kiến trúc](docs/architecture.mermaid) về cấu trúc dự án.
## Liên kết dự án
[Trang web](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Bảo mật](SECURITY.md)
## Lịch sử sao
🎉 **20.000 sao trên GitHub — xin cảm ơn!**
🎉 **50.000 sao trên GitHub — xin cảm ơn!**
Cảm ơn mọi người đã sử dụng REA, báo lỗi, kiểm thử bản dựng và đóng góp bản sửa lỗi.
Cảm ơn mọi người đã sử dụng REA, báo lỗi, đề xuất tính năng, kiểm thử bản dựng và đóng góp bản sửa lỗi.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -280,6 +275,12 @@ Cảm ơn mọi người đã sử dụng REA, báo lỗi, kiểm thử bản d
REA cung cấp công cụ cho nghiên cứu dịch ngược, phân tích và tái tạo hợp pháp. Bạn có trách nhiệm có được các quyền cho phép cần thiết và tuân thủ luật áp dụng. Dự án không ủng hộ việc sử dụng trái pháp luật hoặc không được cho phép.
## Đóng góp
Chúng tôi hoan nghênh bạn giúp phát triển REA! [Mở issue](https://github.com/morluto/rea/issues) để báo lỗi hoặc đề xuất tính năng, hoặc [gửi pull request](https://github.com/morluto/rea/pulls) để cải thiện mã hay tài liệu.
Xem [CONTRIBUTING.md](CONTRIBUTING.md) về thiết lập môi trường phát triển và các bước kiểm tra, [hướng dẫn kiểm thử](docs/testing.md) về các luồng xác minh và [sơ đồ kiến trúc](docs/architecture.mermaid) về cấu trúc dự án.
## Giấy phép
[MIT](LICENSE)
+21 -20
View File
@@ -1,8 +1,8 @@
<div align="center">
[English](README.md) · [简体中文](README_zh.md) · **繁體中文** · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · [简体中文](README_zh.md) · **繁體中文** · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA:逆向分析一切
# REA:逆向一切
### 通過一個 MCP 服務,逆向分析二進位檔案、應用程式和執行階段行為。
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA 在 Hopper 中啟動分析橋,檢查原生二進位檔案" width="1200" />
<br />
<br /><br />
<table aria-label="REA 社群">
<tr>
@@ -135,13 +135,16 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
| --------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 原生二進位檔案 | 偽程式碼、組合語言、字串、符號、呼叫和引用 | Hopper、Ghidra 或 IDA;[原生分析](https://rea.tools/guides/native/) |
| 離線 ELF 佈局 | 節、段、原始符號/重定位資訊及靜態防護機制候選項 | Linux x64 上由呼叫方提供的 pwntools;[二進位診斷](docs/binary-diagnostics.md) |
| EVM 位元組碼 | 分派選擇器、位元組偏移、推斷的參數和狀態可變性 | 本地原始位元組/十六進位輸入載體;[離線 EVM 指南](docs/evm-bytecode.md) |
| 已記錄的 Linux 崩潰 | 原始 note 記錄、每個已記錄執行緒的暫存器/訊號及可選的對映候選項 | 呼叫方提供的 pwntools;可選的 GDB/pwndbg;[已記錄崩潰](docs/recorded-crashes.md) |
| EVM 位元組碼 | 分派選擇器、位元組偏移、推斷的參數和狀態可變性 | Linux x64 上的本地原始位元組/十六進位輸入載體;[離線 EVM 指南](docs/evm-bytecode.md) |
| 已記錄的 Linux 崩潰 | 原始 note 記錄、每個已記錄執行緒的暫存器/訊號及可選的對映候選項 | Linux x64 上由呼叫方提供的 pwntools;可選的 GDB/pwndbg;[已記錄崩潰](docs/recorded-crashes.md) |
| JavaScript / Electron | 模組、匯入、source map、路由、IPC 和原生附加元件關係 | Node.js 和 npm;[應用分析](https://rea.tools/guides/javascript/) |
| 網站 | 頁面結構、腳本、網路觀察結果和按請求獲取的螢幕擷取畫面 | Chrome 系瀏覽器;[瀏覽器分析](https://rea.tools/guides/browser/) |
| 已保存的網路擷取 | 請求、回應、可訪問的酬載和來源位置 | HAR;原生 mitmproxy 擷取需要 Linux 上的 mitmdump;[擷取指南](docs/web-network-captures.md) |
| .NET 程式集 | 中繼資料、CIL 指令、聲明的原生依賴和建置對比 | 靜態檢查;[托管程式碼指南](docs/managed-code-analysis.md) |
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS 上的無界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS/Windows x64 上的無界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android 裝置 | 裝置、套件、程序、日誌、傾印、螢幕擷取以及 APK/檔案傳輸 | 呼叫端提供的 adb(模擬器或實體裝置);[ADB 指南](docs/adb-device-analysis.md) |
| JEB 專案 | 引擎支援的專案單元、成品摘要和型別/方法的虛擬碼 | 由呼叫端啟動、提供 MCP 的 JEB 用戶端,透過 REA_JEB_MCP_URL 選擇;[JEB 指南](docs/jeb-analysis.md) |
| Android 資源 | 解碼後的清單、字串表、語系和版本資訊 | 呼叫端提供的 Apktool 啟動器;[資源指南](docs/apktool-resource-analysis.md) |
| 韌體 | 區域、提取結果和轉交原生分析的內容 | Linux 上的 Binwalk / Unblob;[韌體指南](docs/firmware-analysis.md) |
| 軟體包與資源 | 檔案清單、摘要、plist、Apple bundle 結構和提取的資源 | [製品與 JavaScript 指南](docs/javascript-artifact-reconstruction.md)、[Apple 應用](docs/apple-application-analysis.md) |
| 處理程序行為 | 終端輸出、互動、退出和檔案系統觀察結果,以及執行對比 | 支援原生 PTY 的 Linux/macOS;[處理程序擷取](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
## 案例
[![DX-Ball 聲音平移、Notion 剪貼簿橋接與 TH04 彈幕環案例的插圖](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball:重建聲像計算
沿聲音呼叫追蹤到根據位置計算聲像的輔助函數,檢查指令,將不完整的偽程式碼轉為 C。重建結果通過了 3,205 個原始 x86 測試用例,並復現了編譯後函數的全部 63 個位元組。
@@ -202,7 +207,7 @@ REA 會在操作需要時啟動 Hopper。在 macOS 上,首次執行時可能
<details>
<summary><strong>從 skills.sh 安裝 skill 有什麼作用?</strong></summary>
skill 為 AI 代理提供調查指引。使用 `rea setup` 註冊 REA 的 MCP 服務並安裝對應的指引,然後重新啟動 AI 代理。見[僅安裝 skill](docs/installation.md#skill-only-installation)。
skill 為 AI 代理提供調查指引。使用 `npx rea-agents setup` 註冊 REA 的 MCP 服務並安裝對應的指引,然後重新啟動 AI 代理。見[僅安裝 skill](docs/installation.md#skill-only-installation)。
</details>
@@ -254,21 +259,11 @@ npx rea-agents@latest setup
請按照 [SECURITY.md](SECURITY.md) 報告漏洞。
## 參與貢獻
歡迎幫助改進 REA!你可以[提交 issue](https://github.com/morluto/rea/issues) 報告錯誤或建議功能,也可以[提交 pull request](https://github.com/morluto/rea/pulls) 改進程式碼或文件。
開發設定和檢查見 [CONTRIBUTING.md](CONTRIBUTING.md),驗證流程見[測試指南](docs/testing.md),專案結構見[架構圖](docs/architecture.mermaid)。
## 專案連結
[網站](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [安全](SECURITY.md)
## Star 歷史
🎉 **GitHub Star 達到 20,000 個,感謝大家!**
🎉 **GitHub Star 達到 50,000 個,感謝大家!**
感謝每一位使用 REA、報告錯誤、測試建置和貢獻修復的朋友。
感謝每一位使用 REA、報告錯誤、提出功能需求、測試建置和貢獻修復的朋友。
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -282,6 +277,12 @@ npx rea-agents@latest setup
REA 為合法的逆向工程研究、分析和重建提供工具。你有責任取得所需授權並遵守適用法律。本專案不認同非法或未經授權的使用。
## 參與貢獻
歡迎幫助改進 REA!你可以[提交 issue](https://github.com/morluto/rea/issues) 報告錯誤或建議功能,也可以[提交 pull request](https://github.com/morluto/rea/pulls) 改進程式碼或文件。
開發設定和檢查見 [CONTRIBUTING.md](CONTRIBUTING.md),驗證流程見[測試指南](docs/testing.md),專案結構見[架構圖](docs/architecture.mermaid)。
## 授權條款
[MIT](LICENSE)
+21 -20
View File
@@ -1,8 +1,8 @@
<div align="center">
[English](README.md) · **简体中文** · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
[English](README.md) · **简体中文** · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
# REA:逆向分析一切
# REA:逆向一切
### 通过一个 MCP 服务,逆向分析二进制文件、应用程序和运行时行为。
@@ -11,7 +11,7 @@
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![CI](https://img.shields.io/github/actions/workflow/status/morluto/rea/ci.yml?branch=main&style=flat-square&label=CI)](https://github.com/morluto/rea/actions/workflows/ci.yml)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
[![Node.js 22+](https://img.shields.io/badge/Node.js-22.19%2B-339933?style=flat-square&logo=nodedotjs&logoColor=white)](https://nodejs.org/)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#current-status)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
@@ -28,7 +28,7 @@
<img src="docs/assets/rea-hopper-analysis.png" alt="REA 在 Hopper 中启动分析桥,检查原生二进制文件" width="1200" />
<br />
<br /><br />
<table aria-label="REA 社区">
<tr>
@@ -135,13 +135,16 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
| --------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 原生二进制文件 | 伪代码、汇编、字符串、符号、调用和引用 | Hopper、Ghidra 或 IDA;[原生分析](https://rea.tools/guides/native/) |
| 离线 ELF 布局 | 节、段、原始符号/重定位信息及静态防护机制候选项 | Linux x64 上由调用方提供的 pwntools;[二进制诊断](docs/binary-diagnostics.md) |
| EVM 字节码 | 分派选择器、字节偏移、推断的参数和状态可变性 | 本地原始字节/十六进制输入载体;[离线 EVM 指南](docs/evm-bytecode.md) |
| 已记录的 Linux 崩溃 | 原始 note 记录、每个已记录线程的寄存器/信号及可选的映射候选项 | 调用方提供的 pwntools;可选的 GDB/pwndbg;[已记录崩溃](docs/recorded-crashes.md) |
| EVM 字节码 | 分派选择器、字节偏移、推断的参数和状态可变性 | Linux x64 上的本地原始字节/十六进制输入载体;[离线 EVM 指南](docs/evm-bytecode.md) |
| 已记录的 Linux 崩溃 | 原始 note 记录、每个已记录线程的寄存器/信号及可选的映射候选项 | Linux x64 上由调用方提供的 pwntools;可选的 GDB/pwndbg;[已记录崩溃](docs/recorded-crashes.md) |
| JavaScript / Electron | 模块、导入、source map、路由、IPC 和原生扩展关系 | Node.js 和 npm;[应用分析](https://rea.tools/guides/javascript/) |
| 网站 | 页面结构、脚本、网络观察结果和按请求获取的截图 | Chrome 系浏览器;[浏览器分析](https://rea.tools/guides/browser/) |
| 已保存的网络捕获 | 请求、响应、可访问的载荷和来源位置 | HAR;原生 mitmproxy 捕获需要 Linux 上的 mitmdump;[捕获指南](docs/web-network-captures.md) |
| .NET 程序集 | 元数据、CIL 指令、声明的原生依赖和构建对比 | 静态检查;[托管代码指南](docs/managed-code-analysis.md) |
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS 上的无界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS/Windows x64 上的无界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android 设备 | 设备、软件包、进程、日志、转储、屏幕截图以及 APK/文件传输 | 调用方提供的 adb(模拟器或实体设备);[ADB 指南](docs/adb-device-analysis.md) |
| JEB 项目 | 引擎支持的项目单元、工件摘要和类型/方法的伪代码 | 由调用方启动、提供 MCP 的 JEB 客户端,通过 REA_JEB_MCP_URL 选择;[JEB 指南](docs/jeb-analysis.md) |
| Android 资源 | 解码后的清单、字符串表、语言区域和版本信息 | 调用方提供的 Apktool 启动器;[资源指南](docs/apktool-resource-analysis.md) |
| 固件 | 区域、提取结果和转交原生分析的内容 | Linux 上的 Binwalk / Unblob;[固件指南](docs/firmware-analysis.md) |
| 软件包与资源 | 文件清单、摘要、plist、Apple bundle 结构和提取的资源 | [制品与 JavaScript 指南](docs/javascript-artifact-reconstruction.md)、[Apple 应用](docs/apple-application-analysis.md) |
| 进程行为 | 终端输出、交互、退出和文件系统观察结果,以及运行对比 | 支持原生 PTY 的 Linux/macOS;[进程捕获](docs/process-capture.md) |
@@ -154,6 +157,8 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
## 案例
[![DX-Ball 声音平移、Notion 剪贴板桥接与 TH04 弹幕环案例的插图](docs/assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball:重建声像计算
沿声音调用追踪到根据位置计算声像的辅助函数,检查指令,将不完整的伪代码转为 C。重建结果通过了 3,205 个原始 x86 测试用例,并复现了编译后函数的全部 63 个字节。
@@ -202,7 +207,7 @@ REA 会在操作需要时启动 Hopper。在 macOS 上,首次运行时可能
<details>
<summary><strong>从 skills.sh 安装 skill 有什么作用?</strong></summary>
skill 为智能体提供调查指引。使用 `rea setup` 注册 REA 的 MCP 服务并安装匹配的指引,然后重启智能体。见[仅安装 skill](docs/installation.md#skill-only-installation)。
skill 为智能体提供调查指引。使用 `npx rea-agents setup` 注册 REA 的 MCP 服务并安装匹配的指引,然后重启智能体。见[仅安装 skill](docs/installation.md#skill-only-installation)。
</details>
@@ -254,21 +259,11 @@ npx rea-agents@latest setup
请按照 [SECURITY.md](SECURITY.md) 报告漏洞。
## 参与贡献
欢迎帮助改进 REA!你可以[提交 issue](https://github.com/morluto/rea/issues) 报告错误或建议功能,也可以[提交 pull request](https://github.com/morluto/rea/pulls) 改进代码或文档。
开发设置和检查见 [CONTRIBUTING.md](CONTRIBUTING.md),验证流程见[测试指南](docs/testing.md),项目结构见[架构图](docs/architecture.mermaid)。
## 项目链接
[网站](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [安全](SECURITY.md)
## Star 历史
🎉 **GitHub Star 达到 20,000 个,感谢大家!**
🎉 **GitHub Star 达到 50,000 个,感谢大家!**
感谢每一位使用 REA、报告错误、测试构建和贡献修复的朋友。
感谢每一位使用 REA、报告错误、提出功能需求、测试构建和贡献修复的朋友。
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
@@ -282,6 +277,12 @@ npx rea-agents@latest setup
REA 为合法的逆向工程研究、分析和重建提供工具。你有责任取得所需授权并遵守适用法律。项目不支持非法或未经授权的使用。
## 参与贡献
欢迎帮助改进 REA!你可以[提交 issue](https://github.com/morluto/rea/issues) 报告错误或建议功能,也可以[提交 pull request](https://github.com/morluto/rea/pulls) 改进代码或文档。
开发设置和检查见 [CONTRIBUTING.md](CONTRIBUTING.md),验证流程见[测试指南](docs/testing.md),项目结构见[架构图](docs/architecture.mermaid)。
## 许可证
[MIT](LICENSE)
+151
View File
@@ -0,0 +1,151 @@
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.symbol.SourceType;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HexFormat;
import java.util.List;
/**
* Apply caller-declared analysis seeds before default auto-analysis.
*
* The single argument is REA's canonical seed snapshot: one
* {@code 0x<hex>\t(function|code|label)[\tname]} line per seed. Code seeds are
* applied after functions (highest address first), then labels. The outcome is stored as a
* program property that the bridge reports during its handshake.
*/
public final class ReaGhidraApplySeeds extends GhidraScript {
static final String REPORT_OPTION = "REA analysis seeds";
private record Seed(Address address, String kind, String name) {}
@Override
public void run() throws Exception {
String[] args = getScriptArgs();
if (args.length != 1) {
throw new IllegalArgumentException("REA seed script requires exactly one seed file");
}
Path path = Path.of(args[0]);
if (!Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS)) {
throw new IllegalArgumentException("REA seed file is not a regular file");
}
byte[] bytes = Files.readAllBytes(path);
String sha256 = HexFormat.of().formatHex(
MessageDigest.getInstance("SHA-256").digest(bytes)
);
AddressSpace space = currentProgram.getAddressFactory().getDefaultAddressSpace();
List<Seed> seeds = new ArrayList<>();
for (String line : new String(bytes, StandardCharsets.UTF_8).split("\n")) {
if (line.isEmpty()) continue;
String[] fields = line.split("\t", -1);
if (fields.length < 2 || fields.length > 3 || !fields[0].startsWith("0x")) {
throw new IllegalArgumentException("REA seed snapshot is malformed");
}
Address address;
try {
address = space.getAddress(Long.parseUnsignedLong(fields[0].substring(2), 16));
} catch (ghidra.program.model.address.AddressOutOfBoundsException e) {
address = null;
}
seeds.add(new Seed(address, fields[1], fields.length == 3 ? fields[2] : null));
}
// Highest address first: a function body computed before analysis stops at
// an existing function entry, so later creations cannot swallow earlier ones.
seeds.sort((left, right) -> {
if (left.address() == null) return right.address() == null ? 0 : 1;
if (right.address() == null) return -1;
return right.address().compareTo(left.address());
});
int unmapped = 0;
int logged = 0;
int codeDecoded = 0, codeFailed = 0;
int functionCreated = 0, functionExisting = 0, functionFailed = 0;
int labelApplied = 0, labelFailed = 0;
for (String pass : new String[] { "function", "code", "label" }) {
for (Seed seed : seeds) {
if (!seed.kind().equals(pass)) continue;
monitor.checkCancelled();
MemoryBlock block = seed.address() == null
? null
: currentProgram.getMemory().getBlock(seed.address());
if (block == null || (!pass.equals("label") && !block.isInitialized())) {
unmapped++;
continue;
}
switch (pass) {
case "code" -> {
if (decoded(seed.address())) codeDecoded++;
else {
codeFailed++;
if (logged++ < 20) println("REA seed failed: code " + seed.address() + " " + why(seed.address()));
}
}
case "function" -> {
Function existing = getFunctionAt(seed.address());
if (existing != null) {
functionExisting++;
if (seed.name() != null) {
existing.setName(seed.name(), SourceType.USER_DEFINED);
}
} else if (decoded(seed.address()) &&
createFunction(seed.address(), seed.name()) != null) {
functionCreated++;
} else {
functionFailed++;
if (logged++ < 20) println("REA seed failed: function " + seed.address() + " " + why(seed.address()));
}
}
default -> {
try {
createLabel(seed.address(), seed.name(), true, SourceType.USER_DEFINED);
labelApplied++;
} catch (Exception e) {
labelFailed++;
}
}
}
}
}
String report = "{\"format\":\"rea-ghidra-seeds-v1\",\"sha256\":\"" + sha256 + "\"" +
",\"entries\":" + seeds.size() +
",\"function_created\":" + functionCreated +
",\"function_existing\":" + functionExisting +
",\"function_failed\":" + functionFailed +
",\"code_decoded\":" + codeDecoded +
",\"code_failed\":" + codeFailed +
",\"label_applied\":" + labelApplied +
",\"label_failed\":" + labelFailed +
",\"unmapped\":" + unmapped + "}";
currentProgram.getOptions(Program.PROGRAM_INFO).setString(REPORT_OPTION, report);
println("REA seeds applied: " + report);
}
private String why(Address address) {
if (getDataAt(address) != null) return "defined data " + getDataAt(address).getDataType().getName();
var containing = getInstructionContaining(address);
if (containing != null && !containing.getAddress().equals(address))
return "inside instruction at " + containing.getAddress();
Function owner = getFunctionContaining(address);
if (owner != null) return "inside function " + owner.getEntryPoint();
return getInstructionAt(address) == null ? "undecodable" : "function creation refused";
}
/** Decode one instruction flow at an address, keeping an existing decode. */
private boolean decoded(Address address) {
if (getInstructionAt(address) != null) return true;
if (getDataAt(address) != null || getInstructionContaining(address) != null) {
return false;
}
disassemble(address);
return getInstructionAt(address) != null;
}
}
File diff suppressed because it is too large Load Diff
+123
View File
@@ -0,0 +1,123 @@
import ghidra.app.cmd.function.CreateFunctionCmd;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.FlowType;
import ghidra.program.model.symbol.Reference;
import ghidra.program.model.pcode.PcodeOp;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
/**
* Undo wrong no-return flags from auto-analysis. A function flagged no-return that contains a
* real RET is an ordinary function (stream readers, cxa_guard_acquire, ...). Known returning
* libc/TLS imports have no body to inspect, so clear their flags by exact external ABI name.
* Callers treated the call as a terminator and the decompiler truncated them. Clear the flag, then re-disassemble only
* the call sites of the functions that were cleared and refit their owning functions in place.
*/
public final class ReaGhidraNoReturnFix extends GhidraScript {
private static final Set<String> RETURNING_IMPORTS = Set.of(
"malloc", "__tls_get_addr", "memcpy", "memset", "strlen", "__errno_location");
@Override
public void run() throws Exception {
// Windows P0 does not admit analysis-database mutation.
if (System.getProperty("os.name", "").startsWith("Windows")) return;
FunctionManager fm = currentProgram.getFunctionManager();
Listing li = currentProgram.getListing();
Set<Address> cleared = new HashSet<>();
Deque<Address> pending = new ArrayDeque<>();
for (Function f : fm.getExternalFunctions()) {
monitor.checkCancelled();
// Do not apply import-name assumptions to local functions or to arbitrary externals.
if (!f.hasNoReturn() || !RETURNING_IMPORTS.contains(externalAbiName(f))) continue;
f.setNoReturn(false);
enqueueReturning(f, cleared, pending);
}
for (Function f : fm.getFunctions(true)) {
monitor.checkCancelled();
if (clearDecodedReturn(f, li)) {
enqueueReturning(f, cleared, pending);
}
}
int redone = 0;
TreeSet<Address> owners = new TreeSet<>();
while (!pending.isEmpty()) {
Address target = pending.removeFirst();
TreeSet<Address> sites = new TreeSet<>();
// References include computed import calls after Ghidra resolves their destination.
// Collect before redisassembly mutates the reference table.
for (Reference reference : currentProgram.getReferenceManager().getReferencesTo(target)) {
monitor.checkCancelled();
sites.add(reference.getFromAddress());
}
for (Address s : sites) {
monitor.checkCancelled();
Instruction ins = li.getInstructionAt(s);
if (ins == null) continue;
FlowType ft = ins.getFlowType();
if (!(ft.isCall() && ft.isTerminal())) continue;
Address[] flows = ins.getFlows();
boolean callsTarget = false;
for (Address flow : flows) {
if (flow.equals(target)) callsTarget = true;
}
if (!callsTarget) continue;
// Do not redisassemble into an independently identified function.
Address next = ins.getMaxAddress().add(1);
if (fm.getFunctionAt(next) != null || !currentProgram.getMemory().contains(next)) continue;
Function owner = fm.getFunctionContaining(s);
if (owner != null && !owner.isThunk()) owners.add(owner.getEntryPoint());
clearListing(ins.getMinAddress(), ins.getMaxAddress());
disassemble(s);
redone++;
// Refit the body in place so the name, signature and calling convention survive.
if (owner != null && !owner.isThunk()) {
CreateFunctionCmd.fixupFunctionBody(currentProgram, owner, monitor);
// Auto-analysis may have propagated the false flag to this truncated caller.
// Its RET becomes visible only now; repair its callers in the same pass.
if (clearDecodedReturn(owner, li)) enqueueReturning(owner, cleared, pending);
}
}
}
// No analyzeChanges here: on libpl2.so it adds about 70 s, which pushes startup past the 330 s deadline.
println(
"REA no-return fix: cleared=" + cleared.size() + " sites=" + redone + " refit=" + owners.size());
}
private void enqueueReturning(Function function, Set<Address> cleared, Deque<Address> pending) {
if (cleared.add(function.getEntryPoint())) pending.addLast(function.getEntryPoint());
// A thunk inherits the flag of the function it forwards to, including through other thunks.
Address[] thunks = function.getFunctionThunkAddresses(true);
if (thunks == null) return;
for (Address thunk : thunks) {
if (cleared.add(thunk)) pending.addLast(thunk);
}
}
private String externalAbiName(Function function) {
String name = function.getName();
// Mach-O stores C-linkage symbols with one object-format underscore prefix.
if (currentProgram.getExecutableFormat().contains("Mach-O") && name.startsWith("_"))
return name.substring(1);
return name;
}
private boolean clearDecodedReturn(Function function, Listing listing) throws Exception {
if (!function.hasNoReturn() || function.isThunk()) return false;
for (Instruction instruction : listing.getInstructions(function.getBody(), true)) {
monitor.checkCancelled();
FlowType flow = instruction.getFlowType();
if (flow.isJump() || flow.isCall()) continue;
for (PcodeOp operation : instruction.getPcode()) {
if (operation.getOpcode() != PcodeOp.RETURN) continue;
function.setNoReturn(false);
return true;
}
}
return false;
}
}
+8 -1
View File
@@ -553,7 +553,12 @@ def _search_results(document, kind, params):
if not matches(item[1]):
continue
selected.append(item)
return [{"address": address, **_string_inventory(document)[address]} for address, _ in selected] if kind == "string" else [
if not selected:
return []
if kind == "string":
records = _string_inventory(document)
return [{"address": address, **records[address]} for address, _ in selected]
return [
{
"address": address,
"value": value,
@@ -711,6 +716,8 @@ def _analyze_function(document, params):
"referenced_strings": referenced_strings,
"referenced_names": referenced_names,
"basic_blocks": blocks,
"native_api": None,
"native_value_flow": None,
"limitations": [
"Native CallReference classifications are observed where available; detailed reference flags remain unknown.",
"Hopper's public Python API does not expose equivalent external or thunk classification in this dossier.",
+1 -2
View File
@@ -55,7 +55,7 @@ export default defineConfig({
{ text: "Ghidra on Windows", link: "/windows-ghidra-p0" },
{ text: "Ghidra DOS analysis", link: "/ghidra-dos" },
{ text: "Ghidra NativeAOT", link: "/ghidra-nativeaot" },
{ text: "Provider evaluation", link: "/provider-evaluation" },
{ text: "Ghidra semantics", link: "/ghidra-provider" },
],
},
{
@@ -66,7 +66,6 @@ export default defineConfig({
{ text: "Tool design", link: "/tool-design" },
{ text: "Testing", link: "/testing" },
{ text: "Releasing", link: "/releasing" },
{ text: "Architecture decisions", link: "/adr/README" },
],
},
],
+170
View File
@@ -0,0 +1,170 @@
# ADB device inspection and acquisition
REA inspects connected Android devices, reads device state, and transfers
files and packages through the caller's `adb` binary. Emulators, USB
devices, and network devices participate alike: REA neither starts nor
manages them and never installs platform tools. Every operation composes a
fixed adb argument vector — caller values occupy positional arguments only
and are quoted when adb forwards them to the device shell.
The adb client may start its local server on first device query; that is adb
client behavior, recorded in the tool result when observed.
`inspect_adb_client` probes only the binary and never contacts the server.
## Supply tools
Use any Android platform-tools `adb` (verified with 34.0.5). Select it
through the environment:
```sh
# Optional: absolute path to the adb binary; without it, adb resolves from PATH.
export REA_ADB_PATH=/absolute/path/to/adb
```
REA never installs the Android SDK, an emulator, or a system image.
Readiness is `rea inspect-adb-client`: it runs `adb version` and reports the
resolved binary, its version, and where it was selected from. A missing
binary reports `capability_unavailable` with the `REA_ADB_PATH` remediation
rather than attempting an installation.
## Answer an analyst question
```sh
# Device identity
rea inspect-adb-client
rea list-adb-devices
rea inspect-adb-device emulator-5554
rea inspect-adb-display emulator-5554
rea list-adb-features emulator-5554
rea list-adb-services emulator-5554
# Find and acquire an app (the easy-get flow)
rea resolve-adb-packages emulator-5554 whatsapp
rea list-adb-packages emulator-5554 --scope third_party
rea inspect-adb-package emulator-5554 com.whatsapp
rea pull-adb-package emulator-5554 com.whatsapp --output-directory /tmp/acq
rea inspect-android-package /tmp/acq/com.whatsapp/base.apk
# Device state and files
rea list-adb-processes emulator-5554
rea inspect-adb-window emulator-5554
rea read-adb-setting emulator-5554 global adb_enabled
rea read-adb-logcat emulator-5554 --count 200
rea list-adb-directory emulator-5554 /data/data/com.whatsapp
rea pull-adb-file emulator-5554 /data/local/tmp/notes.txt --output-directory /tmp/acq
rea push-adb-file emulator-5554 /tools/frida-server /data/local/tmp/frida-server
rea capture-adb-screen emulator-5554 --output-directory /tmp/shots
rea collect-adb-bugreport emulator-5554 --output-directory /tmp/bugs
# Package lifecycle and dynamic analysis (device-mutating)
rea install-adb-package emulator-5554 /tmp/app.apk --replace
rea start-adb-app emulator-5554 com.example.app
rea read-adb-logcat emulator-5554 --pid 12345
rea start-adb-activity emulator-5554 android.intent.action.VIEW --data-uri https://example.com
rea stop-adb-app emulator-5554 com.example.app
rea uninstall-adb-package emulator-5554 com.example.app
```
Equivalent MCP methods use the snake_case names (`list_adb_devices`,
`pull_adb_package`, `resolve_adb_packages`, …). Device operations take
`serial` exactly as `adb devices` reports it. The pulled APK set feeds the
existing analysis families directly, for example
`rea inspect-android-package /tmp/acq/<package>/base.apk`.
## Operations
| Tool | Kind | What it does |
| ----------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inspect_adb_client` | read | Resolved binary, version, install path; never contacts the server |
| `list_adb_devices` | read | Serial, state, transport, model metadata, inferred emulator/physical kind with basis |
| `inspect_adb_device` | read | Fixed `getprop` whitelist: build, SDK, patch, fingerprint, product, ABIs, debuggable, `ro.kernel.qemu` |
| `inspect_adb_display` | read | `wm size` and `wm density` as declared |
| `list_adb_features` | read | `pm list features` (hardware/software features, hex GL versions) |
| `list_adb_services` | read | `service list` binder services and interfaces |
| `list_adb_processes` | read | `ps -A`: user, pid, ppid, rss, state, name |
| `inspect_adb_window` | read | `dumpsys window` focus declarations (what is on screen) |
| `read_adb_setting` | read | One `settings get` value; device-side null is reported as such |
| `read_adb_logcat` | read | Bounded `logcat -d -t` dump for one buffer, optional pid filter |
| `list_adb_packages` | read | `pm list packages -f` with scope; base APK device paths |
| `resolve_adb_packages` | read | Case-insensitive package-name substring search with exact-match flag |
| `inspect_adb_package` | read | `dumpsys package` projection: versions, install times, installer, flags, permission count |
| `list_adb_directory` | read | `ls -la`: kinds, permissions, owner, group, sizes, symlink targets |
| `pull_adb_package` | read | Complete split APK set from `pm path`, each file digested |
| `pull_adb_file` | read | One absolute device path pulled and digested |
| `capture_adb_screen` | read | One `screencap -p` frame (exec-out, no device-side file) with dimensions |
| `collect_adb_bugreport` | read | Device-generated bugreport zip, digested |
| `push_adb_file` | **mutates device** | One local file to a device path (e.g. pushing tools into `/data/local/tmp`); refuses existing targets without explicit overwrite; verifies via the device's own sha256sum |
| `install_adb_package` | **mutates device** | Local APK via `adb install [-r]`; preserves the device's Success/Failure verdict |
| `uninstall_adb_package` | **mutates device** | Removes a package and its data for user 0 |
| `start_adb_app` | **mutates device** | Resolves the package's launcher activity (`cmd package resolve-activity --brief`) and starts it (`am start -n`) |
| `start_adb_activity` | **mutates device** | Starts an intent (`am start -a` with optional URI, component, and up to 16 typed extras); preserves the activity manager's verdict |
| `stop_adb_app` | **mutates device** | Force-stops every process of a package, ending a dynamic-analysis run |
## Interpret the result
- **Inferences carry their basis.** Device `kind` reports
`kind_basis` (serial prefix or USB transport); APK `role` reports
`role_basis: file_name`; `emulator_observed` is the build's own
`ro.kernel.qemu` value, `null` when absent.
- **Device paths are not host paths.** `base_apk_device_path` values live on
the device filesystem. Only pulls and captures produce host-local paths,
each paired with byte size and SHA-256 digest.
- **Splits are part of the answer.** `pm path` enumerates the base APK and
every installed split; pulls cover the whole set. System packages whose
APKs keep other names report the `unknown` role rather than guessing.
- **Partial results keep facts.** Failed individual pulls return successful
artifacts with `coverage: "partial"` and per-file `failures`. Listings
that contain unrecognized lines report them as `unparsed_lines` and mark
partial coverage instead of dropping rows.
- **Mutations are explicit.** `push_adb_file`, `install_adb_package`, and
`uninstall_adb_package` declare `mutatesTarget` and never run implicitly:
pushes refuse existing device files unless `overwrite` is set and verify
the transfer with the device's own `sha256sum`; installs preserve the
device's `Failure [...]` reason verbatim.
- **Producer identity stays attached.** Every result embeds the producing
adb client (`binary_path`, `path_source`, `version`, `installed_path`).
## Resource and lifecycle limits
- Caller values reach adb only as positional arguments in fixed vectors;
no tool accepts an arbitrary shell command line, and UI interaction
(`input`, `am`, `monkey`) is deliberately not exposed.
- Per-invocation budgets: client/devices 10-20 s, shell reads 20-60 s with
64 KiB-8 MiB capture caps (logcat 4 MiB, screen 32 MiB), transfers and
bugreports 600 s. Exceeded budgets report `resource_constraint`; stopped
commands report `provider_timeout`.
- Pull and capture outputs are additive: the destination must not already
exist. Re-running a completed pull refuses the existing directory instead
of overwriting evidence.
- Cancellation during a package pull preserves caller-selected output. The
error includes partial observations identifying completed artifacts and the
interrupted local path; remaining APKs were not attempted.
- Failed package acquisition rollback retains its directory identity and retries
cleanup before later work and during shutdown. Cleanup refuses a replacement
directory. Terminal shutdown stops admission and drains active operations.
- The provider holds no long-lived processes; every invocation is one
bounded adb run. The adb server belongs to the caller.
## Related capability and follow-up lanes
UI interaction beyond intent starts (tapping, typing, monkey fuzzing, screen
recording) remains a separate lane: candidates such as
[mobile-device-mcp](https://github.com/srmorete/mobile-device-mcp) install
driver software on the device and pair with the Frida instrumentation lane
(#1359) behind explicit mutation-authority contracts. Network transports
beyond already-connected devices (`adb connect`) are not exposed yet.
## Real verification
`npm run verify:adb` exercises every operation against a live device. It
requires `adb` (or `REA_ADB_PATH`) and any attached emulator or phone;
`--serial` selects one when several are attached, `--pull PACKAGE` pulls a
real package and verifies the returned digests against the files on disk,
and `--install-apk PATH` drives a full install → resolve → uninstall
lifecycle with a lane-owned probe.
Record: verified against adb 34.0.5 on Linux against an Android 14
(API 34) x86_64 emulator — all operations above, a 224-package inventory,
287 services, 92 features, a real two-APK split set pulled with byte-exact
digests, a verified push/pull roundtrip, a 1.3 MB screen capture, and the
complete package lifecycle; see `docs/testing.md` for the lane summary.
@@ -1,578 +0,0 @@
# ADR-0001: Provider selection and analysis profiles
- Status: Accepted
- Date: 2026-07-15
- Implementation status: The provider registry, deterministic selection,
target binding, analysis-profile commitment, and snapshot/Evidence migration
are implemented. Ghidra discovery, target/profile resolution, doctor checks,
the private headless-session foundation, thirteen read-only inventory/load-image
capabilities, and twelve function-analysis capabilities are implemented with
real cross-format conformance. Linux/macOS also supports atomic session
function annotations; experimental Windows x64 P0 uses bundled native controls
and admits only the 25 read-only operations. See the
[release boundary](../installation.md#released-package-and-main).
## Context
Before this decision, REA composed the artifact, native macOS, and Hopper
providers with `CompositeProvider`. That class intentionally requires every
operation to have one route. Hopper and Ghidra will both implement the deep
static-analysis operation family, so putting both into that composite would
either fail at construction or make array order an undeclared selection policy.
The active `BinarySession` also owned one composite client. `open_binary` had no
provider selector, and the domain `BinaryTarget` contained Hopper loader
arguments. Analysis snapshot v1 committed those loader arguments and each
cached entry's provider identity, but it did not commit the selected analysis
engine, engine version, or complete analysis configuration. Two analyses of the
same bytes could therefore disagree because of language, compiler, loader,
analyzer, or provider-version differences while appearing target-compatible.
The decision addressed the earlier representations of
[`CompositeProvider`](https://github.com/morluto/rea/blob/main/src/application/binary/CompositeProvider.ts),
[runtime composition](https://github.com/morluto/rea/blob/main/src/composition/binary.ts),
[`BinarySession`](https://github.com/morluto/rea/blob/main/src/application/binary/BinarySession.ts),
[`BinaryTarget`](https://github.com/morluto/rea/blob/main/src/domain/binaryTarget.ts),
[analysis snapshot](https://github.com/morluto/rea/blob/main/src/domain/analysisSnapshot.ts), and
[session lifecycle inputs](https://github.com/morluto/rea/blob/main/src/contracts/sessionLifecycleInputs.ts).
The next deep provider must not weaken the existing product invariants:
- stable provider-neutral CLI and MCP tool names;
- exact provenance and explicit unavailable or degraded capabilities;
- CLI and MCP parity;
- no silent provider fallback;
- provider-specific code outside the domain and application models;
- local, actionable diagnostics with only genuine secrets redacted; and
- snapshot reuse only when semantic analysis inputs are identical.
## Decision drivers
1. Hopper and Ghidra need to declare overlapping operations without ambiguous
dispatch.
2. A target must have one explainable deep-analysis producer for its lifetime.
3. Target-free discovery must remain useful and must not start an analysis
process.
4. Existing Hopper-only configurations must keep working when no selector is
supplied.
5. Adding a second installed provider must not silently change results.
6. Snapshot and Evidence compatibility must include every setting that can
materially change analysis.
7. Provider-specific open settings must not leak into `BinaryTarget` or become
generic application fields.
## Terminology
- **Deep provider**: an engine such as Hopper or Ghidra that implements the
overlapping static-analysis operation family.
- **Auxiliary provider**: a provider with a disjoint operation family, such as
artifact inventory or native macOS inspection.
- **Candidate**: a registered deep provider before target selection.
- **Binding**: the selected deep provider and analysis profile attached to one
active target.
- **Analysis profile**: a canonical commitment to the selected provider,
provider version, and normalized semantic analysis settings.
- **Available**: the adapter and its required local runtime can be used on this
host.
- **Supported**: the candidate accepts the parsed target and supplied open
options. Availability and target support are separate observations.
## Decision
### 1. Separate disjoint composition from overlapping selection
`CompositeProvider` remains the mechanism for operation families whose routes
are disjoint. It must continue rejecting duplicate operation declarations. It
must not acquire priority, racing, fallback, or provider-selection behavior.
A new `AnalysisProviderRegistry` owns the configured deep-provider candidates.
Provider IDs are unique; duplicate IDs are a configuration error. The registry
may hold multiple candidates that declare the same operation. It performs
candidate discovery, target-support evaluation, option parsing, profile
resolution, and selection, but it does not choose a different provider for each
request.
After selection, the session composes exactly one bound deep provider with the
auxiliary disjoint families:
```text
target-free discovery
|
AnalysisProviderRegistry
/ \
Hopper Ghidra
\ /
one selected binding
|
+-------------------------+-------------------------+
| | |
selected deep family artifact family native family
+-------------------------+-------------------------+
|
BinarySession
```
An auxiliary operation continues to report its actual auxiliary provider as
provenance. A deep operation always reports the provider in the active binding.
The synthetic composite identity is never evidence that two engines jointly
produced one observation.
Operation ownership is fixed by family:
| Operation family | Executor |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| Deep direct operations and provider-native function analysis | The one bound Hopper or Ghidra provider |
| Application-enhanced deep workflows | Application composition over the bound provider's declared operations |
| Native macOS inspection | The disjoint native provider |
| Artifact inventory and extraction | The disjoint artifact provider |
| Browser and Electron observation | Their independently authorized CDP providers; they do not participate in deep-provider selection |
| Session lifecycle, Evidence, comparisons, and reconstruction | The application/session layer using the exact provider provenance recorded by their source operations |
Selecting a deep provider selects the whole deep family. If that provider marks
an operation unavailable, REA returns the unavailability; it does not borrow
that one operation from another deep provider. Application-enhanced workflows
run only when the bound provider supplies their declared dependencies.
### 2. Discover candidates without launching analysis
Each registered candidate exposes three bounded adapter-owned observations:
1. identity and declared capability descriptors;
2. host availability, including an actionable rejection when unavailable; and
3. target support plus normalized profile resolution when a target is known.
Target-free discovery may inspect configuration, manifests, executable
metadata, and documented version files. It must not import a target, create a
project, open a GUI, or start the long-lived analysis process. Any short-lived
version probe added later must be explicitly bounded and truthfully declared as
a process effect.
Candidate output is sorted by provider ID for determinism. Sort order is not
selection priority. Availability and support use stable codes plus a human
diagnostic:
| Code | Meaning |
| ---------------------------- | --------------------------------------------------------------- |
| `not_configured` | Required provider location or configuration is absent |
| `executable_missing` | The configured provider entry point is missing or not runnable |
| `runtime_missing` | A required provider runtime, such as Java, is unavailable |
| `unsupported_host` | The host platform or architecture is unsupported |
| `unsupported_version` | The discovered provider or runtime version is unsupported |
| `target_kind_unsupported` | The provider does not accept this target kind |
| `target_format_unsupported` | The provider does not accept this target format |
| `architecture_unsupported` | The selected target architecture is unsupported |
| `target_role_unsupported` | The provider rejects this executable image role |
| `managed_target_unsupported` | The provider does not admit managed code through this deep path |
| `open_options_invalid` | The selected adapter rejected its open options |
| `version_unresolved` | A concrete analysis-engine version could not be committed |
Diagnostics retain useful local paths, observed versions, architectures, and
mismatch details. Credentials, authorization headers, license secrets, and
other genuine secrets remain redacted.
### 3. Use one deterministic selection algorithm
The caller-visible selectors are:
- MCP `open_binary.provider_id`;
- `rea ... --provider <provider-id|auto>` on every one-shot command that needs
deep analysis; and
- `REA_ANALYSIS_PROVIDER=<provider-id|auto>`, defaulting to `auto`.
The literal value `auto` is reserved and cannot be a provider ID. Precedence is
request or CLI flag, then environment configuration, then the default `auto`.
An explicit request for `auto` overrides a concrete environment preference and
re-enters automatic selection.
Selection occurs after provider-neutral target parsing and before a deep client
is created:
1. A concrete requested provider ID must exist, be available, support the
target, accept its options, and resolve a concrete version and profile. Any
failure returns a typed selection error; another provider is never tried.
2. `auto` filters candidates by availability and target support.
3. Exactly one usable candidate is selected with source
`auto-single-candidate`.
4. More than one usable candidate is an `ambiguous` selection error. The
diagnostic lists the candidates and asks for `provider_id`, `--provider`, or
`REA_ANALYSIS_PROVIDER`. REA does not prefer Hopper, Ghidra, registration
order, the fastest startup, or the first health response.
5. When no deep candidate is usable, an automatic open may still establish an
unbound target so disjoint artifact or native operations remain available.
Deep operations are then explicitly unavailable with the candidate
rejections. A concrete request, or a concrete environment preference for a
deep-eligible target, remains a hard requirement and fails instead of
becoming unbound.
6. A target that no deep adapter declares support for, such as an artifact-only
target, is `not_applicable` rather than a failed deep analysis. Supplying a
concrete provider in that open request is still an actionable unsupported-
target error. A global environment preference does not make an artifact-only
target require a deep provider.
This preserves target opening for non-Hopper capabilities on hosts without a
deep engine while ensuring that installing a second usable deep engine never
changes analysis silently.
### 4. Bind once and never fail over mid-session
An active deep binding contains:
```text
canonical target identity
selected provider identity and concrete version
selection source: request | environment | auto-single-candidate
analysis profile commitment
owned provider client, once started
```
The binding is immutable until `close_binary` or an explicit open/switch
transaction. Provider client creation may remain lazy, but laziness cannot
change which provider was selected.
- Opening the same canonical target without a new selector keeps the existing
binding.
- Opening the same target with the same provider and profile is idempotent.
- A different explicit provider or a profile-changing option is a real switch:
drain active calls, close owned resources, resolve the new binding, and start
it as one serialized transaction.
- If a switch fails, restore the prior target and binding on a best-effort
transactional path and return the original switch error.
- Provider process exit, timeout, cancellation, capability failure, or adapter
error never triggers fallback. The binding stays visible and unavailable
until the caller explicitly switches or closes it.
- A snapshot never chooses or changes the provider. Selection happens first;
snapshot compatibility is checked against the resulting binding.
Calls already admitted to one binding complete or cancel against that binding.
No request can cross a concurrent target or provider transition.
### 5. Keep provider open options adapter-owned
`BinaryTarget` retains only provider-neutral source identity and classification:
canonical path, source digest, generic kind and format, selected architecture,
and available architectures. Hopper loader arguments leave the domain model.
Provider-owned databases use a generic analysis-database classification; their
adapter determines support. A legacy `.hop` target is therefore accepted only
by Hopper without teaching the domain how to open it. Ghidra v1 continues to use
private temporary projects and does not open user projects.
The generic transport may carry one bounded JSON `provider_options` object.
Only the selected adapter parses its keys and reports `open_options_invalid` at
that boundary. If this object is exposed over MCP, the CLI parity surface is
`--provider-options-json` with the same JSON schema and limits. Unknown keys,
wrong-provider options, excessive depth or size, and non-JSON values fail
closed.
Environment settings that are inherently adapter-specific, such as the Hopper
launcher or future Ghidra installation path, remain in adapter configuration.
They do not become `BinaryTarget` fields. The application layer transports an
opaque, already-bounded JSON value and the generic commitment described below;
it does not interpret Hopper or Ghidra option names.
### 6. Commit a canonical analysis profile
Before creating a deep client, the selected adapter normalizes every semantic
input that can affect analysis. Examples include Hopper loader selection and
architecture flags, or Ghidra language ID, compiler specification, import mode,
analyzer set, and analyzer options. Defaults are made explicit, unordered sets
are sorted, and implicit host-dependent choices are resolved.
The adapter returns this provider-neutral envelope:
```json
{
"provider": { "id": "ghidra", "version": "<concrete version>" },
"parameters": {},
"digest": "<sha256 of RFC 8785 canonical JSON excluding digest>"
}
```
`parameters` is bounded JSON interpreted only by that provider adapter. It
contains analysis semantics, not credentials, authorization data, temporary
paths, installation paths, process IDs, timestamps, or other incidental host
state. The generic domain validates the envelope and digest but treats the
parameters as opaque data.
A selected deep binding requires a concrete provider version. If the adapter
cannot determine it, the candidate is unavailable with `version_unresolved`;
REA does not persist a cache that merely commits `null` or "whatever is
installed". Provider identity, normalized parameters, or provider version
changes produce a different digest.
The same target, configuration, and provider must resolve the same profile over
CLI and MCP. Profile resolution must be side-effect-free and complete before
the provider imports the target.
### 7. Make snapshots provider- and profile-exact
Analysis snapshots replace Hopper loader arguments with an explicit binding
commitment:
```text
target: digest + generic format/kind + selected architecture
binding: provider identity + analysis profile commitment
entries: exact immutable queries
evidence_bundle: retained Evidence records
```
The snapshot target identity, canonical snapshot content digest, and every
query ID commit the provider ID, concrete provider version, and profile digest.
A cached entry is reusable only when all of the following match exactly:
- target digest, generic format and kind, and selected architecture;
- provider ID and provider version;
- profile digest;
- operation and canonical parameters; and
- the existing cacheability and immutability rules.
Provider or profile switches select a separate cache partition and cannot reuse
entries from the previous binding. Auxiliary operations are cacheable only if
their provider defines an equivalent explicit profile commitment; otherwise
they remain Evidence but not snapshot entries.
Snapshot v1 cannot be parsed as the current snapshot format. Its `loader_args`
cannot prove which engine version, defaults, or analyzer settings produced the
entries, so snapshots must be recaptured before they can be used as a cache.
An embedded Evidence bundle can still be imported separately through the
Evidence import flow; it is never promoted into an analysis cache.
### 8. Add profile commitments to new deep Evidence while preserving legacy records
The optional `analysis_profile` field uses the canonical envelope above. Every
newly created deep-analysis observation must include it, and its provider ID
and version must match the record's provider. The field participates in the
Evidence semantic ID.
Existing Evidence records without `analysis_profile` remain valid and keep
their existing IDs. Absence on a legacy deep record means the analysis profile
is unknown; REA does not infer or enrich it during import. Such evidence can be
displayed and cited but cannot establish profile compatibility, seed snapshot
replay, or support an "unchanged" conclusion that depends on identical analysis
semantics.
Different providers or profile digests are never snapshot-compatible. A
derived comparison may compare cross-provider normalized facts only when its
own contract explicitly defines that semantic comparison. Exact pseudocode,
provider text, or provider-specific metadata is not treated as equivalent. A
missing or incompatible profile yields unknown or incompatible, never equal.
### 9. Expose selection truth in status and diagnostics
`binary_session`, `rea providers`, and `rea capabilities` expose the same
candidate and binding model. The target-free form does not start providers and
uses `unknown` for target support:
```json
{
"analysis_provider_binding": null,
"analysis_provider_candidates": [
{
"provider": {
"id": "hopper",
"name": "Hopper Disassembler",
"version": "<detected version>"
},
"availability": {
"status": "available",
"code": null,
"reason": null,
"diagnostics": {}
},
"target_support": {
"status": "unknown",
"code": null,
"reason": "No target is open."
},
"selected": false,
"capabilities": []
}
]
}
```
With a binding, `analysis_provider_binding` includes the selected identity,
selection source, and complete profile commitment. Every candidate reports
`supported`, `unsupported`, or `unknown` target support and whether it was
selected. Candidate capability descriptors preserve supported, unsupported,
and degraded truth independently.
An open target also exposes `analysis_run`. Its run ID is allocated by the
session before client construction and propagated into selected Hopper or
Ghidra bridge handshake and process environment. Dynamic clients retain
provider-attributed lineage snapshots only after revalidating launcher
parent/command and every observed launcher or descendant run token. `not_observed`
means no dynamic provider has supplied a snapshot. Once one or more start,
`snapshots` preserves every provider observation; each remains explicitly
`unavailable` or `verified` and records its `observed_at` time. Retained
snapshots are not live inventories, and a point-in-time observation never proves
historical absence.
The existing flat `provider`, `providers`, and `capabilities` status fields stay
during the 1.x compatibility window. Their effective deep-operation entries
come only from the active binding; target-free ambiguity is unavailable rather
than arbitrarily collapsed. The new candidate fields are authoritative for
selection. A future major release may remove the synthetic composite provider
field after callers have migrated.
Selection failures extend the tagged `ProviderSelectionError` with a stable
reason:
- `unknown_provider`;
- `provider_unavailable`;
- `target_unsupported`;
- `ambiguous`;
- `invalid_options`.
The error includes the requested ID or `auto`, candidate IDs, rejection codes,
and actionable local diagnostics. `AnalysisCapabilityUnavailableError` remains
the error for an operation the selected provider cannot supply.
`ProviderAdapterError` and more specific provider errors remain failures of the
already selected provider. None authorizes fallback.
A snapshot whose provider or profile differs from the selected binding returns
`EvidenceIntegrityError` with stable `profile_mismatch` details. It is an
integrity incompatibility after selection, not permission to select the
snapshot's provider.
### 10. Preserve CLI and MCP parity
- `open_binary.provider_id` and one-shot `--provider` use the same parser and
selection service.
- `provider_id: "auto"`, `--provider auto`, and
`REA_ANALYSIS_PROVIDER=auto` have identical auto semantics.
- Startup targets opened from environment configuration use the same service.
- `rea providers`, `rea capabilities`, and target-free `binary_session` use the
same candidate snapshot and reason codes.
- Guided prompt `provider_id` context is a preference to forward into the open
operation; it does not create a hidden routing channel.
- Tool names and normalized output contracts remain provider-neutral. REA does
not add `ghidra_decompile` or `hopper_decompile` tools.
## Compatibility and migration
| Existing behavior or data | Decision |
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| No provider selector, only Hopper usable | `auto` selects the sole candidate; behavior remains equivalent |
| No deep provider usable | Automatic open may remain unbound for auxiliary operations; deep capabilities explain why they are unavailable |
| Hopper and Ghidra both usable, no preference | Open fails with `ambiguous`; installation order never becomes policy |
| Existing Hopper environment settings | Remain supported as Hopper adapter configuration |
| `open_binary` and CLI structured `loaderArgs` output | Retained as a deprecated Hopper-only compatibility projection for 1.x; the analysis profile is authoritative |
| `BinaryTarget.loaderArgs` | Removed; Hopper derives them inside its adapter and commits normalized semantics in the profile |
| Legacy `.hop` input | Classified generically as an analysis database and accepted only by Hopper |
| Snapshot v1 | Not accepted as the current snapshot format; recapture before cache replay |
| Existing Evidence without a profile | Accepted unchanged; profile compatibility is unknown |
| New deep-analysis Evidence | Must include `analysis_profile`; its semantic ID commits the field |
| Existing status fields | Retained for 1.x with additive binding and candidate fields |
| Provider failure after selection | Returned from the selected provider; no transparent retry through another engine |
The deprecated `loaderArgs` response must never be read to select a provider or
validate a snapshot. It is empty for non-Hopper bindings and may be removed only
with a separately documented major contract change.
## Required behavior scenarios
| Scenario | Result |
| ---------------------------------------------------------- | --------------------------------------------------------------------------- |
| Hopper is the only usable candidate, selector omitted | Hopper is bound by `auto-single-candidate` |
| Ghidra is the only usable candidate, selector omitted | Ghidra is bound by `auto-single-candidate` |
| Both are usable, selector omitted | Typed `ambiguous` error; neither provider starts |
| Environment selects Ghidra, request omits a selector | Ghidra is required and bound or the open fails with its rejection |
| Environment selects Ghidra, request selects Hopper | Request wins; Hopper is required |
| Environment selects Ghidra, request selects `auto` | Auto policy runs and is ambiguous when both are usable |
| Unknown concrete provider ID | Typed `unknown_provider`; no target transition |
| Selected provider rejects the target or options | Typed rejection from that candidate only |
| Selected provider times out after binding | Binding remains selected and unavailable; no fallback |
| Same target is reopened without a selector | Existing binding remains unchanged |
| Same bytes are opened with a different profile | Real provider switch and a separate snapshot partition |
| Snapshot provider or profile differs from the binding | Typed `EvidenceIntegrityError` with `profile_mismatch`; nothing is imported |
| Artifact-only target has no deep candidate | Target opens unbound; disjoint artifact capabilities remain usable |
| Environment prefers Ghidra for an artifact-only target | Deep selection is `not_applicable`; auxiliary operations remain usable |
| Concrete deep provider is requested for artifact-only data | Typed `target_unsupported`; the request is not silently ignored |
## Consequences
Positive consequences:
- Hopper and Ghidra can coexist without ambiguous operation routes.
- Provider choice is reproducible, visible, and stable for a target.
- Installation of another provider cannot silently change analysis.
- Snapshot and Evidence identities become analysis-configuration aware.
- Provider adapters retain ownership of their option schemas and diagnostics.
- Auxiliary capabilities remain usable when no deep engine is installed.
Costs and tradeoffs:
- Multi-provider hosts must choose when more than one candidate is usable.
- Snapshots must be recaptured when their provider or profile binding changes.
- Providers must expose deterministic availability, support, version, and
profile resolution before they can be admitted.
- Status and error contracts gain additive structured metadata.
- Hopper needs an adapter-owned version/profile implementation before profile-
exact snapshot persistence is complete.
## Rejected alternatives
### Let `CompositeProvider` choose the first duplicate route
Array order is not a product policy, becomes fragile during wiring changes, and
hides ambiguity from callers.
### Race providers and keep the first healthy response
Machine load would determine provenance and results. It also starts resources
the operator did not select and makes cancellation and cleanup harder.
### Fall back after a provider error
Mid-session fallback can combine incompatible engine state and evidence under
one apparent target. Explicit close or switch is required instead.
### Add provider-prefixed tools
Parallel Hopper and Ghidra tool families would leak adapters into the product
contract and prevent shared workflows from using capability metadata.
### Store raw provider options in `BinaryTarget`
That repeats the current Hopper coupling and makes every generic consumer learn
provider schemas. Only canonical profile commitments cross the adapter boundary.
### Treat matching target bytes and provider ID as sufficient for snapshots
Provider versions, analyzer defaults, loaders, languages, and compiler models
can change results without changing either value.
### Silently upgrade snapshot v1
The missing engine version and analysis settings cannot be reconstructed from
Hopper loader arguments. A fabricated profile would turn unknown provenance
into false certainty.
## Implementation progress
The first six implementation stages are shipped:
1. Provider-specific target state was replaced by generic profile and snapshot
v2 commitments while preserving Hopper execution behavior.
2. The registry, selectors, candidate status, binding lifecycle, and
overlapping-provider production seams were added.
3. Proven process-lifecycle primitives were extracted for shared use.
4. Ghidra availability, target/profile resolution, doctor checks, and a private
read-only headless session were admitted without declaring operations.
5. Program identity, procedures, strings, symbols, memory blocks,
address/name resolution, containing-procedure resolution, and search
were admitted with exact wire schemas and real debug/stripped ELF
conformance.
6. Function metadata, persistent decompilation, assembly, resolved
callers/callees, typed references, xrefs, CFG, and complete function dossiers
were admitted. A serial per-Program queue keeps API access ordered without a
fixed queue length or per-operation deadline. Real conformance covers
x86-64 and AArch64 ELF, PE, Mach-O, stripped symbols, targetless indirect
calls, cancellation, and cleanup.
Future stages may deepen format and indirect-flow coverage, but must continue
to compare normalized semantics rather than provider-specific pseudocode or
assembly text. Linux and macOS now admit atomic function-name and entry-comment
edits in the ephemeral database, with readback, rollback, and cache invalidation.
Executable bytes remain unchanged. Windows P0 retains its read-only boundary;
GUI and other unimplemented mutations remain unavailable.
@@ -1,551 +0,0 @@
# ADR-0002: Controlled JavaScript replay authority and sandbox policy
- Status: Superseded; the controlled JavaScript replay tool was removed
- Date: 2026-07-16
- Implementation status: The implementation was removed. The design below is
retained as historical context and does not describe a supported REA tool.
> Historical design note: The tool, sandbox backend, and plan/execute workflow
> described here are no longer part of REA. For runtime behavior, run probes
> directly against the application and use the available browser, Electron, or
> process capture workflows.
## Context
REA can reconstruct JavaScript and Electron artifacts, observe an existing
browser or Electron page through passive CDP, capture an explicitly approved
process scenario, and correlate those observations without executing bundle
code in the REA server. The next research workflow needs to execute selected,
extracted JavaScript modules with controlled inputs and deterministic stubs so
that parsers, sanitizers, serializers, and similar pure logic can be compared
across versions.
That workflow crosses a qualitatively different boundary. Source recovered
from an application is untrusted code. It can intentionally or accidentally
read files, contact services, spawn processes, exhaust resources, corrupt the
analysis process, forge protocol output, or interact with another same-user
process. A JavaScript realm or Node.js `vm` context is useful for constructing
an API surface, but it is not a security boundary. Node.js also documents its
permission model as protection against accidental access by trusted code, not
as containment for malicious code.
Existing authorities cannot be widened to cover this behavior:
- `browser_observe` and `electron_observe` authorize passive attachment to an
already-running, operator-owned target. They do not authorize evaluation,
navigation, input, or target lifecycle changes.
- `process_capture` authorizes one declared host process scenario and explicitly
states that it is not a sandbox. It cannot silently become permission to run
recovered code.
- static artifact reads authorize inspection of bytes, not execution of those
bytes.
- the Evidence authority `controlled-replay` already describes observations
from an approved process experiment. Reusing that epistemic authority is
correct, but reusing the process permission capability is not.
The implementation following this ADR must fail closed on hosts where REA
cannot establish the promised operating-system boundary. It must not copy the
research `vm.runInContext` scripts into the production server and call that
isolation.
## Decision drivers
1. Passive observation must never imply authority to execute application code.
2. The exact code, inputs, stubs, runtime, sandbox policy, and limits approved
by the operator must be the ones executed.
3. Recovered code must not run in the MCP server, CLI adapter, or any provider
process.
4. A sandbox failure must make the capability unavailable, not select a weaker
execution mode.
5. The default policy must provide no host network and no writable host path.
6. Time, memory, process count, temporary storage, protocol, and output must be
bounded independently.
7. Results must distinguish an observed return, an observed exception or
termination, a derived comparison, and an unresolved application-level
claim.
8. A reproducer must commit enough provenance to detect every relevant change
without committing proprietary application source to the repository.
9. CLI and MCP must expose the same plan, approval, execution, cancellation,
failure, and Evidence semantics.
## Terminology
- **Passive observation**: bounded reads from an existing browser or Electron
target without evaluating code, driving input, navigating, or controlling
its lifecycle.
- **Controlled replay**: execution of operator-selected code in a declared,
isolated environment with committed inputs and limits. This is an Evidence
authority, not a claim that the real application behaved identically.
- **Extracted-module replay**: the only admitted JavaScript replay mode in v1.
REA evaluates a finite manifest of module bytes and explicit stubs without
launching the application.
- **Application interaction**: launching or driving the original application,
browser, renderer, or Electron main process. This is not extracted-module
replay and is not authorized by this ADR.
- **Replay plan**: the canonical, content-addressed description of one proposed
run before execution.
- **Replay worker**: the disposable Node.js process inside the OS sandbox. It
is never the REA server process.
- **Sandbox backend**: the OS mechanisms and adapter that establish namespaces,
resource controls, filesystem visibility, and owned cleanup.
## Threat model
### Protected assets
The boundary protects:
- the REA MCP/CLI process, its memory, credentials, sockets, and Evidence
ledger;
- user files outside the approved source reads and all host files from writes;
- other same-user processes and their control interfaces;
- host network interfaces, loopback services, Unix sockets, and external
services;
- process, memory, CPU, temporary-storage, output, and protocol capacity;
- the integrity of the replay plan, result, Evidence provenance, and exported
reproducer; and
- proprietary module bytes, which remain local and are never repository
fixtures.
### Adversaries and failure sources
REA treats all of the following as untrusted:
- recovered module source, including transitive modules and source maps;
- caller-provided JavaScript stubs;
- structured test inputs and generated fuzz cases;
- returned values, exceptions, console data, and worker protocol messages;
- source paths, symbolic links, and files that can change between planning and
execution; and
- a worker that crashes, hangs, forks, allocates aggressively, or exits while
descendants remain alive.
An operator-controlled sandbox executable, kernel, Node.js runtime, and REA
installation are trusted computing base. A hostile host administrator, kernel
or sandbox vulnerability, hardware side channel, and denial of service by an
already-compromised same-user process are out of scope. These exclusions do not
permit REA to omit the per-run resource controls in this decision.
### Required mitigations
The implementation must address:
| Threat | Required control |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Server-process compromise | Separate worker process inside the OS sandbox; no in-process fallback |
| Host file reads | Empty sandbox root; only a minimal read-only runtime closure; module bytes enter over a private bounded channel |
| Host file writes | No writable bind mounts; size-limited private tmpfs only |
| Network access | Separate network namespace with no host or external connectivity; no allowlist mode in v1 |
| Host process control | PID/user/IPC/UTS isolation, no inherited control sockets, new session, dropped capabilities |
| Kernel escape/inspection surface | Architecture-checked seccomp denial policy in addition to namespaces, capabilities, and cgroups |
| Fork, memory, or CPU exhaustion | Per-run cgroup v2 task, memory, swap, and CPU limits plus an outer wall-clock deadline |
| Output/protocol exhaustion | Independent byte/message/depth limits enforced by the parent before parsing or retaining output |
| Symlink and file-change races | Canonical authorization, descriptor-backed reads, digesting, staging, and exact plan revalidation |
| Undeclared dependencies | Closed module manifest; exact imports only; missing/dynamic imports fail rather than use host resolution |
| Nondeterministic globals | Versioned clock, PRNG, locale, timezone, platform, and API stubs; undeclared globals are unavailable |
| Orphan descendants | Owned PID namespace and cgroup kill followed by an observable empty-cgroup cleanup check |
| Forged result claims | Framed worker protocol, strict schemas, parent-computed commitments, and bounded stderr kept separate |
| Secret leakage | Empty environment, no credential inheritance, bounded local results, and existing genuine-secret redaction |
## Decision
### 1. Add a distinct `javascript_replay` permission capability
JavaScript replay receives a new permission capability named
`javascript_replay`. It does not inherit, imply, or satisfy
`process_capture`, `browser_observe`, `electron_observe`, artifact-read, or
workspace permissions. Grants for any of those capabilities do not satisfy a
JavaScript replay request, and a JavaScript replay grant does not authorize
them.
The administrator ceiling is disabled by default. Its eventual configuration
must commit:
- canonical roots from which module and optional stub files may be read;
- the exact Node.js and sandbox-backend executables;
- filesystem mount authority needed only to construct the private sandbox;
- network mode `none`; and
- no inherited environment names.
Configuration establishes only the maximum authority. Every execution also
requires an active permission grant and literal per-call approval bound to the
exact replay plan. Project, session, and administrator grants may satisfy the
permission-policy layer, but none replace that per-run approval.
Reproducer export is a separate host write after the sandbox has stopped. This
ADR's root-scoped `evidence_write` authority was removed; current exports use
the path supplied by the caller, while replay still waits for complete sandbox
cleanup before writing.
### 2. Admit extracted modules only
The v1 mode executes a finite, closed manifest of JavaScript modules. The
manifest identifies one entry module and every admitted dependency by a stable
sandbox alias and SHA-256 digest. Imports resolve only to another manifest
entry or to an explicitly declared, versioned stub. Bare package lookup,
ambient `node_modules`, import maps from the host, network imports, native
addons, WASI, FFI, child processes, workers, inspector activation, and implicit
dynamic import are unavailable.
Modules and stubs are read and hashed by the authorized parent, then copied as
bytes through a bounded private channel. Original host paths are not mounted
into the sandbox. The worker cannot reopen the operator's source path.
Source maps may supply locations, but source-map source code is not executed
unless its bytes are separately present in the approved manifest. A source-map
name or Webpack module ordinal is never execution authority.
REA does not launch, attach to, navigate, click, type into, or terminate the
user's application under this capability. A full application process remains
an independently approved Process Capture experiment; browser and Electron
targets remain passive. Any future mode that drives an application or permits
host/allowlisted network requires a new ADR and a distinct permission scope.
### 3. Use a two-phase, content-bound approval flow
One public replay surface supports a plan phase and an execute phase with the
same schema through CLI and MCP.
The plan phase:
1. validates all caller input and hard limits before file access;
2. obtains authority to read every selected module or stub path;
3. canonicalizes and opens each file without following an unapproved identity;
4. reads bounded bytes, computes digests, and closes the source descriptors;
5. resolves and probes the exact runtime and sandbox backend without running
application code;
6. normalizes stubs, inputs, generator settings, and limits; and
7. returns the complete proposed effects and a canonical `plan_digest`.
The plan must disclose at least:
- module aliases, canonical local paths, byte counts, and SHA-256 digests;
- input and stub identities, provenance, and digests;
- runtime and sandbox executable paths, versions, and executable digests;
- sandbox policy version and digest;
- network `none`, visible read-only runtime paths, and private writable tmpfs
size;
- time, CPU, memory, swap, task, temporary-storage, input, output, protocol,
case-count, and serialization limits;
- deterministic clock, PRNG seed/algorithm, locale, timezone, and platform
projection; and
- expected Evidence and cleanup behavior.
Execution requires the exact `plan_digest`. REA
rebuilds the plan immediately before admission. Any changed file, runtime,
sandbox executable, policy, stub, input, limit, or environment commitment
returns `plan_stale` before application code starts. Approval is not transferable
to a different plan and cannot be represented by a bare Boolean alone.
Interactive CLI may print the plan and ask for confirmation. Non-interactive
CLI and MCP must perform the same explicit plan/execute exchange; they may not
auto-approve because the caller requested JSON output or because permission
elicitation is supported.
### 4. Require an OS sandbox; fail closed elsewhere
The first production backend is Linux-only. It must combine:
- an empty mount namespace rooted in private tmpfs;
- a new user namespace with all capabilities dropped and further nested user
namespaces disabled;
- new PID, network, IPC, UTS, and cgroup namespaces;
- a new terminal session and parent-death behavior;
- no host D-Bus, agent, browser, Docker, Wayland/X11, SSH, GPG, audio, device,
or application sockets;
- a minimal, read-only runtime closure rather than `/`, the user's home,
working directory, or host `/tmp`;
- a fresh `/proc` for the sandbox PID namespace and a minimal private `/dev`;
- a parent-generated, architecture-checked seccomp policy that denies at least
namespace or mount changes, `ptrace` and cross-process memory inspection,
BPF/perf access, kernel keyring and module control, reboot/swap controls, and
the `TIOCSTI` terminal injection path;
- cgroup v2 `memory.max`, `memory.swap.max=0`, `pids.max`, and bounded CPU
controls owned for the one run; and
- an outer REA supervisor that can kill the complete cgroup and verify it is
empty.
The seccomp program is passed by descriptor, has a version and digest committed
to the replay plan, validates the syscall architecture before the syscall
number, and never permits `ptrace`-based mediation. Seccomp reduces exposed
kernel surface; it is not described as a complete sandbox by itself.
The reference backend for the implementation PR is Bubblewrap for namespace,
mount, and seccomp construction plus a delegated cgroup v2 manager for resource
enforcement. REA must feature-probe the actual required operations; version
text alone is insufficient. A setuid Bubblewrap installation, a backend that
silently skips a requested namespace or filter, unavailable user namespaces,
missing cgroup delegation, or inability to prove cleanup makes the capability
unavailable. REA setup must not install or upgrade Bubblewrap, systemd, Node.js,
or kernel components.
macOS, Windows, Linux hosts without every required feature, containers that
block the required namespaces, and alternative backends are unavailable in
v1. They must return precise diagnostics and remediation, not a process-only or
`vm`-only degraded mode.
Node.js runs with its permission model enabled and without grants for network,
filesystem, child processes, workers, native addons, WASI, FFI, or inspector.
That layer is defense in depth. It is never cited as the OS security boundary,
because Node.js explicitly does not promise containment of malicious code.
### 5. Make the worker disposable and deterministic by construction
Each approved run receives a new sandbox, runtime root, worker process, module
loader, and deterministic state. No module cache, realm, timer, file, global,
or child survives into another run. Within a multi-case run, every case gets a
fresh realm and fresh module instances; case order and generator state are
committed.
The worker exposes a small versioned set of language primitives and explicitly
selected stubs. It does not expose `process`, `require`, host `console`, timers,
`fetch`, sockets, filesystem APIs, `Buffer`, worker APIs, native bindings, or
ambient environment variables. Date/time, randomness, locale, timezone, and
platform values come only from committed deterministic providers. An
unsupported global or import produces an observed exception; REA does not
substitute a convenient host implementation.
Caller-provided stubs are executable untrusted code and receive the same
sandbox treatment as recovered modules. Built-in stubs have stable IDs,
versions, canonical source digests, and documented semantics. No undeclared
fallback stub is allowed.
Inputs are bounded canonical JSON. Results are projected without invoking
getters, proxies, `toJSON`, or arbitrary coercion: only admitted primitives,
arrays, and plain data properties are serialized. Cycles, accessors, functions,
symbols, unsupported prototypes, excessive depth, excessive nodes, and
oversized values become explicit serialization outcomes. Worker stdout is the
framed protocol only; bounded diagnostic stderr and bounded, opt-in console
observations remain separate.
### 6. Enforce independent resource ceilings
Every limit has a conservative product default. The v1 plan and result commit:
- an outer wall-clock deadline for the complete disposable run;
- cgroup memory, swap, task, and CPU ceilings;
- Node/V8 heap ceiling as defense in depth;
- private tmpfs bytes;
- serialized worker-protocol bytes, aggregate module bytes, and case-input
bytes; preset-generated cases also have a fixed preflight count ceiling;
- stdout, stderr, exception, stack, and aggregate retained-output bytes; and
- structured-result depth and node count.
The parent enforces protocol and output limits while bytes arrive, before JSON
parse or Evidence retention. The worker cannot request wider limits. A limit
hit terminates the complete run cgroup and is an observed termination, not a
partial successful return.
### 7. Preserve exact provenance and the right Evidence authority
A run that reaches worker admission produces Evidence with:
- provider `rea-javascript-replay` and a concrete implementation version;
- operation `run_controlled_replay`;
- authority `controlled-replay`;
- confidence `observed` for the exact returned value, thrown exception,
sandbox denial, limit termination, signal, exit, or crash that REA directly
observed;
- environment isolation `container`, the host platform/architecture, runtime
identity, sandbox-backend identity, and sandbox-policy digest;
- the replay plan digest, module and stub digests, canonical input or generated
case digests, deterministic providers, and every effective limit;
- bounded raw input, output, and exception data when retained, plus their
canonical digests and truncation state;
- start/admission/termination/cleanup states; and
- explicit limitations for incomplete output, nondeterminism not checked,
sandbox diagnostics, or cleanup that could not be proven.
The host module path remains an actionable local diagnostic and Evidence
subject location, while the worker sees only a stable alias. Module source is
not embedded in ordinary Evidence. A separately approved reproducer may copy
module/stub bytes or may retain path-plus-digest references; its manifest says
which mode was used. Repository tests use source-owned fixtures, and real-app
verification stores only digests and expected structural facts.
Derived differential results use confidence `derived` and link every source
run Evidence ID. A repeat with the same commitment can establish
`repeat-confirmed` for those runs; a single deterministic plan is only
`committed-not-confirmed`. Neither state proves behavior in the original
application.
When replay observations are added to the JavaScript Application Graph, their
graph-fact authority is `controlled-replay`. A claim that the real renderer,
preload, main process, or remote service behaves the same remains inferred or
unknown until compatible runtime authority exists. Static inference, passive
CDP observation, controlled replay, and real application interaction are never
promoted into one another.
### 8. Treat post-admission failures as observations
Pre-admission failures return a typed error and create no claim that module code
ran. Once the worker is admitted, REA retains a bounded execution record even
when the requested function does not return normally.
| Condition | Caller result and Evidence semantics |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| Disabled capability or missing grant | `permission_required`/`capability_unavailable`; no worker admission and no replay observation |
| Sandbox/runtime probe failure | `capability_unavailable` with exact failed feature; no module execution |
| Plan digest mismatch or changed source | `plan_stale`; no module execution |
| Sandbox setup fails before worker admission | `execution_failure`; no controlled-replay claim about the module |
| Module returns admitted data | Observed return value with complete or explicitly limited coverage |
| Module throws or result serialization rejects | Successful replay observation with outcome `exception` or `serialization_error`; application claim unknown |
| Node permission or sandbox denies an operation | Observed denial/termination when attributable; no claim that all attempted side effects were enumerated |
| Timeout, memory, CPU, task, tmpfs, or output hit | Observed limit termination; requested functional result unknown |
| Signal, runtime crash, or malformed protocol | Observed termination plus bounded diagnostics; functional result unknown |
| Caller cancellation after admission | Kill full cgroup, record cancellation/cleanup if possible, and project the public cancellation contract |
| Cleanup proves an empty cgroup and removed root | `cleanup: complete` |
| Cleanup cannot prove emptiness or removal | `cleanup_incomplete`, name every residual resource, and do not report success |
An exception is data, not an adapter failure. A sandbox setup error is not
evidence that the module crashed. A timeout is not evidence that the function
would never return. An output limit is not evidence that the truncated prefix
equals the full result. These distinctions are part of the public contract.
Cancellation and cleanup must be idempotent. REA first stops admission and
input, kills the owned cgroup, waits for an empty-cgroup observation, removes
the private runtime root, closes protocol descriptors, and releases timers.
Failure at one cleanup step does not skip the remaining steps.
### 9. Keep replay records reproducible without overstating determinism
The canonical replay manifest commits:
```text
plan structure and policy identity
REA/provider/runtime/sandbox executable identities and digests
module aliases, dependency graph, bytes digests, and source references
stub IDs, versions, source digests, and caller-provided stub digests
canonical inputs or generator algorithm, seed, case order, and case digests
clock, PRNG, timezone, locale, platform, and exposed-global commitments
all resource and serialization limits
network and filesystem projections
expected entry export and invocation convention
```
The result manifest adds canonical output/exception/termination digests,
coverage, dropped-data counts, cleanup state, and source Evidence links.
Canonical digests are computed by the trusted parent; worker-provided digests
are ignored.
Reproduction requires exact manifest compatibility. A runtime, sandbox policy,
built-in stub, module byte, generated case, limit, architecture, or platform
change is a different experiment. Cross-environment comparison may still be a
derived investigation, but it is never an exact replay.
### 10. Expose availability and policy truth before execution
`rea doctor`, capability inventory, and the planning response must report the
JavaScript replay capability without executing application code. Diagnostics
name the exact missing executable, unsupported host, failed namespace feature,
cgroup delegation failure, setuid rejection, runtime mismatch, or cleanup-probe
failure. Genuine secrets remain redacted; local executable paths, versions,
digests, and kernel feature failures remain visible.
The capability must be absent from executable tool routing until implemented.
Accepting this ADR does not increase the current tool count and does not add a
hidden experimental flag.
## Required implementation and verification gate
The implementation PR cannot merge until all of the following are true:
1. `javascript_replay` exists in configuration, permission policy, project
grants, policy explanation, CLI, MCP, docs, and capability inventory with
fail-closed defaults.
2. Plan and execute phases have schema-identical CLI/MCP behavior and an exact
plan-digest stale check.
3. No replay-disabled static, browser, Electron, session, setup, doctor, or
application workflow can reach module execution.
4. The worker never imports into the REA server process and no adapter offers a
`vm`-only fallback.
5. The Linux backend feature-probes namespaces, seccomp installation and
denial, delegated cgroup v2 limits, and the exact admitted architecture.
Every plan content-addresses the worker, seccomp filter, Node executable,
ELF loader, shared-library closure, and sandbox executables.
6. Source-owned fixtures cover parser, sanitizer, clipboard, exception,
ambient side-effect attempts, memory pressure, and busy loops. The worker
exposes no filesystem, environment, network, process, worker, native-addon,
timer, inspector, or ambient package-resolution API.
7. Tests and the real verifier prove bounded protocol/diagnostics, timeout and
OOM cgroup termination, and observed cgroup cleanup.
8. Evidence tests cover observed return/exception/termination, derived
comparison with source Evidence links, stale admission, cancellation
projection, and explicit limitations on application-level claims.
9. Package verification exercises the target-free public contract. The
dedicated real-Linux workflow exercises the sandbox backend; environments
without delegated user namespaces or cgroups report truthful unavailability
rather than selecting a weaker backend.
10. A real operator-local Notion-like parser or sanitizer benchmark can run
without committing its source, and exports only approved local reproducer
material.
## Rejected alternatives
### Reuse `browser_observe`, `electron_observe`, or `process_capture`
Rejected because those grants authorize different effects. Reuse would turn a
passive or unsandboxed process permission into recovered-code execution.
### Execute in the MCP server with `vm.runInContext`
Rejected because a VM context is not a security boundary and a crash, resource
attack, or escape would compromise the long-lived session and its credentials.
### Use only the Node.js permission model
Rejected because Node.js documents it as a seat belt for trusted code and
explicitly does not guarantee containment of malicious code. It remains a
defense-in-depth layer inside the OS sandbox.
### Ship a process-only fallback on unsupported hosts
Rejected because it changes the security claim while preserving the same tool
name. Unsupported hosts return unavailable.
### Permit network allowlists in v1
Rejected because DNS, redirects, proxies, credentials, service identity, and
response nondeterminism would substantially expand the threat and Evidence
model. The v1 namespace has no host or external network.
### Mount the approved project root read-only
Rejected because one approved module does not imply authority to disclose
every file in its project. The parent stages only exact, digested bytes.
### Treat exceptions, crashes, or limit hits as ordinary tool errors only
Rejected because that discards the principal behavioral observation and makes
negative results impossible to reproduce. Post-admission termination is
retained with explicit functional uncertainty.
## Consequences
- JavaScript replay is Linux-only at first and may be unavailable on containers
or distributions that disable user namespaces or cgroup delegation.
- The implementation requires more host probing and lifecycle code than a
simple Node worker, but the public security claim remains stable.
- Plans require two calls in non-interactive environments and become stale when
any committed input changes.
- Network-dependent modules and full application interactions are excluded;
their absence is explicit rather than emulated implicitly.
- Results are reproducible for the committed isolated experiment, not proof of
production behavior.
- Adding another sandbox backend, network mode, or application-interaction mode
requires a separate reviewed decision and conformance suite.
## References
- [Node.js permissions](https://nodejs.org/api/permissions.html) documents that
the permission model does not protect against malicious code and describes
its known filesystem and cross-process limitations.
- [Bubblewrap README](https://github.com/containers/bubblewrap/blob/main/README.md)
describes its namespace construction and makes clear that the caller's
arguments, not Bubblewrap alone, define the sandbox security model.
- [Linux seccomp filter documentation](https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html)
explains that syscall filtering reduces kernel surface but is not a complete
sandbox by itself.
- [ADR-0001](0001-provider-selection-and-analysis-profiles.md) establishes the
existing rule that provider selection, Evidence provenance, and capability
unavailability remain explicit and never silently fall back.
@@ -1,452 +0,0 @@
# ADR-0003: Managed-code evidence and provider boundary
> Historical design record: The non-executing runtime-correlation planning
> tool described in earlier revisions was removed. This ADR's current
> implementation status below covers only the static managed tools that ship.
- Status: Superseded for runtime planning; static evidence boundary remains in force
- Date: 2026-07-16
- Implementation status: Read-only PE/CLI triage and exact identity are shipped
through `inspect_managed_artifact` / `rea inspect-managed-artifact`. Bounded
metadata, signatures, method bodies, raw CIL hashes, limited
decoded-instruction-tuple v1 hashes, exception regions, call edges, and
field-access anchors are shipped through `inspect_managed_members`; `rea
inspect-managed-members` provides CLI parity. Static member comparison and build-local
token remapping are shipped through `compare_managed_members` /
`rea compare-managed-members`. Declaration-only managed/native boundary
inventory for ModuleRef, ImplMap/PInvoke, ReadyToRun indicators, and non-IL
method flags is shipped through `inspect_managed_native_boundaries` /
`rea inspect-managed-native-boundaries`. Managed/native export or function
Evidence matching is shipped through `verify_managed_native_boundaries` /
`rea verify-managed-native-boundaries`; it verifies only supplied P/Invoke
export/function observations and does not map managed tokens to native
addresses. Decompiler reconstruction import is
shipped through `import_managed_reconstruction` /
`rea import-managed-reconstruction`; it records user-supplied C#/IL/pseudocode
as analyst inference only after exact static member locks match. Managed
inspection does not execute assemblies or observe CLR internals. Managed static graph
projection is shipped through
`project_managed_application_graph` /
`rea project-managed-application-graph`; it projects authenticated managed
Evidence into the application graph without changing managed tokens into
native addresses. Native-body bridge mapping and an actual runtime executor
remain future contracts.
## Context
Professional C# reverse engineering is not one decompiler operation. A file
described as “.NET” can be ordinary Common Intermediate Language (CIL),
ReadyToRun code containing both CIL and native implementations, a single-file
deployment, C++/CLI mixed mode, Unity Mono, Unity IL2CPP, or NativeAOT. Those
forms have different sources of truth and different native-analysis needs.
Choosing a decompiler before classifying the artifact can therefore produce a
plausible but false model.
The durable static facts in an ordinary managed PE are its PE/CLI headers,
metadata tables, signatures, method bodies, exception regions, and CIL. A C#
decompiler reconstructs source-like control flow and language constructs from
those facts. That reconstruction is valuable, but it is not the original
source and cannot replace the underlying metadata and CIL evidence. Obfuscation
makes names especially weak while tokens remain coordinates in only one build.
REA already separates one selected deep native provider from disjoint auxiliary
providers under [ADR-0001](0001-provider-selection-and-analysis-profiles.md).
It also separates static evidence, passive observation, process capture, and
interactive observation authorities. Managed analysis must fit those boundaries
without requiring a CLR to inspect an artifact, loading target code into the
REA process, or treating a managed token as a native address.
The design is informed by exact-build, reflection-free metadata extraction,
hash-locked method manifests, independent behavior models, and managed/native
boundary analysis performed against a local C# application. The application,
its decompiler output, and its runtime observations are research inputs only;
they are not distributable REA fixtures.
## Decision drivers
1. Classify the deployment before selecting an analysis route.
2. Make metadata and CIL independently inspectable without a CLR or target
execution.
3. Preserve exact-build provenance while enabling structural comparison across
builds whose MVIDs, tokens, names, and layout differ.
4. Compose managed and native analysis without introducing another ambiguous
deep-provider candidate.
5. Keep decompiled C# useful but epistemically subordinate to canonical bytes.
6. Analyze Linux, macOS, and Windows managed artifacts through the same local
CLI/MCP contracts on REA's supported hosts.
7. Keep setup additive and prevent managed analysis from installing .NET,
ILSpy, an SDK, or another unrelated toolchain.
8. Prove semantics with source-built conformance artifacts and compact,
operator-local real-application checks.
## Terminology
- **Managed artifact**: a PE, bundle component, or related metadata artifact
that carries a CLI header, CLI metadata, CIL, or another managed-runtime
commitment.
- **Classification vector**: independently observed container, runtime family,
implementation form, and architecture. It is not one guessed label.
- **Canonical static observation**: a bounded value decoded directly from the
target bytes under a versioned parser contract.
- **Reconstruction**: source-like output, including decompiled C#, derived from
canonical observations.
- **Structural inference**: a relationship or cross-version match derived from
signatures, APIs, constants, control/data-flow shape, or other observations.
- **Validation**: an independently checked proposition, for example a
source-built oracle assertion or a behavior-model corpus result.
- **Runtime observation**: a separately authorized fact obtained by attaching,
loading, debugging, instrumenting, or otherwise executing code.
## Decision
### 1. Classify before analyzing
Managed triage returns a classification vector and the observations supporting
each dimension. Absence of a marker produces `unknown` or `not_applicable`, not
an invented runtime family.
| Dimension | Initial values |
| ------------------- | ------------------------------------------------------------------------------------------------------------ |
| Container | PE file, single-file bundle, bundle component, Unity metadata pair, native image, malformed, unknown |
| Runtime family | .NET Framework, modern .NET, Unity Mono, Unity IL2CPP, NativeAOT, mixed CLR/native, unknown |
| Implementation form | CIL, CIL plus ReadyToRun, native only, C++/CLI mixed, metadata only, unsupported, unknown |
| Architecture | PE machine plus CLI flags; component-specific architecture for bundles; conflicting or unknown when required |
Target-framework attributes, assembly references, metadata stream versions,
bundle manifests, ReadyToRun directories, and native headers are observations.
They may support a runtime-family inference, but no single string is treated as
authoritative when the other bytes conflict.
Classification selects these routes:
| Observed form | Managed route | Native route and limitation |
| --------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| Ordinary Framework or modern CIL | Full metadata, signatures, method bodies, and CIL | Optional only for declared interop boundaries |
| Obfuscated CIL | Same canonical route; names receive no special trust | Optional for declared interop boundaries |
| Unity Mono assembly | Same canonical route with Unity context retained | Optional for engine/native boundaries |
| ReadyToRun | Metadata/CIL where present; implementation availability is per method | Selected Hopper/Ghidra analyzes native sections; CIL absence is reported per method |
| C++/CLI mixed mode | Metadata/CIL for managed members and explicit mixed-mode boundary observations | Selected Hopper/Ghidra analyzes native bodies; REA never converts tokens directly to native addresses |
| Single-file deployment | Inventory the bundle, then analyze each authenticated managed component | Selected Hopper/Ghidra analyzes the host/native components; unsupported compression remains explicit |
| Unity IL2CPP | Pair and authenticate available Unity metadata; do not claim canonical CIL | Selected Hopper/Ghidra analyzes the generated native binary; semantic recovery is degraded until supported |
| NativeAOT | Report any independently present managed metadata, otherwise no CIL claim | Treat as a native target with NativeAOT provenance; managed source reconstruction is unavailable |
| Malformed or unsupported artifact | Return bounded partial observations and typed unavailable/unknown scopes | Do not silently retry by loading or executing the file |
Classification is byte-driven and bounded. File extensions, product names,
process names, and an operator's description are hints only.
### 2. Implement managed static analysis as a disjoint auxiliary provider
The initial producer is a REA-owned auxiliary provider with ID
`rea-dotnet-static`. It owns a disjoint managed-artifact operation family. It is
not registered as a Hopper/Ghidra deep-provider candidate because it does not
compete for the same operation names and must be able to coexist with the one
selected native provider.
```text
one opened artifact/session
|
SessionProviderRouter
/ \
rea-dotnet-static auxiliary selected deep binding
PE/CLI metadata and CIL Hopper or Ghidra
\ /
explicit managed/native links
|
Evidence and workflows
```
An ordinary managed artifact can therefore remain unbound to a deep native
provider while managed operations work. ReadyToRun, C++/CLI, IL2CPP, NativeAOT,
and interop workflows may additionally require a caller-selected native
binding. Native-provider failure never causes managed evidence to be relabeled,
and managed-parser failure never causes an implicit native fallback.
Provider mechanics live under a provider directory such as `src/dotnet/`.
Provider-neutral identities, evidence states, and bounded values may live in
the domain/contracts layers. Application code composes results but does not
parse PE headers, metadata tables, signatures, CIL, ReadyToRun headers, or
provider-specific output.
### 3. Make the production static path byte-only and execution-free
`rea-dotnet-static` reads approved local bytes and implements the required
PE/CLI metadata and CIL subset in TypeScript. It does not call any reflection
API and does not require the .NET runtime. In particular, static inspection
must never:
- call `Assembly.Load`, `Assembly.LoadFrom`, `ReflectionOnlyLoad`, or an
equivalent runtime loader;
- resolve target dependencies by executing target-controlled resolver code;
- run module initializers, constructors, entry points, build tasks, plugins, or
generated helpers;
- start the target, attach to a process, contact a service, or inherit target
configuration and credentials; or
- interpret a decompiler, CLR, or native-provider diagnostic as an observation
from the artifact bytes.
The parser uses checked offsets and additions, explicit endianness, bounded
table/heap/body counts, cycle-safe traversal, and typed partial results. A bad
row, signature, body, resource, or stream does not authorize an unbounded retry
or a CLR load. Complete-coverage claims require every applicable bounded region
to have been admitted; otherwise coverage is partial, unknown, or unavailable
with exact offsets and reasons.
The caller selects the local input path directly. Local artifact
paths, digests, MVIDs, tokens, malformed offsets, and analysis metadata are
actionable diagnostics and are not secrets. Credentials, authorization data,
and genuine secrets remain redacted.
### 4. Bind every finding to exact artifact and producer identity
Every managed result carries a commitment with at least:
```text
artifact: canonical path + byte length + SHA-256
component: container identity + component path/name + component SHA-256, when applicable
classification: container + runtime family + implementation form + architecture
assembly/module: simple name + version + culture + public-key identity + module name + MVID
producer: provider ID + exact version + analysis-affecting parameters + profile digest
```
An assembly-qualified name does not replace the artifact digest or MVID.
Neither an MVID nor an Authenticode signature proves who authored the behavior.
Bundle components retain both their container and component commitments so that
bytes extracted from another host cannot be silently substituted.
Method observations add:
```text
declaring type + normalized CLI signature
build-local metadata token
RVA/file extent when present
raw CIL byte length + SHA-256 when the body is admitted
decoded-instruction-tuple SHA-256 when CIL is valid
separate max-stack, locals-token, and exception-region observations
```
The shipped `il_sha256` commits only the raw CIL byte stream identified by the
method header's `il_size`. It does not commit the method header, local-signature
blob, alignment padding, or extra sections such as exception clauses. Those
facts remain separate observations and the enclosing artifact SHA-256 binds
them to the exact file. A digest over the complete method body is not shipped.
The caller-visible field remains named `normalized_il_sha256`, but its shipped
v1 meaning is deliberately narrower than a canonical semantic CIL identity.
For a completely decoded method, REA serializes the instruction-order array of
`[opcode, operand_kind, operand]` tuples with JavaScript `JSON.stringify`,
encodes that text as UTF-8, and reports its lowercase SHA-256. The tuple
projection is defined here; the member result carries only the described
normalized digest.
Operands retain the current decoder projection: metadata and user-string
operands are build-local lowercase hexadecimal tokens, scalar branch operands
are decimal target CIL byte offsets, and `switch` retains only its decimal case
count. Constants and variable indexes are decimal strings; an operand-free
instruction uses kind `none` and value `null`. Opcode names preserve distinct
short forms and prefix instructions, but instruction offsets, branch target
instruction identity, switch targets, resolved token identities, method
headers, locals, and exception regions are not part of this digest. A partial
or malformed decode has no `normalized_il_sha256`.
Consequently v1 is a deterministic decoded-tuple fingerprint, not proof of
semantic equivalence. In particular, methods with the same opcodes and switch
case counts can share it despite different switch targets, and token movement
can change it without a semantic change. Cross-build comparison may use it as
one unique-only structural tier while retaining artifact/MVID commitments and
ambiguity; it must not describe the digest itself as token-remapped canonical
CIL. Canonical operand resolution, complete control-flow operands,
exception/local commitments, and an explicit algorithm version require a new
normalized-CIL schema.
Metadata tokens are reported because they are precise coordinates inside one
module. Cross-version identity never consists of a token alone. Matching tries
exact CIL/signature identity, then an exact declared-type/name/signature tuple,
then structural shape; a name by itself never selects a pair. Partial or
malformed bodies leave body facets unknown after a signature tuple pairs the
methods. Matches cite both build commitments, both local tokens, and all
competing candidates. V1 cannot cite a separate matching-algorithm version
because none is exposed.
### 5. Separate five evidence layers
Managed workflows retain these layers independently:
| Layer | Examples | Permitted claim |
| ---------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------- |
| Static observation | Metadata row, signature, CIL opcode, literal, exception region | “These bounded bytes decode to this value.” |
| Reconstruction | Decompiled C#, async/iterator source shape, expression simplification | “This is one source-like representation of cited observations.” |
| Structural inference | Likely caller, field flow, behavior slice, cross-build method match | “These cited structures support this relationship.” |
| Independent validation | Synthetic oracle, corpus result, second parser agreement | “This declared proposition passed the named independent check.” |
| Runtime observation | Exact-build attach/load/instrumentation event | “This separately authorized experiment observed this event.” |
Each layer has its own producer, authority, state, confidence, coverage, and
limitations. A readable C# method is never emitted as original source or exact
semantic proof. A validator does not upgrade unrelated claims. Runtime
agreement does not retroactively turn a static inference into an observation.
Negative results are scope-qualified. For example, “no declared P/Invoke rows
were found in the admitted metadata tables” does not prove the application has
no native, dynamically resolved, generated, server-side, or protected path.
### 6. Admit ILSpy only as an optional reconstruction and conformance tool
REA's canonical static operations do not depend on ILSpy, a .NET SDK/runtime,
dnlib, or Mono.Cecil. The following review was current on the decision date:
| Tool | Reviewed coordinate | License | Runtime/host observation | Decision |
| ---------------------------- | ------------------- | ------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `System.Reflection.Metadata` | 10.0.10 | MIT | Library targets .NET Framework 4.6.2, .NET 8/9/10, and .NET Standard 2.0 | Pinned independent metadata oracle for conformance; not shipped or invoked by production parsing |
| `ICSharpCode.Decompiler` | 10.1.1.8388 | MIT | Library targets .NET Standard 2.0; output is reconstruction | Pinned reconstruction/differential oracle candidate |
| `ilspycmd` | 9.1.0.7988 | MIT | Cross-platform .NET 8 tool; newer 10.1.1.8388 requires .NET 10 | Initial optional BYO reconstruction coordinate because it matches the source research baseline |
| dnlib | 4.5.0 | MIT | Cross-platform library; also exposes assembly-writing APIs | Differential test candidate only; its writable model is outside the production trust boundary |
| Mono.Cecil | 0.11.6 | MIT | Cross-platform .NET Framework/.NET Standard library with read/write support | Differential test candidate only; not a production dependency |
Coordinates and package hashes used by real verification are checked into a
source-owned lock manifest when that verifier is implemented. “Latest” is
never a reproducibility coordinate. A version change requires conformance and
an explicit profile/version change.
Artifact platform and REA host support are separate. The byte-only parser must
inspect PE/CLI artifacts produced for Windows on a supported Linux or macOS REA
host; that is not a claim that REA itself currently runs on Windows. Managed
library/tool candidates above are cross-platform at their reviewed targets, but
native composition remains limited by the selected Hopper/Ghidra host and
format support. Real verification runs the canonical path on Linux and macOS
and may run pinned oracle checks on Windows without turning that development
check into a public Windows-host claim.
If a caller-visible C# reconstruction operation is admitted, it is a distinct
optional capability. It accepts only an exact supported BYO `ilspycmd`, records
the tool and decompiler version, runs in an owned bounded process without
loading target code into REA, and links output to the canonical method
observation. Setup and installers do not download or install ILSpy, .NET, an
SDK, or a runtime. Doctor may inspect an explicitly configured executable and
report exact actionable incompatibility. Missing reconstruction never removes
canonical metadata/CIL capabilities.
This decision does not make a decompiler process a security sandbox. The
initial public path can defer C# reconstruction while canonical contracts and
process isolation are proven.
### 7. Use source-built conformance and operator-local real targets
The repository stores source, build descriptions, expected semantic facts,
and tool lock manifests, but not compiled managed binaries. An isolated build
step creates fixtures outside source directories and records their SHA-256 and
MVID before verification. At minimum, the corpus covers:
- Framework-compatible and modern .NET metadata;
- AnyCPU, x86, and x64 PE/CLI flags;
- generics, nested types, overloaded signatures, properties, events, resources,
attributes, and constants;
- exceptions, filters, prefixes, switch branches, P/Invoke, async and iterator
state machines;
- obfuscated and Unicode names without assigning semantics from names;
- malformed headers, tables, heaps, signatures, bodies, and exception regions;
and
- two semantically related builds with different MVIDs, tokens, layout, and
selected names.
Expected facts are checked directly and against pinned
`System.Reflection.Metadata`; ILSpy, dnlib, or Mono.Cecil may add differential
coverage but do not vote by majority. Disagreement is a failing or explicitly
unsupported case, not silently normalized output.
The real-application benchmark is an operator-local, opt-in osu! check derived
from the research workflow. It accepts an explicit path plus a compact
expectation manifest; verifies target SHA-256, MVID, architecture, and expected
assembly identity before analysis; and emits only bounded identities, tokens,
signatures, IL lengths/hashes, match states, and assertion results. It does not
emit full IL, decompiled source, runtime logs, user data, credentials, or
service/account material. No proprietary binary, hash-locked application
manifest, or derived dump is committed to REA.
### 8. Keep runtime behavior separate from static managed analysis
No managed runtime planning or execution tool ships. Managed inspection does
not execute assemblies or establish which methods ran. Where supported, direct
process capture can record target-level inputs and outputs, but it does not
prove CLR method execution or resolution. Internal managed behavior remains
unknown until independently observed with suitable runtime evidence.
## Public contract consequences
- Managed static operations will have CLI and MCP parity and produce the same
Evidence commitments.
- Adding managed operations changes the caller-visible tool inventory and
generated product catalog only in the implementation PR that admits them.
- Partial parsing includes admitted/dropped counts, exact limitations, and
coverage; it never returns a partial list labeled complete.
- Managed addresses distinguish file offsets, RVAs, native virtual addresses,
metadata tokens, and CIL offsets. They are not interchangeable.
- Cache compatibility is exact on artifact/component commitment, member-result
fields, parser profile, and producer version. For shipped v1,
`normalized_il_sha256` has no independent algorithm-version field.
- Provider-neutral workflows may compose canonical managed findings with the
one native binding, but every source operation retains its actual producer.
## Alternatives rejected
### Make ILSpy the only managed provider
This would make canonical metadata/IL inventory depend on a separately
installed CLR and conflate source reconstruction with byte observations. It
would also make tool-version drift part of ordinary inventory. ILSpy remains a
valuable optional reconstruction and conformance tool instead.
### Use `Assembly.Load` or reflection-only loading
Both delegate parsing and dependency behavior to a CLR and make static support
runtime-dependent. Ordinary loading can execute target code; reflection-only
loading still establishes a CLR load boundary and is unavailable across modern
runtimes in a uniform way. Neither is required to decode ECMA-335 bytes.
### Register the managed analyzer as another deep candidate
That would force callers to choose managed analysis instead of Hopper/Ghidra
for ReadyToRun and mixed-mode artifacts even though both are needed. Disjoint
auxiliary composition represents the real ownership boundary.
### Treat tokens, names, or decompiler output as durable identity
Tokens and obfuscated names change across builds, while decompiler output
changes across tools and versions. They remain useful build-local coordinates
or reconstruction labels but are insufficient for exact or structural
cross-version identity.
### Package a .NET runtime or mutable managed library in REA
This would expand installer effects, package size, patching obligations, and
the target-parsing attack surface. The initial byte parser keeps canonical
support within REA's existing Node runtime; external managed tools remain BYO
or development-only oracles.
## Rollout gates
1. Add read-only triage and identity with malformed-input bounds. Shipped.
2. Add metadata, signatures, method bodies, deterministic decoded-CIL tuple
fingerprints, and exact artifact Evidence. Shipped with the v1 limitations
above; full normalized-CIL semantics remain planned.
3. Add obfuscation-resistant slices and cross-build match states. Shipped.
4. Compose explicit managed/native boundaries with Hopper/Ghidra. Declaration
inventory and native export/function Evidence matching shipped; native-body
bridge mapping remains planned.
5. Add source-built, pinned real-tool, package, CLI, and MCP conformance.
Source-owned conformance is shipped; pinned external real-tool checks remain
planned.
6. Project authenticated managed static Evidence into the application graph.
Shipped.
Every gate must keep unsupported ReadyToRun, NativeAOT, IL2CPP, mixed-mode, or
bundle cases explicit rather than broadening claims to make a fixture pass.
## References
- [ECMA-335: Common Language Infrastructure](https://ecma-international.org/publications-and-standards/standards/ecma-335/)
- [.NET ReadyToRun deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run)
- [.NET Native AOT deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/)
- [.NET single-file deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview)
- [`System.Reflection.Metadata` package](https://www.nuget.org/packages/System.Reflection.Metadata/10.0.10)
- [ILSpy repository and releases](https://github.com/icsharpcode/ILSpy)
- [dnlib repository](https://github.com/0xd4d/dnlib)
- [Mono.Cecil repository](https://github.com/jbevain/cecil)
-11
View File
@@ -1,11 +0,0 @@
# Architecture decision records
Accepted decisions describe the architecture that implementation PRs must
follow. Acceptance does not by itself mean the behavior is shipped; each record
states its implementation status separately.
| ADR | Status | Implementation |
| ------------------------------------------------------------------------------------------------------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| [0001: Provider selection and analysis profiles](0001-provider-selection-and-analysis-profiles.md) | Accepted | Provider selection and 25 read-only Ghidra operations on Linux/macOS and experimental Windows x64 P0; Linux/macOS session annotations |
| [0002: Controlled JavaScript replay authority and sandbox policy](0002-controlled-replay-authority-and-sandbox.md) | Superseded | Historical design; the controlled JavaScript replay tool was removed |
| [0003: Managed-code evidence and provider boundary](0003-managed-code-evidence-and-provider-boundary.md) | Partially superseded | Seven static managed tools remain; runtime planning removed |
+63 -4
View File
@@ -23,10 +23,37 @@ export REA_JADX_MCP_JAR=/absolute/path/jadx-headless-mcp-0.7.1-all.jar
export JAVA_HOME=/absolute/path/existing-jdk
```
On Windows x64, use a REA package with its matching bundled Windows native
controls **including owned protocol stdin support**. This Windows boundary is
new on repository main; an older released package can still reject this host.
PowerShell accepts paths containing spaces without additional escaping
inside these environment values:
```powershell
$env:REA_JADX_MCP_JAR = 'D:\tools\jadx-headless-mcp-0.7.1-all.jar'
$env:JAVA_HOME = 'D:\tools\jdk-21'
rea inspect-android-package 'D:\targets\Example.apk'
```
REA selects `JAVA_HOME\bin\java.exe`, or resolves `java.exe` on the selected
Windows `PATH`. A missing or mismatched native artifact reports the package
prerequisite rather than attempting an unowned Java launch. Windows arm64 is
outside this provider's current native boundary.
Readiness checks the selected JAR's ZIP directory for the classes consumed by
REA's metadata bridge, as well as Java's compiler and version modules. It does
not load an APK or execute engine code. Invalid archives and missing bridge
classes report JAR-specific recovery; classpath inventory alone does not prove
that every class or engine operation will load successfully. Discovery limits
each ZIP metadata read to 8 MiB before allocation; a larger directory reports
the exhausted read budget and the selected JAR path.
The current metadata bridge is verified on macOS arm64 with OpenJDK 21 and the
public Appium ApiDemos fixture. The POSIX adapter also supports Linux; the new
bridge has not yet undergone real verification on Linux/JDK 25.
Windows is unsupported for this provider's owned stdio process boundary.
Windows x64 uses an owned Job Object with bidirectional stdio, atomic job
assignment and kill-on-owner-close. Real Windows verification uses JDK 21 and
the pinned JADX 0.7.1 JAR; see the real verification lane below.
## Answer an analyst question
@@ -91,10 +118,25 @@ selected overload. Native/abstract methods with no decompiled body report
responses remain in Evidence. Source revision is populated only for bytes
matching the audited release JAR.
If a later step fails, the error's `details.partial_observation` retains the
selected and resolved APK paths, digest, observed provider identity and versions,
and each upstream request and reply collected before the failure. Failed replies
remain available even when their payload cannot be interpreted. Cancellation
also stops target hashing before provider admission.
These operations do not execute the APK or provide split APK/AAB handling,
signature validation, full resource-table semantics, native-library analysis or
Android runtime capture. Existing artifact inventory/extraction tools can supply
archive evidence. Project that Evidence with the execution-free inventory tool:
Android runtime capture. An `.aab` suffix is a ZIP archive, not an APK, so
Android tools and the application graph do not treat it as a standalone APK.
Existing artifact inventory/extraction tools can supply archive evidence.
Inventory records an APK root only for ZIP bytes whose name ends in `.apk`.
The projection adds a limitation when no root `AndroidManifest.xml` was
observed, because such a ZIP may not be an APK. Nested members take a ZIP or
ASAR family from their bytes; an unread member keeps an unknown format.
Inventory keeps ZIP names that differ only in case and records that a
case-insensitive destination cannot store both spellings. Extraction fails
only when that destination directory cannot keep both names. Project that
Evidence with the execution-free inventory tool:
```sh
rea project-android-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}'
@@ -111,7 +153,12 @@ rea project-android-application-graph '{"inventory_evidence":[<inventory_artifac
The projection reports exact component paths and hashes, runtime-family hints,
and path-based bridge hypotheses. It does not decode DEX or claim observed
runtime calls. Bridge hypotheses form a DEX/JVM-class by native-library
runtime calls. Framework hints match complete native library names, such as
`libreactnativejni.so`, `libreactnative.so`, `libhermes.so`,
`libhermes_executor.so`, `libflutter.so`, and `libunity.so`; unrelated names
such as `libcommunity.so` and `libreactivity.so` do not identify those families.
The bridge basis is inferred from the native path and repeated for each managed
component, so it does not identify a specific JNI binding. Bridge hypotheses form a DEX/JVM-class by native-library
Cartesian product. The projection computes the product and exact serialized
candidate-array size before creating candidate objects, then retains a
deterministic prefix within a 2 MiB UTF-8 JSON budget. If candidates are omitted,
@@ -130,6 +177,12 @@ target/configuration changes, failure, timeout, cancellation, MCP disconnect or
server shutdown. One-shot CLI commands always join cleanup before returning.
REA never writes to the original APK or launches target code.
On Windows, stdin writes preserve stream backpressure and run outside the Node
event loop. Cancellation terminates the retained job, including descendants,
before workspace cleanup. An abrupt CLI/server process termination closes the
job and stops Java, but cannot run JavaScript workspace cleanup; temporary
workspace files can remain after that forced exit.
If Java cannot start the bridge, REA reports the selected executable and retained
startup diagnostics. Select a full JDK through `JAVA_HOME` or `PATH`, and use
`java --list-modules` to confirm `jdk.compiler` is present. A runnable JRE alone
@@ -189,6 +242,12 @@ without the compiler module. It checks real Java startup failures, missing
selectors, recovery after failures, and CLI cancellation with owned cleanup.
The original APK and host Java configuration remain unchanged.
The same lane runs on Windows x64 with the bundled native controls and a full
JDK. It checks CLI/MCP results, real MCP cancellation and disconnect, and Java
exit after abrupt CLI owner termination. Windows forced termination is checked
separately from the POSIX CLI SIGTERM handler; it does not claim a structured
cancellation result or workspace removal after the owner is forcibly killed.
The download script verifies fixed SHA-256 values, reuses matching files and
refuses to overwrite a different existing file. APK/JAR files live under ignored
`_reference/` and are excluded from package contents. The lane exercises actual
+86
View File
@@ -0,0 +1,86 @@
# Apktool resource decoding
REA decodes Android resource tables and the binary manifest through the
caller's Apktool launcher. This completes the static triad for Android
targets: Java/Kotlin sources through the JADX family, engine-grade
decompilation through JEB, and resources through this family. REA never
installs Apktool or a Java runtime.
## Supply tools
Use Apktool 2.7.0 or newer (verified with 2.7.0) and a Java runtime the
launcher can find. Select the launcher through the environment:
```sh
# Optional: absolute path to the apktool launcher (upstream wrapper or a
# java -jar script); without it, apktool resolves from PATH.
export REA_APKTOOL_COMMAND=/absolute/path/apktool
```
Readiness is `rea inspect-apktool-client`: it runs `apktool --version` and
reports the resolved launcher, its selection source, and its version. A
missing launcher reports `capability_unavailable` with the
`REA_APKTOOL_COMMAND` remediation rather than attempting an installation.
## Answer an analyst question
```sh
rea inspect-apktool-client
rea decode-android-resources /targets/Example.apk
rea decode-android-resources /targets/Example.apk --locale de
rea decode-android-resources /targets/Example.apk --no-strings
```
Equivalent MCP methods are `inspect_apktool_client` and
`decode_android_resources`. The decode request takes `path`, an optional
`locale` (project `res/values-<locale>/strings.xml` instead of the default
table), and `include_strings` (default true). Regional locales such as `pt-BR`
select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
`b+zh+Hans+CN` may also be supplied directly.
## Interpret the result
- **An owned APK snapshot is digested and decoded.** `target.sha256` and
`target.bytes` bind the observation to the exact APK that was decoded.
- **Metadata comes from apktool.yml as apktool printed it.** Version codes
keep their own spelling (`'7'` versus `7`); `package_name` is read from
the decoded manifest, not inferred.
- **The manifest is the decoded text**, bounded at 512 KiB and reported as
truncated when larger.
- **Strings are projected verbatim.** Escaped entities stay escaped, and
entries containing nested markup (`<b>`, `<xliff:g>`) are counted as
unparsed rather than flattened — the limitation names the count. The
default table is bounded to 2000 entries with partial coverage when more
exist; `locales` lists every `values-<locale>` that has a strings table.
- **Smali is skipped by design** (`apktool d --no-src`): Java-source
recovery belongs to the JADX family. Resource smali edits and rebuild are
a follow-up lane with mutation authority.
- **Workspaces are owned and short-lived.** Decoding happens in a
provider-owned temporary directory that is removed before the result is
returned. The APK snapshot and framework cache both live inside this directory.
If removal fails, the result names the residual path and the provider retains
ownership for a cleanup retry on close, including failed decodes.
## Resource and lifecycle limits
- The decode runs with a 600 s deadline and a 4 MiB output capture budget;
a stopped decode reports `provider_timeout` and exceeded budgets report
`resource_constraint`.
- Manifest reads are bounded to 512 KiB before decoding UTF-8. Strings XML
reads are bounded to 8 MiB; larger documents are skipped with partial
coverage and an explicit limit, rather than reported as missing.
- `decoded_file_count` is capped at 100,000 files; the cap is reported in
the limitations when hit.
- Apktool's own decode failures (`AndrolibException`, directory traversal
refusals) surface as `unsupported_target` with apktool's reason preserved
verbatim.
## Real verification
`npm run verify:apktool -- --apk PATH` exercises both operations against a
real launcher. Record: apktool 2.7.0-dirty (Debian packaging) on Linux with
OpenJDK 25 against a signed aapt2-built probe APK carrying two resource
locales — launcher version, on-disk digest agreement, apktool.yml metadata
(1.2.3, SDK 24–34), manifest package agreement, default and `de` string
tables projected. Parser goldens in the test suite come from the same
decode. See `docs/testing.md` for the lane summary.
+18
View File
@@ -7,6 +7,16 @@ hashes, detected formats, bundle anatomy, runtime-family hints, and path-based
bridge hypotheses. It does not parse plist or CMS semantics or claim observed
runtime calls.
Framework hints match complete path segments such as `React.framework`,
`ReactNative.framework`, `hermes.framework`, `Flutter.framework`, and
`UnityFramework.framework`. Substrings in `Preact.framework`,
`Community.framework`, or `MyApp.framework` do not identify those families.
A generic `App.framework` also does not identify Flutter by itself. Runtime
families remain inventory-derived hints, not observed loading. Generic framework
and dylib paths do not establish Swift or Objective-C; this projection does not
decode language metadata. A bridge basis is inferred from the native path and
repeated for each paired script, rather than proving a particular binding.
```sh
rea project-apple-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}'
```
@@ -31,6 +41,14 @@ overall coverage becomes `partial` and a limitation explains the omission.
Duplicate inventory pages are merged by artifact identity and occurrence path;
their Evidence IDs remain attached as source Evidence.
Content nodes identify bytes by SHA-256 and report only content-derived formats.
Each occurrence reports its own `artifact_kind`, `artifact_format`, and executable
permission. Identical bytes can therefore appear as a script, resource, or native
addon at different paths without overwriting another occurrence's role. Package
formats such as APK and IPA belong to the occurrence; their ZIP bytes share a
content format. Graph and directory identities use locale-independent Unicode
ordering.
For IPA inventories, archive components outside every application root remain
in the component lists. Their JavaScript and native candidates are grouped with
other unrooted components, preserving the inventory projection's path pairing
+1 -1
View File
@@ -58,7 +58,7 @@ graph TD
end
subgraph "Configuration"
CONFIG["src/config.ts + src/config/<br/>Zod-validated env parsing<br/>provider settings and origins"]
CONFIG["src/config/<br/>Zod-validated env parsing<br/>provider settings and origins"]
end
subgraph "Tests"
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

+58
View File
@@ -84,6 +84,19 @@ uses isolated mode and an owned cache. Exact upstream profiles are recorded in
stack can accompany an unknown (`null`) NX indicator. ET_DYN can be a shared
library, and an absent canary symbol does not prove every function unprotected.
When complete layout Evidence is already retained, `inspect_analysis_view` /
`inspect-analysis-view` projects a summary, the mitigations or linkage facet,
one section or symbol, or a stable page without re-running the decoder. CLI
one-shot invocations pass portable inline Evidence JSON; an MCP session uses
the retained `evidence_id`. Page `limit` is required and bounded by the
measured MCP stdio budget documented on the tool contract.
Over MCP, `inspect_binary_layout` with `"detail": "summary"` retains the
complete layout Evidence in the session and returns only its summary view.
Its `normalized_result.parent_evidence_id` names the retained layout for later
section, symbol, mitigation or linkage views. The default `complete` detail and
CLI output are unchanged.
Complete results have a 32 MiB input, 64 MiB reply, 1 MiB combined diagnostics
and 30-second owned command deadline. The reply budget applies to the decoder
record; the CLI/MCP Evidence envelope adds copies and encoding overhead. The
@@ -129,3 +142,48 @@ malformed limit reports remain unknown with their read failure preserved. A
received signal alone does not establish its exact cause. Dynamic tags require
a complete DT_NULL inside PT_DYNAMIC; interpreter names and ranges end at the
first NUL, with any padding still represented by the original segment range.
## Portable PE resources
`inspect_pe_resources` / `inspect-pe-resources` inspects an explicit PE32 or
PE32+ file without an active target, native engine, Python, or Windows SDK:
```sh
rea inspect-pe-resources ./selected.exe --json
```
```json
{
"name": "inspect_pe_resources",
"arguments": { "path": "/artifacts/selected.exe" }
}
```
The complete Evidence identifies the stable artifact snapshot by path, byte
count and SHA-256. Resources retain separate type, name and language identities:
numeric IDs are distinct from UTF-16 names, whose original bytes are also
reported. Directory headers, entries, data entries and payloads retain original
file offsets and lengths. Each opaque payload has its own SHA-256; code page and
reserved data-entry fields are preserved.
RT_GROUP_ICON records expose original image descriptors and RT_ICON candidates.
A reference resolves only when an icon with the same numeric ID and language
exists. Missing references, other-language candidates and declared-size mismatch
remain explicit. Encoded dimensions are preserved (zero denotes 256 pixels).
This is static reference inspection; no image decoding, language fallback,
resource loading or selected-file execution occurs.
An absent resource data directory is a complete empty inventory. Malformed
headers, truncated tables, cycles, duplicate sibling identities, unbacked or
ambiguous RVA mappings, nonidentical overlapping ranges and unsupported tree
shapes fail explicitly, rather than returning partial inventories. Exact shared
payload ranges are supported. The supported tree has three levels: type, name,
and language. Other resource payload formats remain opaque.
`max_file_bytes` defaults to 64 MiB (maximum 512 MiB); `max_entries` defaults to
4096 (maximum 65536). CLI options are `--max-file-bytes` and `--max-entries`.
Metadata is bounded to 8 MiB; exceeding any budget fails without truncation.
Large Evidence envelopes may require a caller-configured MCP transport receive
buffer because envelope copies add overhead. Requests honor cancellation during
snapshot reading, directory traversal and payload hashing. The operation reads
regular files only and rejects symbolic links.
+37 -2
View File
@@ -14,15 +14,39 @@ REA can attach to a user-owned Chrome-family browser through the Chrome DevTools
- `inspect_web_page` / `rea inspect-web-page` captures DOM structure, accessibility nodes, scripts, resources, safe response/DOM metadata, attach-window network and console metadata, WebSocket frame sizes, workers, quota, and optionally selected storage key names, redacted storage-content fingerprints, or script sources.
- `analyze_web_bundle` / `rea analyze-web-bundle` parses selected script artifacts without execution and derives chunk edges, route and endpoint candidates, vendor fingerprints, static WebMCP declarations, and optionally source-map/original-source evidence.
- `observe_web_session` / `rea observe-web-session` arms an observation window of the requested duration for an external user action and records ordered reload, SPA navigation, redirect, failure, lifecycle, and target-termination metadata.
- `discover_webmcp_tools` / `rea discover-webmcp-tools` uses the experimental CDP WebMCP domain to return every in-scope registration and its complete structural input-schema summary inline. Registrations with the same name and URL in distinct observed frames retain separate identities. `tool_key` includes the observed frame ID; it is not a stable identity across navigation or browser sessions. Same-frame registration updates replace that owner only, and removal leaves other owners intact. REA never exposes `WebMCP.invokeTool`; malformed protocol payloads fail explicitly instead of returning incomplete tool metadata.
- `discover_webmcp_tools` / `rea discover-webmcp-tools` uses the experimental CDP WebMCP domain to return every in-scope registration and its complete observed `input_schema` declaration and canonical `input_schema_sha256` digest inline. Declarations are untrusted JSON data, including declared types, required fields, enums, examples and reference URLs. REA does not resolve schema references. These fields replace `input_schema_shape`. Registrations with the same name and URL in distinct observed frames retain separate identities. `tool_key` includes the observed frame ID; it is not a stable identity across navigation or browser sessions. Same-frame registration updates replace that owner only, and removal leaves other owners intact. REA never exposes `WebMCP.invokeTool`; malformed protocol payloads fail explicitly instead of returning incomplete tool metadata.
- `compare_web_captures` / `rea compare-web-captures` compares passive captures or exact-step-aligned browser scenarios. Scenario results commit reproducible literal normalization and expose alignment failures plus artifact-level action, screenshot, DOM, accessibility, URL, history, storage, and event differences. Missing or truncated evidence is never treated as equivalence.
- `capture_web_screenshot` / `rea capture-web-screenshot` returns a content-addressed visible-viewport PNG.
- `compare_web_screenshots` / `rea compare-web-screenshots` performs bounded local PNG pixel comparison without OCR or external services.
- The CLI comparison commands accept each capture, screenshot artifact or normalization policy as inline JSON or a JSON file path. Use files for screenshot artifacts and scenario captures, whose embedded PNG bytes can exceed the host's command-line length limit.
- Every surface has equivalent CLI and MCP contracts and returns Evidence provenance.
- MCP tools return complete results inline and include the Evidence ID. Session evidence can be exported with `export_evidence_bundle`.
Target discovery returns the complete in-scope target array in one result.
## Screenshot comparison memory budget
`compare_web_screenshots` admits both PNGs against a 256 MiB estimated
working-memory budget before inflating either image. This is a processing
buffer budget for this operation, not a PNG dimension limit, CDP transport
limit, or process RSS guarantee. Header-valid dimensions that exceed the
budget return `resource_constraint` with `details.resource: "memory"` and the
estimated and maximum working-set bytes. Invalid PNG structure remains
malformed input; encodings outside supported pixel-comparison coverage remain
unsupported-target errors.
The conservative estimate includes the two decoder-owned decoded input
buffers, the current image's concatenated IDAT buffer, Node zlib's default
16 KiB output chunk backing rounded up for retained chunks, the concatenated
inflate result while its output chunks are retained, one possible extra output
chunk before zlib checks `maxOutputLength`, unfiltered scanline storage,
RGB-to-RGBA expansion, and the first retained RGBA image while the second is
decoded. RGBA output aliases its unfiltered buffer and is counted once.
Admission uses checked integer arithmetic before image-sized allocation.
Caller-owned JSON/base64 strings, input parsing and validation, transport
buffers, garbage-collector behavior, and other runtime memory are outside this
estimate; the budget does not promise a bound on total process memory.
Electron `file://` pages use a separate provider and target boundary; see [electron-observation.md](electron-observation.md).
## Provider authorities
@@ -52,8 +76,19 @@ google-chrome \
REA does not launch, own, or terminate this browser. Use a dedicated profile and stop it yourself when the investigation is complete. Do not expose the debugging port on a non-loopback interface.
On Linux, a reachable but locked desktop keyring can stall Chrome before its
first navigation. For a dedicated investigation profile, add
`--password-store=basic` to bypass that keyring. Empty or placeholder frame URLs
then describe an unloaded page; REA continues to require an allowed, committed
URL. See [the startup investigation](https://github.com/morluto/rea/issues/1384#issuecomment-6093781686).
## Request boundary
CDP connections enforce the shared 64 MiB limit per WebSocket message. A larger
reply, including a valid reply from Chrome, fails with `payload_limit`. The limit
counts message bytes before JSON parsing; it does not bound the memory used by
decoded strings or JSON objects.
Discovery supplies a literal loopback CDP endpoint and returns all eligible
page targets unless an exact HTTP(S) origin filter narrows the result. Follow-up
inspection requests select one target; their default scope is its current origin. `localhost`, private-LAN
@@ -134,7 +169,7 @@ REA retains local observation data and removes only URL userinfo credentials, ex
- DOM snapshots retain node types, node names, value lengths, and attribute names, but not text or attribute values.
- Accessibility structure and roles are retained by default, while names and descriptions require `include_accessibility_text: true`.
- Network observations retain method, status, MIME type, size, type, initiator stack location, and complete URLs with userinfo credentials removed. Redirects reported by CDP are attached as ordered `redirects` on the one request ID, with the prior request URL, CDP response URL, method/type, response status/MIME/encoded length, request timestamp, and the next `requestWillBeSent` event timestamp. CDP delivers `redirectResponse` with that next request event, so the latter is an event boundary rather than an exact response timestamp. Redirect response headers and bodies are discarded; hops outside the selected origins are discarded with the request chain. Headers are discarded after an allowlisted projection of length/encoding, structured CSP/Link/policy fields, and untrusted agent hints. Cookies and authorization headers are never retained.
- Request/response bodies are not requested or parsed by default. When selected, only allowed-origin JSON media types are read, converted immediately to complete value-free property paths/types, and discarded. `Network.getResponseBody` is never sent unless JSON body shape capture is selected.
- Request/response bodies are not requested or parsed by default. When selected, only allowed-origin JSON media types are read, converted immediately to complete value-free typed paths, types and observation counts, and discarded. Each path segment is either `{ "kind": "property", "name": "raw property name" }` or `{ "kind": "array-element" }`; array-element types include primitives and nested arrays. Literal `*` properties remain distinct from array elements. `Network.getResponseBody` is never sent unless JSON body shape capture is selected. Comparison uses body shapes only when both captures selected them, and compares request/response shapes only where both observations provide those facts. Unavailable or truncated selected coverage makes equivalence unknown; observed differences still report changed.
- Console observations with a stack source retain call type, argument types, timestamp, and source location. When console text capture is selected, already-delivered primitive values are retained verbatim; objects, getters, and remote properties are never expanded.
- WebSocket observations retain direction, opcode, and payload byte length. When shape capture is selected, text frames are classified as text or complete value-free JSON shape; binary bytes, hashes, prefixes, and raw frames are never retained.
- Storage observations always redact values. Key names, IndexedDB names, and cache names require `include_storage_keys`; stable content fingerprints require the additional `include_storage_fingerprints` selection. Cookie fingerprints cover cookies applicable to the current main-frame URL, including its path, rather than every cookie path on that origin. Other storage remains scoped to the origin. Cache bodies above 64 KiB and partial IndexedDB remote objects make fingerprint coverage incomplete, so identical observations remain `unknown`.
+17 -4
View File
@@ -156,6 +156,18 @@ Storage cookies are scoped to the page URL at each capture. Unsupported action
tags, unknown fields, duplicate step IDs, and undeclared secret references fail
validation.
Cookies are installed before the initial navigation. Local storage entries are
seeded once per browser storage partition; session storage entries are seeded
once per origin in each top-level browsing context. Seeding occurs before the
first document scripts for that area. An origin first reached by a later action
receives its seed on that first visit. Application updates, deletions, and
empty values then persist across later navigations in the same area; a new
scenario starts with its own seeds. Partitioned frames can receive separate
local storage seeds even when they share an origin. The pre-script mechanism
uses CDP debugger instrumentation. The observer resumes only pauses whose top
frame belongs to its private seed script; page breakpoints and `debugger`
statements remain under the attached debugger client's control.
The result is Evidence with an initial state followed by one record per
declared action. Each step reports action status, elapsed time, sanitized URLs,
event bounds, and independently typed capture states for screenshot, DOM,
@@ -236,12 +248,13 @@ network metadata observation; listing `network` in `events` is then optional.
Each observed request object receives a capture-scoped `transaction_id`.
Requests sharing a URL remain distinct. Redirects link to the preceding
transaction only when it was observed; a null predecessor does not establish
that no earlier hop existed. Older captures without IDs remain readable and
their transaction association is unknown.
that no earlier hop existed. Request events require both transaction fields;
an absent ID is malformed capture data, while a null redirect predecessor is
an explicit unknown.
`scenario.network_content` records the resolved content selection. Comparing
captures with different selection, or legacy captures without that coverage
information, reports network evidence as unknown with a recovery instruction.
captures with different selections reports network evidence as unknown with a
recovery instruction.
Capturing more data alone does not establish a website change.
`network-content` events reference the exact request or response event through
-477
View File
@@ -1,477 +0,0 @@
# Incremental capability migration
This working guide tracks the migration in #740. Update it as concrete domains
migrate. Existing public contracts and domain-specific ports remain authoritative;
there is no new universal provider interface or fixed module manifest.
## Ownership to preserve
| Responsibility | Current owner | Migration direction |
| --------------------------------------------- | ----------------------------------- | ----------------------------------------------------- |
| Analyst semantics and Evidence representation | domain | Keep pure and provider-neutral |
| Named public input/output contracts | contracts | Keep exact CLI/MCP meaning and complete discovery |
| Producer parsing and external tool protocols | provider adapters | Keep behind the relevant typed port |
| Shared analyst workflows | application | Share between CLI and MCP |
| Concrete provider construction | composition, MCP startup | Keep fresh typed factories at the production boundary |
| Investigation Evidence and Unknowns | InvestigationRecords/EvidenceLedger | Consume narrow read/write/atomic record ports |
| Target/profile snapshots and invalidation | BinarySessionRecords/BinarySession | Keep binary-owned |
| Subprocess ownership and host primitives | process/windows | Reuse; preserve cancellation and cleanup |
| Public translation | CLI/MCP adapters | Delegate to shared workflows and named contracts |
Retain exact Evidence IDs, provenance, detached reads, atomic Evidence/Unknown
mutations and optimistic revisions. Preserve current close and failed-cleanup
record clearing while extracting ownership; #721 owns any retention-policy change.
Each CLI invocation and MCP connection keeps its own state. Provider registration
must not launch engines or install prerequisites.
## Migrate before generalizing
1. Record the actual callers, state, environment, protocol and verification owner
of the capability being migrated.
2. Move concrete construction behind its existing typed port. Preserve injected
ports, selected environment, queues, failure state and cleanup behavior.
3. Test both caller paths and the applicable package/real-provider boundary.
4. Use independently migrated capabilities to identify repeated metadata and
composition needs. Derive a small source declaration only when those needs
are established; keep unlike target/lifecycle semantics separate.
5. Move a coherent capability's files, fixtures and verification lanes in a
mechanical PR. Update all path-sensitive consumers in that same PR.
Pure helpers do not need an interface each. A capture-format adapter or typed
factory may be sufficient. Avoid generic JSON execution, external MCP catalog
passthrough, eager provider acquisition, new permission fields or a multi-package
rewrite. Optional loading should preserve successful peers and report the failed
capability without hiding tools from the catalog.
## Checks before and after a move
`npm run verify:test-discovery` compares actual Vitest file discovery with every
repository-owned `*.test.ts` under src and tests, including newly added files. The
check requires Git, includes untracked non-ignored tests, and excludes removed
paths during a move. It
rejects missing files and overlapping project ownership. It only lists files;
it does not replace behavior tests or real-provider verification.
Check imports, project isolation and coverage, development-test selection,
lint exceptions, catalog/generator imports, npm and CI verification entrypoints,
fixture ownership, and installed-package bridge/native path resolution.
Domain and contracts must not import application workflows, caller adapters or
provider implementations. Production composition is a deliberate outer boundary.
Other existing adapter imports will migrate incrementally; do not widen a lint
exception to conceal new protocol code inside application workflows.
`npm run verify:module-boundaries` parses repository-owned source imports,
reexports, type imports and literal dynamic imports, then checks their resolved
source layer. Nested names such as `domain/android` are domain code; `src/android`
is the provider adapter. The check runs with lint, including cached static gates.
It covers tracked and untracked non-ignored TypeScript source and skips cached
paths removed during a move. Pass exact source paths for a focused check.
Pure source and its tests keep inward dependencies. Application/server provider
construction guards cover the migrated deep, Android, firmware, JavaScript recovery and observation
implementations. Application workflows cannot import composition, including the
former binary runtime entrypoint; shared browser capture/export helpers remain admitted while their
ownership is reviewed. Test lane restrictions still use Oxlint. Producer-dependent
browser and managed comparison tests live in boundary lanes with their original
fixtures and assertions. This is a development guard, not runtime authorization.
Select verification by the claim changed: schema/composition, package, real
engine or host-native workflow. Record host/target prerequisites and source-owned
fixtures. Run heavy lanes serially with bounded workers/heaps and reuse existing
engines. Recording ports do not prove real provider or platform support.
## Extension examples to validate during migration
An implementation of an existing port should require a provider adapter, typed
production factory selection, exact producer parsing/provenance and matching
verification. Existing workflow meaning and public contracts should stay stable.
A new analyst capability deliberately adds semantics, named contracts, a typed
port/workflow when needed, both caller adapters, availability, documentation and
verification. Its integration is broader than swapping a provider. The migration
should eliminate incidental duplicate wiring, not erase those design decisions.
Update these examples with real migrated entrypoints before closing #740.
## First production factory migration
`src/composition/android.ts` and `src/composition/firmware.ts` construct providers
behind the existing AndroidAnalysisPort and FirmwareAnalysisPort. CLI registrars
pass their selected environment; MCP uses the process environment unless a caller
injects a port. Each factory call returns a fresh instance and acquires no process,
workspace or toolchain. Queues, cleanup-failure state and per-request cleanup stay
inside the provider. The existing launcher seams remain available to boundary
fixtures, which now exercise the production factories.
Application workflows and MCP registration must not import these concrete
providers. Composition may import their implementations. Binary composition also
uses this outer boundary after its direct-analysis callers were migrated.
This concrete pilot does not introduce a shared provider interface or module
manifest.
## Independent optional observation adapters
Browser observation, browser scenarios, Electron observation, Electron scenarios
and V8 Inspector observation now have separate factories in `src/composition/`.
CLI commands reuse them; MCP startup dynamically imports each factory independently.
`OptionalObservationProviders` describes these five existing typed ports only. It
is provisional startup wiring, not an extensible plugin manifest or a universal
provider interface.
A failed import or constructor retains the successful peers. The complete tool
catalog remains advertised. Session availability reports the failed adapter and
its actual reason, and affected handlers return the existing capability-unavailable
error. Explicit loading failures take precedence over configured availability.
Passive Electron and active Electron failures are independent; static JavaScript
analysis and runtime reconciliation remain usable without either adapter. CLI
Electron commands also load only their selected runtime factory at execution.
Source identities are available without importing the optional implementations.
Registration acquires no engines, probes no endpoints, changes no permissions and
installs nothing. Core transport failures and shutdown still use their existing
lifecycle. Fault-injection coverage uses the production loading/startup path and
actual MCP SDK calls; recording ports establish composition behavior, while the
real Inspector lane separately establishes runtime behavior.
## Investigation record ownership pilot
`src/application/investigation/InvestigationRecords.ts` owns one existing
EvidenceLedger per runtime. The production session composition constructs that
owner explicitly; the direct BinarySession constructor retains a fresh default
for compatibility. There is no second ledger, global store, persistence or new
retention policy.
The ledger, Unknown Evidence helper and the ledger's two original behavior tests
now live beside the owner in `src/application/investigation/`. Bundle validation
and record-owner consumers follow the new paths; retained-reference access still
uses the narrow record ports. The move preserves implementation bodies and test
assertions. Binary snapshot/cache files remain with their existing owner.
EvidenceReader, EvidenceWriter and EvidenceUnknownWriter describe existing
read/write/atomic callback needs. UnknownRegistryPort preserves optimistic
revisions and consistency verification. Non-binary MCP registrars use these
record types without depending on the binary execution/lifecycle surface.
BinarySessionPort retains its compatible record methods through composition.
BinarySessionRecords remains the snapshot owner and compatibility facade. It
passes the actual active target explicitly for recordUnknown/updateUnknown;
recordEvidenceWithUnknown keeps its target-free mutation subject. Snapshot import
merges records without notifying midway, then emits after the cache commits.
Bundle import retains the full change delta so Unknown-only changes notify even
when recordsAdded is zero. Clearing resets records, cache and invalidation before
notification; observer failures remain best effort after a committed mutation.
Close and failed-cleanup clearing, ordinary target-switch retention, detached
reads, Evidence identities and deterministic bundle transfer keep their existing
behavior. Snapshots still require an active target and concrete analysis profile;
extracting investigation ownership does not make them a target-free record store.
#721 remains responsible for any future lifetime-policy change.
## Inspector adapter ownership
`src/inspector/` owns V8 Inspector discovery, passive capture, script/target
location interpretation and its lightweight provider identity. The composition
factory and optional loader use this owner. Browser CDP connection, endpoint/value
and Electron file-location helpers remain deliberate shared adapter utilities at
their existing paths; no provider wire protocol moves into domain or process.
Loopback fixtures and producer boundaries now live under
`tests/fixtures/inspector/` and `tests/boundary/inspector/`. The socket-backed
unresolved-target reconciliation test moves from composition into the forked
boundary lane with its original assertions. Adapter tests retain fork isolation.
`npm run verify:inspector` keeps its public development entrypoint and delegates
to `scripts/verify/inspector/runtime-observation.mjs`, using the real Node fixture
under `tests/conformance/inspector/`. Catalog imports, source guards and test
discovery follow the new paths. Observation authority, lifecycle, producer
interpretation and caller-visible contracts stay unchanged.
## Auxiliary source declaration pilot
Artifact, macOS native and managed static metadata now belongs to each adapter's
`*ProviderMetadata.ts` module. The implementation and
`src/composition/auxiliaryAnalysisProviders.ts` reuse the same identity and exact
capability descriptors. The declarations reference existing AnalysisProvider
loaders; they cover these three disjoint auxiliary implementations only. Deep
candidate selection and the five typed observation ports remain separate.
The binary runtime reads these source declarations while auxiliary construction
stays lazy. The separate managed-only entrypoint retains direct construction for
its execution-free workflow. The MCP catalog generator reads declarations without
constructing implementations, using its canonical macOS platform; actual runtime
host restrictions remain explicit.
Discovery and binary operation-kind routing now consume canonical source contracts
rather than their generated JSON artifact. No declaration imports its generated
output. Generated catalog facts and public schemas stay unchanged.
All observation registrars resolve contracts by name. An isolated compiled-process
test reverses presentation arrays and performs actual MCP SDK calls to verify
advertised schemas and handler meaning. Reordering metadata must not select a
different operation, schema, provider or deep-provider priority.
## Android layer and verification ownership
Android workflows and their existing typed port live in `src/application/android/`,
pure APK/inventory semantics in `src/domain/android/`, and the named inspection
contracts in `src/contracts/android/`. The headless JADX producer remains in
`src/android/`; `src/composition/android.ts` supplies its fresh factory to both
caller adapters. Public names, result meaning and JVM/queue/cleanup limits are
unchanged. Inventory-only application projection remains execution-free.
The real lane and signal-cleanup helper belong to `scripts/verify/android/`; its
explicit downloader and fixed manifest belong to `scripts/fixtures/android/`.
`verify:android` and `fixtures:android` keep their command names and repository-root
`_reference/apk-integration/` fixture default. Synthetic producer fixtures stay in
`tests/fixtures/android/`, with matching boundary and composition ownership. Real
JADX CLI/MCP parity requires the fixed APK and existing audited JAR; synthetic
protocol/cancellation success does not establish that engine or an unverified host.
## Deep-provider source declarations
Hopper, Ghidra and IDA declare their implemented analyst operations in their
own `*ProviderCapabilities.ts` modules. Hopper's inventory is typed against the
existing direct-operation contracts; Ghidra reuses its inventory/function adapter
operations; IDA retains its read-only operation family. Frozen operation arrays
feed the existing capability builders without importing generated catalog data.
The catalog generator reads these source declarations and joins operation names
to canonical `TOOL_CONTRACTS`. A missing contract identifies the declaring provider
and operation. Public schemas and descriptions remain owned by contracts; the
declarations describe implementation coverage. Provider adapters must not consume
the generated MCP catalog that is derived from them. The resolved module guard
checks this edge while admitting canonical source contracts, generated package
metadata and the existing application snapshot-cache consumer.
Exact provider effects and lifecycle differences remain in their adapters:
Hopper's GUI and mutation effects, Ghidra's experimental Windows authority and
mutation restrictions, and IDA's attached/headless effects and live observations.
This source increment introduces no common provider lifecycle or new interface.
## JavaScript application ownership
`src/application/javascript/` owns JavaScript/Electron artifact analysis and
graph projection, feature/version/export/source comparisons, runtime Evidence
and reconciliation, observation ports, and source recovery workflows. Pure
analysis and public schemas keep their existing domain/contract ownership;
shared artifact inventory, investigation records and execution types remain
shared. CLI, MCP and production factories import the owning workflow directly.
`src/domain/javascript/` owns static parsing and semantic IR, application and
semantic graphs, Electron facts, runtime reconciliation, recovery result
semantics, and source-to-bundle comparisons. Shared Evidence, digests, ordering,
comparison semantics and historical-source graphs stay at their existing owners.
Native handoffs link exact-subject Evidence without selecting or executing a
provider.
`src/contracts/javascript/` owns the JavaScript/Electron observation and recovery
contracts, JavaScript-specific workflow requests, and their examples. The shared
`applicationToolContracts.ts` aggregate stays at the contract root because it also
owns reconstruction and Android/Apple projection operations. Canonical tool
aggregation, named handler binding and SDK schema presentation remain unchanged.
Catalog source paths, compiled verifier/SDK fixtures and recovery CI filters
follow the domain/contract owners.
`scripts/verify/javascript/` groups application-workflow, runtime-reconciliation,
large-digest and real-recovery entrypoints. Their existing npm commands retain
their invocation semantics. Recovery fixture compilation lives beside its
unchanged sources under `scripts/fixtures/javascript-recovery/`. Its default
REA entrypoint still resolves to `scripts/rea.mjs`. Managed conformance imports
the relocated compiled workflow; owning CI source filters follow the new paths.
`src/artifacts/javascript/` owns directory/ASAR reader construction and relevant
file acquisition, including root/nested byte verification, UTF-8 diagnostics and
nested reader cleanup. Its narrow factory returns the existing `ArtifactReader`;
the application retains input admission, inventory, graph construction and its
original root-reader `finally` close. Pure file facts live in
`src/domain/javascript/javascriptArtifactFiles.ts`, and the shared immutable
inventory snapshot lives in `src/domain/artifactInventorySnapshot.ts`. Inventory
options and integrity policy remain application-owned. Shared stream hashing
lives in `src/artifacts/ArtifactHash.ts`, preserving complete byte counts and the
bounded classification prefix. Acquisition/hash guards reject imports from
application, composition or caller adapters; JavaScript workflows use the factory
instead of importing concrete ASAR/directory reader classes.
ZIP, native-DMG and Mach-O inventory reader selection keep their existing
lifecycles. Runtime ports retain their distinct Inspector, passive Electron and
active Electron effects; shipped Electron hooks remain at their existing
provider boundary.
## Managed capability ownership
`src/domain/managed/` owns managed artifact and member semantics, reconstruction
import, native-boundary verification and application graph projection.
`src/application/managed/` owns their shared Evidence workflows, and
`src/contracts/managed/` owns their named contracts and examples. Producer
metadata/IL parsing stays in `src/dotnet/`; target resolution, Evidence, ordering
and investigation records retain their shared owners. Path-based member
comparison preserves its actual target/byte-digest admission and existing parser
helper.
`scripts/verify/managed/` groups the portable conformance entrypoint and its
support, manifest, oracle and completion-report helpers. Its PE byte fixture
builder and declaration live in `scripts/fixtures/managed/`, shared with the
installed-package lane and existing managed conformance tests. `verify:managed`
keeps its command name and optional caller-cwd manifest resolution. Compiled
catalog and generator imports follow the owners; document-check cache inputs
include the relocated runtime verifier and fixture files.
Portable byte fixtures, optional operator-local manifests, actual ILSpy oracles
and real Ghidra NativeAOT checks retain their distinct proof levels and
prerequisites. The existing NativeAOT fixture/engine lane keeps its owner. This
move preserves implementations, Evidence identities and generated commitments.
## Binary application ownership
`src/application/binary/` owns the active session, deep-provider registry and
evaluation, operation routing, disjoint provider composition, lazy auxiliary
clients, cancellation and client cleanup. Its records facade and snapshot
cache/files remain bound to the exact target and analysis profile. Investigation
records still have their separate owner in `src/application/investigation/`.
`AnalysisProvider.ts` stays shared because its identity/execution types also serve
nonbinary ports. `BinaryTargetResolver.ts` stays shared because Android, firmware,
managed and artifact workflows use its target parsing. Production wiring lives
in `src/composition/binary.ts`; application workflows gain no outward composition
dependency.
The three colocated application tests move with their owner. Composition cases
remain in `tests/composition/analysis-sessions/`; filesystem and SDK cases retain
their boundary lanes. The shared `tests/fixtures/binarySession.ts` factory supports
several capability families. Existing recursive application globs discover the
moved tests; bridge assets and real-verifier entrypoints remain at their owners.
## Firmware layer and verification ownership
Firmware workflows and their existing typed port live in
`src/application/firmware/`, pure request/result semantics in
`src/domain/firmware/`, and named contracts in `src/contracts/firmware/`.
`src/firmware/` keeps producer commands, report parsing, source copies, publication
and cleanup; `src/composition/firmware.ts` supplies a fresh typed factory.
The real lane belongs to `scripts/verify/firmware/analysis.mjs`; the fixture runner
and its unchanged Python producer belong together in `scripts/fixtures/firmware/`.
The npm command names and selected `REA_FIRMWARE_FIXTURE_ROOT` are unchanged. The
runner retains its working-directory-relative default; the verifier retains its
repository-root default. Both point to `_reference/firmware-integration/generated`
when invoked through the documented npm commands. Optional ext4/Ghidra lanes keep
their own prerequisites. Source-fixture generation and synthetic producer tests
do not establish real Binwalk/Unblob analysis or another host's execution support.
## Apple artifact capability ownership
`src/domain/apple/` owns Apple application anatomy/projection, asset catalog
facts, Interface Builder graphs, keyed archive semantics and plist values.
`src/application/apple/AppleApplicationService.ts` retains the shared workflow
that projects authenticated IPA/macOS inventory Evidence.
`src/artifacts/apple/` owns the actual producer boundary: directory acquisition,
assetutil invocation, plist/NIB decoding, encoded view-parent interpretation and
keyed archive inspection. These helpers are used by ArtifactProvider, retain
its existing typed analysis boundary, injected assetutil seam and original reader
cleanup, and do not require a new port for each helper. Producer code no longer
lives in the application layer. Guards reject application/composition/caller
imports from this owner while admitting pure facts and shared artifact readers.
Adapter-source tests retain their assertions in the existing forked adapter lane.
`scripts/verify/apple/` groups archive, asset catalog, Interface Builder,
Objective-C/Swift dispatch and macOS bundle verification. The macOS bundle fixture
builder lives in `scripts/fixtures/apple/`; NIB byte fixtures stay beside their
artifact decoder. Existing format-specific conformance sources and goldens keep
their locations, and relocated verifiers resolve them against their own file
URLs. Public npm entrypoints and CLI/MCP contracts stay stable; generated-document
cache inputs include the relocated runtime scripts and fixture builder.
Portable decoder and injected producer tests establish their format/boundary
claims. Actual Swift/Xcode, assetutil, native NIB, bundle signing and DMG lifecycle
claims require the real Apple lane. Native binary API/value-flow semantics and
shared cross-domain contract aggregates keep their separate owners.
## Artifact inventory and extraction ownership
`src/artifacts/inventory/` owns format classification, reader selection, inventory
policy, canonical scanning and artifact graph construction. The shared artifact
provider and JavaScript reconstruction workflow consume this owner. Snapshot
semantics remain in `src/domain/artifactInventorySnapshot.ts`.
`src/artifacts/extraction/` owns member selection, integrity checks and transactional
materialization through the existing readers and safe output tree. Reader cleanup,
cancellation, rollback, archive containment and caller-visible results retain their
existing behavior. Acquisition guards reject imports from these producer owners
into application workflows, production composition or CLI/MCP adapters.
`src/application/artifacts/ArtifactExtractionDestination.ts` owns the caller's
default temporary output-root choice for both CLI and MCP. The adapters pass this
destination to the existing provider operation; format handling and member writes
remain in the artifact owner.
Add format-specific acquisition behavior beside the inventory readers and exercise
its actual producer representation in filesystem boundary tests. Add caller
workflow behavior in the application owner and verify both adapters. The installed
package lane checks inventory identity and extraction through CLI and MCP; the
real Apple bundle lane separately establishes DMG mount and detach behavior.
## Binary production composition closure
`src/composition/binary.ts` is the shared production owner for deep candidate
construction, lazy auxiliary composition and the managed-only session factory.
It preserves the existing constructor bodies, selection policy and fresh session
per invocation. Factory registration acquires no engine or target.
`DirectAnalysis` and `DirectAnalysisStatus` receive these two existing factories
through `DirectAnalysisDependencies`. They retain configuration parsing, selected
status environment, cancellation, snapshot replay/binding, Evidence projection
and finally-close. The dependency uses the existing BinarySession type, including
its replay policy; it adds no universal backend or lifecycle contract.
`src/composition/directAnalysis.ts` binds the production factories for CLI and
one-shot managed MCP callers. Binding creates no session and stores no retained
analysis state. MCP startup constructs its connection session through the same
binary factory. Source and compiled fixtures use these entrypoints. The former
application runtime path is removed, and the source guard no longer admits its
outward provider/composition imports.
## Native analyst capability ownership
`src/domain/native/` owns portable native inspection, instruction/data types,
load-image facts, API boundaries, annotations, metadata recovery, UI observation
semantics and value/investigation graphs. `src/application/native/` owns shared
API projection, call routes, dispatch inspection and UI/value tracing. Its tests
keep the existing service lane. `src/contracts/native/` owns the named native
adapter contracts; shared official/enhanced aggregates remain at their owners.
Producer interpretation, external commands and host UI lifecycle remain in
`src/native/`, Hopper, Ghidra and IDA. The shared function dossier still lives in
`domain/hopperValues.ts`: its historical name does not make its meaning exclusive
to Hopper. This move retains existing typed ports, exact result schemas,
observed/derived/unknown distinctions, profiles and Evidence links.
Source and compiled verifier imports follow the new owners. Host UI and real
native-value verifier locations are retained until their own proof lanes migrate;
interactive macOS UI success and real dependency tracing require their respective
host/engine workflows. Portable source fixtures and injected call-route tests
establish their narrower boundaries, without expanding provider/platform support.
## Process capture and analyst workflow ownership
`src/domain/process/` owns scenario/capture validation, portable process trees,
trace specifications, observations, comparisons and the canonical process Evidence
identity. The standalone contract example lives in `src/contracts/process/`;
shared session contracts retain their broader investigation owner.
`src/process/capture/` owns the actual PTY boundary, terminal rendering, sampling,
selected child environment, filesystem snapshots/effects, runtime path admission,
event journal, settlement and resource cleanup. It reuses `src/process/` ownership
primitives and the Windows host substrate. Its identity import follows the
existing pure declaration directly. A source guard rejects outward application,
composition and caller imports; no new provider or lifecycle interface is added.
`src/application/process/` retains Evidence projection and file-backed CLI
capture/comparison workflows. Capture helper tests use the forked adapter lane;
Evidence/host integration tests use the serial process-boundary lane. Their
fixtures and assertions remain unchanged. Installed capability-probe URLs follow
the new compiled adapter path, including the optional-dependency failure probe.
Windows PTY capture retains its existing unavailable outcome because descendant
cleanup is not yet verified. Native Job Objects and a PTY binary do not establish
that capture workflow. Real POSIX capture/cleanup and installed terminal/PTY module
resolution require their actual host and package lanes; portable comparison
fixtures establish their separate evidence semantics.
+49 -5
View File
@@ -20,6 +20,23 @@ files when neither `--provider` nor `--snapshot` is supplied. See
[JavaScript artifact reconstruction](javascript-artifact-reconstruction.md)
for results, integrity checks and coverage.
The complete application Evidence can be hundreds of megabytes for a real
application. When an agent or a person reads the result, save it to a file and
project a summary, a module page or one module from the saved Evidence:
```bash
rea analyze-javascript-application /absolute/path/to/app --json > app-evidence.json
jq -c '{source: {kind: "inline", evidence: .}, view: {kind: "summary"}}' app-evidence.json > app-view.json
rea inspect-analysis-view app-view.json
```
For example, a 334 MB Obsidian application Evidence file yields a summary view
of about 10 KB. Replace the view with
`{"kind": "page", "collection": "modules", "offset": 0, "limit": 32}` for a
module page. See
[JavaScript application workflows](javascript-application-workflows.md) for
views, feature traces and comparisons that take the same saved Evidence.
## Native analysis
Configure [Hopper or Ghidra](installation.md#hopper), or the
@@ -80,7 +97,7 @@ or close. Provider failures are returned with their original reason. For an
`ambiguous` selection error, choose from `details.candidate_ids`; for
`provider_unavailable`, run `rea doctor --provider ID --json` to diagnose the
selected engine. See [task readiness](installation.md#check-readiness-for-your-task)
and [provider selection](adr/0001-provider-selection-and-analysis-profiles.md).
and [provider selection](mcp-contracts.md#identity-and-discovery).
The session reports work still in progress through `analysis_activity`.
A client timeout can end its wait while the provider continues analyzing.
@@ -96,6 +113,12 @@ an exact result when the target bytes, operation, parameters, provider and
settings match. Mutations and cursor-dependent calls are excluded from the
cache. Snapshot files are local and use owner-only permissions.
Snapshots retain eligible target-scoped question histories in full, including
mutation Evidence recorded while another target was active. Observations and
related questions must still belong to the saved target. If those dependencies
cannot be retained, the entire history is excluded instead of reverting the
question to an earlier revision or disposition.
```bash
rea analyze /absolute/path/to/program --provider ghidra --snapshot /absolute/path/to/analysis/program.json
# Repeat the same query to reuse its saved result.
@@ -109,6 +132,13 @@ cached result. `close_binary` accepts `snapshot_path` and optional
`overwrite: true` to save before releasing provider resources. A failed save
leaves the session open so the caller can resolve the output failure.
The MCP save receipt reports `primitive_entries`, `workflow_entries`, and
`evidence_records` separately. Zero primitive bindings can still accompany retained workflow
results and Evidence. These are cached observations, not a saved provider
database: only eligible exact queries can reuse a result, and new or live
queries can still require provider startup. The CLI uses the same snapshot
format and preserves these records when loading and updating it.
## Import, export and compare Evidence
Evidence records retain artifact identity, source locations, observations,
@@ -136,9 +166,20 @@ rea import-reference-source /absolute/path/to/source
```
The import records hashes and metadata for the supplied files, separately
from observations of the current app. File names do not automatically exclude
files. Set `REA_REFERENCE_SECRET_PATTERNS_JSON` to a JSON array of ignore
patterns when you want to exclude selected paths.
from observations of the current app. It honors the source tree's `.gitignore`
and applies default exclusions for common generated and dependency paths such
as `node_modules/`, `dist/`, and `*.log`. Pattern-based exclusions record the
matched pattern and whether it came from project, default, caller, or sensitive
path policy. Set `REA_REFERENCE_SECRET_PATTERNS_JSON` to a JSON array of ignore
patterns when you want to mark selected paths as sensitive; those patterns are
reported separately as configured-secret exclusions.
Re-import saved graphs whose pattern-based exclusions lack `pattern` before
using them in source-to-bundle comparisons.
JavaScript and TypeScript import parsing requires valid UTF-8. Malformed source
bytes retain their original hashes and sizes with a decoding diagnostic; REA
does not infer module targets from replacement characters.
Historical-source import requires safe no-follow file opens on Linux or
macOS. Native Windows returns `unsupported_host`; use Linux REA inside WSL
@@ -162,7 +203,10 @@ user permissions; consult the chosen guide for host requirements and effects.
## Output and exit status
The default terminal format is TOON. Use `--json` when saving results for a
JSON consumer. Output selection and formatting do not change operation status.
JSON consumer. `--json` is indented on a terminal and compact when piped or
redirected, which keeps large results smaller for agents and scripts; pipe
through `jq .` for indented files. Output selection and formatting do not change
operation status.
| Status | Meaning |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
+7 -1
View File
@@ -15,7 +15,11 @@ when both Evidence sets already exist.
The request supplies a literal-port loopback endpoint and, for inspection, a
target ID. REA accepts local hostless `file://` URLs that resolve to regular
files; remote hosts, encoded path separators, and nonexistent paths are
files, including pages a packaged application serves from inside `app.asar`.
For those, the first `.asar` path component that is a regular file is the
archive, the remainder must name a regular file in its header, and the reported
path is the canonical archive path joined with that member. Remote hosts,
encoded path separators, ASAR directories or links, and nonexistent paths are
rejected. The endpoint exposes every eligible target and its local path
metadata.
@@ -120,3 +124,5 @@ projection is intentionally target-only and partial: it binds the selected
application path and capture outcome to the static graph, while frames, scripts,
workers, and execution claims remain unavailable until a separate passive runtime
capture provides them.
ASAR observation reads the header through one open file handle, validates its declared lengths against the archive size, and limits encoded JSON headers to 16 MiB before parsing. The header cache also retains at most 16 MiB of encoded headers across eight archives. Oversized headers produce a scope refusal.
+6
View File
@@ -25,6 +25,12 @@ extraction have independent prerequisites; one does not require the other.
Both require util-linux `prlimit`, normally `/usr/bin/prlimit`; override its
absolute path with `REA_FIRMWARE_PRLIMIT_COMMAND` if needed.
REA retains at most 8 MiB of combined stdout and stderr per command. Exceeding
that diagnostic budget stops analysis with an explicit truncated-output error;
child process limits do not bound parent-side pipe retention. Completed commands
drain their output streams before recording diagnostics. Failed worker cleanup
retains the worker and workspace for retry before another request or at shutdown.
Unblob needs the external extractor for the selected format on its inherited
`PATH`: for example, `debugfs` for ext2/ext3/ext4. Its default Landlock sandbox
and skip rules stay enabled. Sandbox startup failures remain actionable errors;
+112
View File
@@ -0,0 +1,112 @@
# MIPS ELF analysis through Ghidra
This lane extends native ELF analysis; it does not execute MIPS code or rehost
firmware. It advances the generic-MIPS portion of
[#718](https://github.com/morluto/rea/issues/718), not the whole firmware roadmap.
PSP/Allegrex remains a separate specialization tracked in
[#1330](https://github.com/morluto/rea/issues/1330).
## Admission boundary
ELF `EM_MIPS` is retained as the provider-neutral `mips` family. The target also
retains class, byte order, `e_type`, raw `e_flags`, and inspected ABI declarations.
Recognition does not mean every provider or MIPS variant is supported. Existing
PE, managed and Mach-O architecture sets are unchanged.
The first Ghidra lane admits ELF32 `ET_EXEC`, little or big endian, with explicit
o32 and `EF_MIPS_ARCH_32R2` flags and no machine-specific or ASE encoding flags.
These are header declarations, not proof that every instruction conforms to
that ISA. ELF64, n32/n64, unspecified ABI, MIPS16/microMIPS, machine-specific
variants, shared/relocatable objects and PSP PRX are not covered by this lane.
Their family may be identified, but provider selection returns the specific
unsupported constraint rather than guessing a compatible profile.
Explicit `EF_MIPS_FP64` and `EF_MIPS_NAN2008` declarations are refused. Their
absence is insufficient: Clang can emit identical `e_flags` for FP32, FP64 and
soft-float targets. Target resolution also reads the 24-byte ABI flags record
identified by `PT_MIPS_ABIFLAGS` and/or `SHT_MIPS_ABIFLAGS`, without relying on
section names or the record being inside the initial 4 KiB header probe.
Program and section declarations must agree; duplicate, conflicting, truncated
or out-of-file records are rejected. Stripped section tables and section-only
records are supported. Extended table numbering is explicitly unsupported.
For carved ELFs whose section table extends beyond the captured file, REA
examines every complete captured section header and records the unavailable
headers as a limitation. A valid program-header ABI record can still establish
the supported declaration. Available section declarations must agree with it;
their duplicate, conflicting or unreadable records remain errors. A missing
program-header record does not make ABI declarations in uncaptured sections
absent or supply a default ABI.
The field layout follows
[`Elf_MIPS_ABIFlags_v0`](https://github.com/bminor/glibc/blob/master/elf/elf.h).
Provider admission requires record version 0, MIPS32r2, 32-bit GPR/CPR1, no CPR2,
and a double-precision or FPXX ABI declaration with no ISA extension, ASE or
unknown general flags. Missing records remain unknown rather than defaulting
to a compatible ABI, and this initial lane refuses them. Unknown record values
are retained for diagnosis but do not gain provider support. These checks bind
the declared interpretation; the integer-only fixture does not establish full
floating-point behavioral conformance.
MIPS header and ABI record facts are committed in the analysis profile so
interpretation changes invalidate profile-bound snapshots. The support-lane
identity is versioned independently of file identity. Evidence, lifecycle
outputs and saved snapshots preserve the `mips` family. Hopper and IDA adapters
do not implicitly gain MIPS support. Windows Ghidra P0 remains PE x86/x86-64 only.
## Use
With a caller-installed Ghidra and compatible JDK on a supported Linux/macOS host:
```bash
rea analyze /absolute/path/to/mips.elf --provider ghidra --json
rea function /absolute/path/to/mips.elf function_name --provider ghidra --json
```
MCP uses the existing tools, including `open_binary` with an absolute path and
`provider_id: "ghidra"`. No MIPS-specific tool catalog or emulator is introduced.
Inspect instructions, caller relationships and data alongside pseudocode. In
particular, delay-slot semantics are supplied by Ghidra, not reconstructed by
REA's ELF parser.
## Verification
The source-owned freestanding fixture is `tests/conformance/c/mips.c`. The
optional cross-target lane requires a caller-supplied Clang with MIPS targets,
LLD, GNU `readelf`, Ghidra and its compatible JDK; ordinary host-native checks
do not acquire these tools. `REA_MIPS_CLANG` selects Clang and
`REA_MIPS_READELF` selects GNU readelf (for example `greadelf` on macOS).
These are test-time prerequisites, not REA runtime providers.
```bash
GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra npm run verify:ghidra:mips
```
The lane compiles both byte orders and never executes the targets. GNU readelf
independently supplies header/ABI facts and symbol addresses, compared with the
production REA target resolver before provider startup. Its version, bounded
command output and selected tool path are retained in the verification report.
The parser deliberately recognizes only this fixture's GNU output, rejecting
missing, ambiguous or unexpected fields rather than substituting defaults.
Existing public MCP operations check Ghidra's **observed** language/compiler
specification and loaded-file hashes. The source-owned `mips-probe.S` supplies
fixed ADDIU and conditional-branch encodings: verification checks bytes, length,
immediate and direct destination, independent of decompiler variable names.
Global and string bytes are checked at independently reported symbol addresses.
ELF load-image results retain observations even though REA's independent
load-image comparison currently covers DOS, not ELF; this lane checks those
observations and does not relabel the upstream result as verified.
CLI/MCP discovery and decompilation, direct calls, target/profile/Evidence
identity, snapshot round-trip and final process cleanup remain covered.
For both byte orders, the lane also carves away the section table while retaining
all program-header payloads. It checks the actual Ghidra language, entry-address
decompilation, distinct artifact digest and missing-section limitations through
CLI Evidence and an MCP-produced snapshot. Caller-selected Ghidra heap limits
are passed to these child workflows.
Pseudocode presence is a liveness check, not proof of semantic equivalence.
Instruction decoding and reader agreement likewise do not establish runtime,
delay-slot execution or complete floating-point semantics. Assertion regressions
reject incorrect byte order, constants, destinations and loaded identities.
Parser/profile tests are narrower checks, not substitutes for this real-provider
run. Report the actual lanes run and leave unexecuted verification pending.
+64 -35
View File
@@ -1,16 +1,25 @@
# Optional NativeAOT metadata recovery
REA integrates [Washi1337/ghidra-nativeaot](https://github.com/Washi1337/ghidra-nativeaot)
through an optional headless adapter. The original source is an opt-in submodule,
pinned to `effeb734fc570c32650f88b159608979dc7b423e`; its MIT license and existing
source notices are retained. No upstream source or algorithms are rewritten.
REA has a built-in read-only snapshot parser for x64 PE targets with .NET 8 RTR
9.1 metadata. It parses the exact admitted Ghidra session snapshot and uses an
in-memory overlay for rehydrated metadata; it does not define Ghidra DataTypes,
labels, functions, or memory bytes. The hydration semantics are adapted from
[Washi1337/ghidra-nativeaot](https://github.com/Washi1337/ghidra-nativeaot) at
`effeb734fc570c32650f88b159608979dc7b423e` (MIT), cross-checked against
.NET's `MethodTable.h` at runtime commit
`a3b2d40328be0be3f8dd43f0e5cc925b8827b044` (MIT). The required notice ships in
[`licenses/nativeaot-parser-MIT.txt`](../licenses/nativeaot-parser-MIT.txt).
The initial tested layout is .NET runtime **8.0.22**, NativeAOT RTR **9.1**,
x86-64 ELF and native Windows PE **targets analyzed on Linux x64**, using
Ghidra **12.1.4** and JDK **21**. The build accepts any Ghidra 12.1.x release and
javac 21 or newer, and it compiles with `--release 21`. Real verification of
this layout remains the Ghidra 12.1.4 and JDK 21 pair. Other NativeAOT layouts,
architectures, and hosts are unsupported.
The optional headless Ghidra adapter remains available for database annotations
and broader recovery. It uses the same pinned upstream commit as an opt-in
submodule and is a separate, more capable workflow.
The parser currently handles x64 PE32+ and RTR 9.1, including bounded
DEHYDRATED_DATA processing, MethodTable relationships, virtual slots, and
frozen strings. Other RTR versions and PE architectures are reported as
unsupported or partial. The matching .NET 8.0.22 fixture is source-built and
the parser's Windows-host Ghidra workflow has not yet had a real Windows-host
run. This does not establish Windows Ghidra import or decompiler behavior.
Windows Ghidra P0 has no database mutation authority. A PE/CLI or ReadyToRun
assembly should use `inspect_managed_artifact`; it is not NativeAOT.
@@ -43,42 +52,62 @@ arbitrary caller-supplied bytes. The bounded loader accepts regular JARs up to
## Use existing tools
Open the executable with provider `ghidra`. `inspect_native_load_image` returns
optional `observations.metadata_recovery` inline, including the detected header,
layout, recovery status, type category paths/addresses, diagnostics, annotation
coverage and derived-memory SHA. The enclosing `unsupported` load-image status
for PE/ELF concerns independent DOS loader verification; metadata recovery has
its own status. It is not a failed import.
Open the executable with provider `ghidra`. For an x64 PE, `inspect_native_load_image`
returns `observations.metadata_recovery` inline from the captured source snapshot,
including the RTR header, MethodTable addresses, frozen strings, derived overlay
identity, and examined/recovered counts. Its enclosing `unsupported` load-image
status means independent PE load-image verification was not performed; it does
not mean the metadata parser failed or the executable failed to load.
Pass one returned type path or its typed address to `inspect_native_data_type`.
Its optional `metadata_recovery` includes related/base type, implemented
interfaces and virtual slots with targets and known procedure names. Follow
these with `analyze_function`, string searches and ordinary cross-references.
For CLI use:
Pass a returned MethodTable address to `inspect_native_data_type`. A direct PE
query also derives the snapshot metadata from the authenticated Ghidra session
handshake, so it does not require a preceding load-image call. In a persistent
MCP session, load-image followed by type inspection reuses that same derivation.
The database result remains `unavailable` when Ghidra has no DataType at that
address; its `metadata_recovery.source` is `read-only-derived-overlay` and
carries related type, interface, slot, and target observations. Generated
address identities do not claim original managed names. The parser does not
merge frozen literals into Ghidra's database string inventory. Follow slot
targets with `analyze_function` and ordinary cross-references.
The built-in CLI path uses a MethodTable address returned by the parser or
another observation:
```sh
rea inspect-native-load-image ./NativeAotFixture --provider ghidra --json
rea inspect-native-data-type ./NativeAotFixture --type /NativeAOT/MethodTables/Class_ADDRESS_MT --provider ghidra --json
rea inspect-native-data-type ./NativeAotFixture --address 0xMETHODTABLE_ADDRESS --provider ghidra --json
rea function ./NativeAotFixture 0xADDRESS --provider ghidra --json
```
No new MCP workflow or approval flag is required. Configuration opts into the
adapter; without it ordinary Ghidra profiles/results remain unchanged.
The generated `/NativeAOT/...` category path belongs to the optional headless
adapter. Use `--type /NativeAOT/MethodTables/Class_ADDRESS_MT` only when that
adapter is configured and has created the corresponding Ghidra DataType.
Built-in PE analysis includes its parser contract and resource policy in the
Ghidra analysis profile; non-PE profiles do not include that contract.
## Evidence boundaries
Discovery prefers an imported RTR symbol, otherwise the upstream initialized,
non-executable-memory signature heuristic. REA rejects ambiguous candidates,
unknown layout versions, malformed directory rows, unsupported flags and
unmapped ranges before recovery. It requires the verified dehydrated layout.
The built-in parser uses an initialized non-executable PE signature scan and
requires a unique RTR 9.1 header and exactly one DEHYDRATED_DATA row. Rehydrated
bytes live only in a parser-owned overlay, identified by virtual address, size,
and SHA-256; the caller's source Buffer remains unchanged. Limits derive from
captured section extents and format field bounds. Separate resource policies
admit up to 128 MiB of captured PE bytes, 64 MiB-equivalent parser work, 64 MiB
of exact parser-owned overlay/index Buffers, and 4 MiB of serialized NativeAOT
report JSON. These are local parser limits, independent of MCP delivery; the
buffer counter does not claim to cap V8 heap or total process memory. Rows that
do not fit the report budget are omitted with explicit partial status and
coverage. Coverage counts describe the pointer scan, recovered MethodTables,
and frozen-string candidates examined, not every possible runtime type or
object. Cancellation is honored during snapshot I/O and checked immediately
before and after parsing; the synchronous parser call itself is bounded but
cannot be interrupted mid-call. Parser output never claims that a Ghidra
database type was defined.
The adapter performs rehydration, method-table recovery and frozen-object
annotation in one ephemeral Program transaction. Fatal failure/cancellation
rolls it back. Recovery may change analysis-memory bytes, never the original
executable file. Derived ranges have a digest and **no original file offset**;
they are not captured runtime state. Candidate/committed instance annotation
counts distinguish partial frozen-object coverage. Coverage concerns the
recovered candidate set, not every possible object or every runtime type.
The optional adapter performs its annotations in an ephemeral Program
transaction. That workflow may change analysis-memory bytes, never the original
executable file. It is unavailable on Windows P0, which has no database
mutation authority.
REA preserves pre-recovery calling conventions and uses the loaded compiler
specification default for newly created methods. The upstream universal
+105
View File
@@ -0,0 +1,105 @@
# Ghidra provider semantics
REA imports one target into an ephemeral Ghidra database. Linux/macOS support
read-only analysis and atomic function-name/entry-comment edits; Windows P0 is
read-only. GUI controls and persistent database mutation are unavailable.
Executable bytes remain unchanged.
Use [installation](installation.md#ghidra) for supported hosts, prerequisites,
configuration, startup deadlines, resource controls, and cleanup recovery.
[Windows P0](windows-ghidra-p0.md) has its own admission and lifecycle boundary;
[NativeAOT observations](ghidra-nativeaot.md) include a built-in read-only PE
snapshot parser and a separate optional annotation extension. Check the
[release boundary](installation.md#released-package-and-main) when using npm.
See [import language and analysis seeds](installation.md#ghidra-import-language-and-analysis-seeds)
to override the header-detected language or seed analysis.
Provider selection and profile identity follow
[MCP contracts](mcp-contracts.md#identity-and-discovery). One deep
provider stays bound to the target; runtime failure never selects another
provider automatically. The contracts below describe Ghidra observations,
not equivalence with another engine's pseudocode or analysis database.
## Admitted inventory semantics
| Concern | Ghidra contract |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Program identity | One `analyzeHeadless` import produces exactly one Program; `list_documents` therefore returns exactly one name. |
| Addresses | Default memory uses lowercase `0x` hexadecimal. Non-default and external spaces use `<percent-encoded-space>:0x<hex>` and remain round-trippable. The handshake commits image base and default address-space name. |
| Symbols | `list_names` includes address-bearing memory and external symbols, including dynamic symbols, while excluding variable and no-address namespace records. Each item reports primary, dynamic, external, symbol type, and source facts. |
| Procedures | Both non-external and external functions are listed. A local thunk remains distinct from its resolved target; exact and qualified name lookup fails on ambiguity rather than guessing. |
| Strings | Only Ghidra-defined string `Data` is observed. Items report charset, byte length, and whether a required null terminator is missing. The API cannot distinguish a present terminator from fixed/Pascal layouts when no terminator is missing, so that state is named `present_or_not_required`. |
| Memory | Memory-block end addresses are exclusive. Read/write/execute, initialization, overlay, address space, and image base are direct Ghidra observations. |
| Inventory | Procedure, symbol, and string listings plus searches return the complete matching collection in one response; callers do not provide offsets or result-count limits. |
| Search | Literal and Java-regex searches return every match in the immutable provider-defined inventory; string search does not cover every text sequence in artifact bytes. Search waits for a reply or caller cancellation; there are no caller-supplied offsets or result-count limits. |
| Analysis state | The socket is exposed only after default auto-analysis completes. Established operations wait for their reply or caller cancellation; there is no fixed response-size ceiling. |
String-search completeness applies only to Ghidra-defined string `Data`. Packed
or undefined literals, including Rust strings, may be absent; an empty result
does not prove text is absent. Both list and search Evidence carry this
limitation. When an address is known, use `read_bytes` and `xrefs` to inspect
bytes and references.
## Admitted function-analysis semantics
| Concern | Ghidra contract |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Decompiler lifetime | One persistent `DecompInterface` is opened for the imported Program and disposed during bridge shutdown. Native decompilation has no fixed per-function deadline. External functions or functions without bodies return `null`; cancellation and native failure remain distinct. |
| Serialization | A FIFO sends one Program request at a time. Caller cancellation removes queued work promptly and is passed to active socket waits. This is an adapter safety commitment, not a claim that every Ghidra API is thread-safe. |
| Function identity | Every function result carries the entry address and Ghidra FunctionManager classification for external, thunk, and resolved thunk target. These are observations, not proof that unresolved targetless calls have been recovered. |
| Assembly and pseudocode | Assembly is complete Ghidra Listing text; pseudocode is Ghidra decompiler output. Neither is original source, and cross-provider comparison never treats Hopper and Ghidra text as equal or unequal semantic facts. |
| Instruction fast path | `read_function_instructions` returns every raw Listing instruction for the requested function without invoking the decompiler or whole-program name/string inventories. |
| Calls and references | Callers/callees contain only resolved functions. Reference edges preserve exact ReferenceManager type and call/jump/data/read/write/indirect/computed/conditional/terminal/external facts. Targetless computed flow remains unknown. Synthetic entry-point references without actionable memory sources are omitted explicitly. |
| CFG | Dossiers use `BasicBlockModel` and retain only non-call successors inside the function body. CFG topology is address-normalized for comparison; provider-specific block construction remains a declared difference. |
| P-code value flow | Function dossiers include up to 3,000 high-p-code operations, at most 64 inputs per operation, and 12,000 def-use edges. Results identify memory reads/writes, branches, and calls by p-code opcode, and mark decompiler-dead operations. Large results report truncation, an omitted-operation lower bound, and known omitted-input/edge counts. The dossier is an intra-function graph; `trace_native_values` composes derived parameter/argument and return/output dependencies across resolved calls. It does not resolve memory aliasing, call side effects, runtime behavior, persistent state, or business meaning. |
| Result extent | Function instruction scans and native API boundary observations remain complete. P-code flow is the explicit bounded exception; its count fields distinguish exact retained counts from lower-bound or known-omitted counts. Caller cancellation and provider failures remain distinct. |
Function extents and instruction completeness refer to Ghidra's analyzed body.
An inferred no-return call can terminate that body before subsequent bytes.
Pseudocode, assembly, procedure info, instruction windows, and dossiers report
observed terminal call sites in Evidence limitations, including resolved callee
names, addresses, and FunctionManager flags when available. Instruction windows
and dossiers also retain these warnings in their result limitations. An
unresolved callee or unestablished terminal-flow basis remains explicit. These
observations qualify the analysis; they do not prove that a no-return flag is
incorrect or recover excluded code. Analysis profiles version this observation
contract so older snapshots cannot replay unqualified results.
On non-Windows hosts, the ephemeral import repair clears no-return flags on the
known returning external ABI names `malloc`, `__tls_get_addr`, `memcpy`, `memset`,
`strlen`, and `__errno_location`. This relies on their expected ABI behavior;
external implementations are not inspected. The repair re-disassembles affected
terminal calls and refits their owning functions, preserving independent function
entries. If a recovered caller reveals a decoded return, its propagated no-return
flag and affected callers are repaired in the same pass. Unknown imports and
genuine no-return imports keep their flags. Analysis profiles version this repair
so snapshots produced before it are not reused. Windows P0 does not run it.
`npm run verify:ghidra` compiles the versioned C oracle into debug and stripped
host-native targets (x86-64/AArch64 ELF on Linux or Mach-O on macOS), plus a native
DWARF 4 type-layout object. It proves the admitted operations, external functions, resolved thunks, exports, stripped-name
behavior, direct and targetless indirect calls, typed references, strings/xrefs,
multi-block CFG, bounded p-code def-use/effect links, semantic enhanced workflows, cancellation, startup deadlines,
serialized concurrency, malformed-target rejection, profile identity, and
process/project cleanup against real Ghidra 12.1.4. Unit fixtures separately
cover startup deadlines, process exit, queued cancellation, and malformed wire
output.
`npm run verify:ghidra:cross-format` adds AArch64 ELF, x86-64 PE, and x86-64
Mach-O target coverage. It requires `clang`, LLD, and `lld-link`; set
`REA_CLANG`, `REA_LLD`, or `REA_LLD_LINK` to select them. The verifier checks
these tools before compilation. Keeping this matrix separate lets Linux
host/provider acceptance run with only the host compiler.
`npm run verify:ghidra:windows` checks source-owned native x86-64 PE applications;
`-- --x86` selects x86 and `-- --dll` selects DLLs, and the flags can be combined.
These lanes check all 25 read-only operations, target/snapshot/import SHA-256 linkage,
and project, endpoint, process, and runtime cleanup. The independent native
lane checks DACLs, handle admission, cancellation, and Job Object lifecycle.
`npm run verify:ghidra:windows:package` packs and installs REA into an isolated
prefix, then checks ordinary-user CLI/MCP operations against canonical contracts.
It accepts the same architecture and DLL flags and verifies the selected PE role
in the analysis profile.
All lanes require matching native controls; package startup alone establishes
only package compatibility.
+319 -21
View File
@@ -68,7 +68,17 @@ selects the npm release, and persistent MCP registrations are pinned to the
version that performed setup. Installing newer instructions does not update a
running server or its registration.
The release checked on **2026-10-07** was **5.0.0** (133 MCP tools), published
The npm release checked on **2026-10-11** was **6.3.0**, published from
[`74cf9e14`](https://github.com/morluto/rea/commit/74cf9e1401fcd89482fe39c27cc898f5858e9b72),
with bundled skill version 34. It does not include automatic Qwen Code, Pi, or
Hermes registration: `setup --client qwen_code`, `setup --client pi`, and
`setup --client hermes` reject those IDs before writing configuration. It also
does not honor `OPENCODE_CONFIG_DIR` when selecting OpenCode's configuration
directory. These workflows below require a source build or a later release
containing the relevant changes; `@latest` alone cannot select unpublished
changes.
The earlier release checked on **2026-10-07** was **5.0.0** (133 MCP tools), published
from the fixed checkpoint
[`b33236ec`](https://github.com/morluto/rea/releases/tag/rea-agents-5.0.0).
The public CLI, MCP catalog and target-free session, and isolated update from
@@ -95,7 +105,7 @@ npx skills add morluto/rea --skill reverse-engineer-anything
This installs agent instructions and bundled references, not REA MCP
registration or analysis engines. Follow the skill's
[conditional connection guide](https://github.com/morluto/rea/blob/main/skill-src/reverse-engineer-anything/SKILL.md#connect-only-when-needed).
[conditional connection guide](https://github.com/morluto/rea/blob/main/.agents/skills/reverse-engineer-anything/SKILL.md#connect-only-when-needed).
Working tools can be used immediately. If tools are missing, inspect the current
client's registration with `doctor --client codex --json` (substitute its client
ID), then plan repairs with `setup --client codex --dry-run --json`. Show and
@@ -135,16 +145,169 @@ listed after the table because its connector is not one of these files:
| Antigravity | `antigravity` |
| GitHub Copilot CLI | `copilot_cli` |
| Command Code | `commandcode` |
| Qwen Code | `qwen_code` |
| VS Code | `vscode` |
| Grok Build | `grok_build` |
| OMP | `omp` |
| Pi | `pi` |
| Hermes | `hermes` |
For OpenCode, setup writes the V1 `mcp.rea` entry, which OpenCode V1 and V2
For GitHub Copilot CLI 1.0.95, `gpt-4.1` model metadata can block ordinary
chat with REA's full input-schema profile before sending a model request
(`compaction_static_context_blocked`; [#1554](https://github.com/morluto/rea/issues/1554)).
For the native offline OpenAI-compatible BYOK adapter, full-profile chat and
analysis also passed with a distinct `COPILOT_PROVIDER_MODEL_ID` such as
`rea-gpt-4.1`, `COPILOT_PROVIDER_WIRE_MODEL=gpt-4.1`, and that distinct ID selected
through `copilot --model rea-gpt-4.1`. The local fixture requested
`COPILOT_PROVIDER_MAX_PROMPT_TOKENS=1000000`; configure the limit supported by
your backend. This keeps every full schema and the actual wire model intact.
It does not establish the effective client budget or fix the built-in-ID path.
The existing compact profile passed native chat and analysis with the complete
tool inventory on Linux using a loopback model fixture. After setup, add
`"REA_MCP_INPUT_SCHEMA_PROFILE": "compact"` to the `env` object of the
`mcpServers.rea` entry in Copilot's `mcp-config.json`, preserving its other
settings, then restart the client. Compact advertisements can reduce nested
schema constraints; REA still validates complete canonical inputs. Full-profile
`gpt-5.4` metadata is also verified locally. Live model API acceptance and
Windows remain unverified; see [native client verification](testing.md).
For [Pi](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/mcp.md),
automatic setup requires a build containing the integration; npm 6.3.0 does not
include it. See [released package and main](#released-package-and-main).
In a supported build,
setup writes a `type: "stdio"` entry under `mcpServers.rea` in the user-level
`~/.pi/agent/mcp.json` and installs the bundled skill under `~/.agents/skills`.
Use `rea setup --client pi --dry-run --json` to inspect the plan, then
`rea setup --client pi --yes --json` to approve it. Check the registration with
`rea doctor --client pi --json`. Pi reads `mcp.json` as strict JSON, like its
own loader: comments, trailing commas, a byte-order mark, or an empty existing
file are invalid, and setup reports them instead of rewriting the file. Repair
such a file to plain JSON first, then rerun setup.
Setup follows Pi's `PI_CODING_AGENT_DIR`: unset or empty selects the default;
`~` and `~/` expand to the home directory; absolute paths and file URLs select
that directory; relative paths stay relative to the command's working directory.
On Windows, native paths, `~\`, and Git Bash/MSYS, Cygwin, and WSL drive paths
are normalized as Pi does. Run REA and Pi from the same working directory when
using a relative override. Pi has no profiles: `OMP_PROFILE`, `PI_PROFILE`,
`PI_CONFIG_DIR`, and OMP's `enabledServers`/`disabledServers` lists do not affect
Pi registration. Doctor accepts an omitted `type` for stdio but reports a
non-stdio type as invalid; `enabled: false` stays disabled.
REA configures only the user scope. Pi also reads `.pi/mcp.json` in trusted
projects; a same-name project entry can replace the user entry or override its
enabled state and exposure. Check that file if the user registration is aligned
but unavailable in a project. An extension that registers `/mcp` can replace
Pi's built-in MCP support and use its own configuration instead. Run `/reload`
in an existing Pi session after changing servers outside the session.
For Qwen Code, automatic setup requires a build containing the integration;
npm 6.3.0 does not include it. See
[released package and main](#released-package-and-main). In a supported build,
setup registers `rea` in the `mcpServers` table of the
user-level `~/.qwen/settings.json`, or `$QWEN_HOME/settings.json` when configured.
Setup and doctor follow Qwen Code's tilde and working-directory-relative home
overrides. Qwen Code also discovers personal skills in `~/.agents/skills`,
where setup installs the bundled workflow.
Gemini CLI uses `$GEMINI_CLI_HOME/.gemini/settings.json` when that home override
is nonempty, including its shared personal skills at
`$GEMINI_CLI_HOME/.agents/skills`. Setup and doctor check MCP allow/exclude
policies from system defaults, user settings, trusted workspace settings, and
system overrides. Workspace trust follows `GEMINI_CLI_TRUST_WORKSPACE`,
`GEMINI_RESTRICTED_MODE`, the effective `security.folderTrust.enabled` setting,
and the selected `trustedFolders.json` (including
`GEMINI_CLI_TRUSTED_FOLDERS_PATH`). Settings in an untrusted workspace do not
participate. A workspace or system `mcpServers.rea` replaces the entire user
entry; setup stops if the winning definition conflicts with its planned entry.
Review those files manually: setup never edits administrator/workspace settings
or grants workspace trust. Trust supplied only by a running IDE is outside this
standalone CLI check.
Codex treats an unset or empty `CODEX_HOME` as `~/.codex`. Devin honors
`XDG_CONFIG_HOME` for its `devin/mcp_config.json` on non-Windows systems.
For OMP, setup writes a `type: "stdio"` entry to the user-level
`~/.omp/agent/mcp.json`. It follows `PI_CONFIG_DIR` and
`PI_CODING_AGENT_DIR` (relative to the setup working directory), and the profile selected by `OMP_PROFILE` or
`PI_PROFILE` (`~/.omp/profiles/<name>/agent/mcp.json`). Setup also removes
`rea` from that file's `disabledServers` list, which would otherwise hide the
registration. Doctor treats an `enabled: false` entry as active when
`enabledServers` lists `rea`, as OMP does, unless `disabledServers` also lists
it. Run setup under each profile that should load REA.
For Hermes, automatic setup also requires a build containing the integration;
npm 6.3.0 does not include it. See
[released package and main](#released-package-and-main).
In a supported build, setup writes a `mcp_servers.rea` entry to `config.yaml`, preserving
comments and unrelated settings. It resolves that file from `HERMES_HOME`, else
from the platform default Hermes itself uses — `%LOCALAPPDATA%\hermes` on
Windows, `~/.hermes` elsewhere — including any `HERMES_DATA_DIR_SUFFIX`. Hermes
connects an entry unless `enabled` is false, so setup states `enabled: true`.
Hermes personal skills install under the active Hermes home's `skills` directory.
Setup, doctor and uninstall follow the root's `active_profile` selection, as
plain Hermes CLI commands do. An explicit `HERMES_HOME` pointing to
`profiles/<name>` selects that named profile directly. An invalid, missing or
deleted sticky profile is reported instead of writing into the default home;
repair the profile or run `hermes profile use default` before retrying.
REA follows `HERMES_HOME` whitespace trimming, environment-variable expansion,
and home expansion before resolving that profile. Setup previews the resolved
configuration and skill destinations; doctor and uninstall use those same paths.
### DeepSeek Harness
DeepSeek Harness uses a Cordis YAML patch sequence rather than a `mcpServers`
object. REA's `setup --client` does not edit this format. For Harness
`0.2.0-rc.2`, append the following entry to `$DSH_HOME/cordis.patch.yml`
(`~/.dsh/cordis.patch.yml` when `DSH_HOME` is unset). Preserve existing patches
and replace the executable paths with absolute paths from your installation:
```yaml
- insert:
- id: rea-mcp
name: "@deepseek-ai/dsh-mcp-client"
config:
serverName: rea
transport: stdio
command: /absolute/path/to/node
args: ["/absolute/path/to/rea/scripts/rea.mjs", mcp]
cwd: !!js process.cwd()
```
For a global npm installation, the launcher is under
`$(npm root -g)/rea-agents/scripts/rea.mjs`. Check the Node executable with
`command -v node`. Register `serverName: rea` only once in each active profile,
then restart Harness. It exposes tools as `mcp__rea__<tool_name>`.
Run `rea setup --skill --dry-run`, review the destination, then
`rea setup --skill --yes` to install the workflow in `~/.agents/skills`.
Harness discovers that directory, or `$DSH_AGENTS_HOME/skills` when configured;
its native `skill` tool can load `reverse-engineer-anything`.
REA's optional [native client verification](testing.md#end-to-end-integration-and-golden-evidence)
checks headless chat, skill loading, all tool input schemas and actual analysis
using the installed Harness and a local model fixture. This establishes the
Harness integration, with live DeepSeek API compatibility remaining unverified.
See the [Harness MCP guide](https://github.com/deepseek-ai/deepseek-harness/blob/639ed015397290b3745d163aafe02ffee4aa3f84/packages/mcp/mcp-client/README.md)
for its native configuration contract.
### Other client settings
For OpenCode, npm 6.3.0 does not honor `OPENCODE_CONFIG_DIR`; use a source build
or a later release containing the override support when selecting a custom
configuration directory. See [released package and main](#released-package-and-main).
In a supported build, setup writes the V1 `mcp.rea` entry, which OpenCode V1 and V2
both load. If the configuration already uses OpenCode V2's native
`mcp.servers` table, setup registers REA there instead and replaces any earlier
`mcp.rea` entry from REA.
`mcp.rea` entry from REA. Setup honors `OPENCODE_CONFIG_DIR` and
`OPENCODE_CONFIG`, preferring the later-loaded JSONC file when both JSON and
JSONC exist. The ordinary XDG global configuration still participates when a
custom directory is selected. Doctor checks the merged user registration; uninstall removes
REA-owned entries from every applicable user file so an older entry cannot
become active again. Malformed applicable files block setup before changes.
Grok Build loads `[mcp_servers.rea]` from `$GROK_HOME/config.toml`, or from
`~/.grok/config.toml` when `GROK_HOME` is unset. Setup edits that server
`~/.grok/config.toml` when `GROK_HOME` is unset or empty. Setup edits that server
table, `[mcp_servers.rea.env]`, and a root `disabled_mcp_servers` entry that
names `rea`. It sets `startup_timeout_sec = 30` and leaves every other name
in that list. The shared skill installed under `~/.agents/skills` is already
@@ -182,6 +345,20 @@ default. Hopper is a separate optional choice: setup shows its proposed
installation or connection and requires its own explicit approval. It can also
save verified paths for an existing Ghidra installation.
The bundled skill is installed where each selected client discovers personal
skills: Claude Code uses `~/.claude/skills` (or
`$CLAUDE_CONFIG_DIR/skills` when configured). Gemini CLI uses `.agents/skills`
under its selected home; Antigravity 2.0 uses `~/.gemini/config/skills`.
Other integrations, including Qwen Code, use `~/.agents/skills`.
A mixed selection plans each distinct destination. Selecting the skill without a client uses the shared
directory. Setup leaves existing skill copies in other locations untouched.
`doctor --skill --json` verifies the selected copies against the bundled
instructions and references. Consumers should use `identity.skill.state`,
`installed_version`, and `installed_tool_count` for skill readiness. The
obsolete `installed_catalog_digest` field has been removed; current catalog
identity remains available at `identity.catalog`.
After selection, review the plan's exact paths and changes and approve before
REA writes files or installs Hopper. You can cancel at any prompt.
@@ -189,14 +366,21 @@ Before applying changes, REA checks your current configuration. The plan lists:
- an existing Hopper installation, a verified existing Ghidra installation, or the official Hopper package it proposes to install;
- each detected agent configuration path;
- the REA skill destination;
- each selected REA skill destination;
- external software, network origins, integrity evidence, and package-manager
commands.
Malformed or unsafe existing configuration blocks the whole transaction before
Hopper installation or any file write. Declining or pressing Ctrl-C makes no
changes. Agent configuration writes preserve unrelated
entries, create backups, use atomic replacement, and verify their result.
changes. Agent configuration writes preserve unrelated entries and comments,
create backups, use atomic replacement, and verify their result. Setup and
uninstall retain an existing `.rea.backup` rather than replacing the first snapshot.
Setup also retains valid environment overrides in REA's existing server entry,
such as `REA_MCP_INPUT_SCHEMA_PROFILE` and `REA_MCP_MAX_RESPONSE_BYTES`.
Detected provider settings replace only matching environment keys.
Setup and doctor report a malformed REA environment map or invalid runtime
setting before setup writes files. Repair the named setting in the client
configuration; setup does not silently discard the rest of the map.
After setup, REA reports which agents, analysis tools, and workflow files passed
its final checks. Restart any agent named in the completion message, then begin
@@ -279,7 +463,7 @@ vendor-defined limits, and a paid license is optional. REA reuses any detected
installation and preserves Hopper during uninstall.
The supported native host baseline is macOS 12+, Ubuntu 24.04+, Fedora 41+,
64-bit Arch Linux, or CachyOS. Ghidra and IDA have their own provider-specific
Nobara 44+, 64-bit Arch Linux, CachyOS, or Omarchy. Ghidra and IDA have their own provider-specific
host requirements; Windows Ghidra uses the [experimental P0 boundary](windows-ghidra-p0.md).
On macOS, approved setup downloads the official DMG, checks its published size
@@ -310,6 +494,19 @@ host mount and the rest of `/tmp` remain unchanged; this fallback never invokes
`sudo`. `rea doctor --provider hopper --json` reports the selected
strategy and both host and effective mount facts.
The supported Linux demo forwards additional launches into its existing
application, even across private displays. REA therefore reserves one Linux
Hopper application per user across cooperating REA processes. A competing
CLI or MCP session receives the owning session ID before Hopper is launched,
for both the same target and a different target. Switch targets through that
MCP session, or close it before starting another session. Closing the owner
releases the reservation. This does not attach to or claim ownership of
manually opened Hopper applications.
Stale lease recovery is serialized. If an interrupted recovery leaves its
reservation directory, the diagnostic identifies that exact path. Stop REA
sessions before removing that recovery directory and retrying.
### Launcher paths and troubleshooting
On macOS, REA uses
@@ -392,6 +589,17 @@ Closing or switching a target closes its bound Hopper document, shuts down REA's
bridge and removes its temporary socket directory while preserving the Hopper
application and unrelated documents. A `cleanup_incomplete`
result identifies resources whose cleanup could not be verified.
REA retains unresolved cleanup ownership and any confirmed shutdown phases.
After addressing the reported failure, retry `close_binary` on the same
connection. Unconfirmed document or process cleanup retains the target/application
lease and prevents another client from launching against that owned resource.
Once document and process closure are confirmed, the lease can be released even
if temporary-file cleanup fails. Another client can then launch, but the owning
client must finish its retained cleanup before starting again.
An unconfirmed external document can be retried while its authenticated bridge
remains connected. If that bridge has disconnected, another close cannot confirm
the document: inspect and close the reported document in Hopper before ending
the owning REA connection.
### Hopper in CI
@@ -424,8 +632,11 @@ and JDK 21. Each installation must include the native decompiler for the host
architecture in `Ghidra/Features/Decompiler/os/<platform>/` or the corresponding
`build/os/<platform>/` directory. Linux ARM64 uses `linux_arm_64`; official
release archives may require you to build that native component separately.
REA checks the executable prerequisite and does not build or install native
tools, or change Gatekeeper quarantine settings.
REA checks the executable prerequisite by inspecting the file's own executable
header, so a native component built for another platform or architecture is
reported as incompatible instead of being admitted from its directory name, and
a header that cannot be read or recognized is reported as unknown. REA does not
build or install native tools, or change Gatekeeper quarantine settings.
The adapter exposes 25 read-only operations: thirteen inventory/name/search
operations and twelve function-analysis operations. These cover metadata,
@@ -434,11 +645,13 @@ dossiers, instructions, recovered data types, measured load mappings, loaded
memory bytes, and observed file offsets. Independent load-image attestation
supports DOS MZ and explicitly selected COM; PE returns its measurements with that limitation.
On Linux and macOS, `annotate_native_function` also edits a function name and/or
entry comments atomically and returns refreshed analysis. These session metadata
edits leave executable bytes unchanged and are discarded on close. GUI controls
entry comments atomically and returns refreshed analysis, and `set_address_name`
and `set_addresses_names` name a function entry or any other mapped address
(creating or renaming its primary label) with per-address success results. These
session metadata edits leave executable bytes unchanged and are discarded on close. GUI controls
require Hopper; Windows P0 remains read-only.
Windows P0 admits native x86 and x86-64 PE applications on fixed local NTFS volumes.
Windows P0 admits native x86 and x86-64 PE applications and DLLs on fixed local NTFS volumes.
The npm package bundles native Job Object ownership, protected private runtime
DACLs, and handle-based path admission; no separate addon installation is needed.
See the [Windows Ghidra P0 guide](windows-ghidra-p0.md) for verified scope and
@@ -479,14 +692,14 @@ installs, upgrades, or modifies Ghidra or Java.
Each verified session uses an ephemeral temporary project and isolated
home/cache/config/temp paths. REA passes `-readOnly`, `-deleteProject`, uses
Ghidra's default analysis and resource settings, and loads its packaged Java
Ghidra's default analysis settings, and loads its packaged Java
bridge via `-scriptPath`; it never opens an existing user project. Linux and
macOS use a current-user-only local bridge socket and descriptor. The
project remains under the selected temporary directory. If its Unix socket
pathname would exceed the host's byte limit, REA allocates a separate mode-0700
socket directory under `/tmp` and removes it on close, cancellation, or failure.
Diagnostics retain the actual endpoint and both owned directories.
On macOS, REA starts the inspected JVM directly using Ghidra's own LaunchSupport
On Linux and macOS, REA starts the inspected JVM directly using Ghidra's own LaunchSupport
configuration. Apple platform shell wrappers hide their environments from
ownership inspection, so retaining those wrappers would prevent verified
process-group cancellation during startup.
@@ -501,8 +714,9 @@ import and auto-analysis. The first Ghidra-backed query starts that work lazily.
The provider startup deadline is 330,000 ms by default for import, analysis,
bridge, and health readiness. Large binaries can need more: set
`REA_GHIDRA_STARTUP_TIMEOUT_MS` to an integer between 1 and 2,147,483,647
milliseconds in the server environment. An absent, empty, invalid or out-of-range
value keeps the default. REA parses the supplied configuration environment and
milliseconds in the server environment. An absent setting uses the default;
empty, invalid or out-of-range supplied values fail configuration validation.
REA parses the supplied configuration environment and
passes the deadline to each provider client; a startup failure is returned by the query that triggered it,
without exposing partial analysis. This deadline is separate from MCP transport
initialization and the client's deadline for that individual tool call. A client
@@ -519,6 +733,86 @@ is no fixed per-operation or response-size ceiling. Unresolved computed calls
remain unknown, reference-kind provenance is preserved, and provider-specific
pseudocode is never treated as original source or Hopper-equivalent text.
### Ghidra import language and analysis seeds
Ghidra detects the language from the executable header. To set it (for example, Borland C++ PE images):
```bash
export REA_GHIDRA_LANGUAGE_ID="x86:LE:32:default"
export REA_GHIDRA_COMPILER_SPEC_ID="borlandcpp" # optional; requires a language
```
REA passes `-processor`/`-cspec`, checks both against the installation's `.ldefs`, and records them in the analysis profile. DOS imports reject an override.
To seed code that auto-analysis cannot reach (computed jumps, pointers in data):
```bash
export REA_GHIDRA_SEED_FILE=/absolute/path/to/seeds.tsv
```
Each line is `address<TAB>kind[<TAB>name]`, where kind is `function`, `code` or `label` (a label needs a name). Addresses are `0x` hex in the default space; `#` lines are comments. A pre-script applies seeds before auto-analysis: functions from the highest address down, then code, then labels. The seed digest is part of the analysis profile, and the session fails if the applied seeds differ. Result limitations report the outcome counts; a seed fails when it overlaps an instruction Ghidra already decoded.
Label seeds can name mapped uninitialized storage such as `.bss`; function and code seeds require initialized bytes.
### Ghidra heap and CPU controls
Set resource controls in the environment that launches the CLI or MCP server,
before opening a new Ghidra session. On Linux and macOS, REA chooses the first
nonempty setting in this order: `GHIDRA_HEADLESS_MAXMEM`, `GHIDRA_MAXMEM`, then
`2G`. The chosen value becomes the JVM's `-Xmx` argument. Use a JVM heap-size
value such as `512M` or `2G`; an invalid value causes Java startup to fail.
The supported Ghidra 12.1.4 Windows headless script consumes the same settings
with the same precedence.
For a small target on a constrained host:
```bash
export GHIDRA_HEADLESS_MAXMEM=512M
```
In PowerShell:
```powershell
$env:GHIDRA_HEADLESS_MAXMEM = "512M"
```
An MCP client must pass this setting to its REA server process; changing an
unrelated terminal's environment does not reconfigure an existing server or
JVM. A 512 MiB heap was verified with small native fixtures, but larger targets
can require more memory. The Java heap limit does not bound JVM RSS, Node's
heap, or total memory used by the process family. The startup deadline controls
waiting time independently of these memory settings.
REA clears `_JAVA_OPTIONS`, `JAVA_TOOL_OPTIONS`, `JDK_JAVA_OPTIONS`, and
`GHIDRA_JAVA_OPTIONS` inherited from the caller, and owns
`GHIDRA_HEADLESS_JAVA_OPTIONS`. Custom flags injected through these variables
are not supported configuration. On Windows, REA replaces `JDK_JAVA_OPTIONS`
with its own isolated home/temp settings and `-XX:-UsePerfData`; on Linux and
macOS it supplies isolated paths directly to Java. Use the supported heap
settings above instead of adding a second `-Xmx` through an injection variable.
The Linux/macOS launch sets `-XX:ParallelGCThreads=2` and
`-XX:CICompilerCount=2`; the supported Windows headless script also sets these
counts. These constrain particular JVM thread pools, not all analysis threads
or CPU usage. REA does not pass Ghidra's `-max-cpu` option or expose a general
Ghidra CPU limit. When needed, apply host CPU affinity and scheduling controls
to the REA process and verify the resulting JVM's affinity. Select CPUs allowed
on the host; do not assume CPU numbers from another machine are valid.
Verify controls at their consumer after the first Ghidra-backed query starts
the JVM: inspect that owned JVM's effective `-Xmx` and GC/compiler flags, CPU
affinity, and observed memory use. Do not infer them from the parent shell's
environment or the absence of an error. On Linux, `/proc/<jvm-pid>/cmdline`
contains the launch arguments and `/proc/<jvm-pid>/status` reports
`Cpus_allowed_list` and `VmRSS`. Inspect only the process belonging to this
session and retain the resource flags needed for the measurement rather than
copying full command lines or environments into reports. Heap and affinity
settings affect cost and latency; they are not part of REA's semantic analysis
profile identity. See [real-provider testing](testing.md) for bounded
verification workflows.
### Ghidra diagnostics and verification
Unexpected request failures retain their original internal cause. CLI and MCP
errors expose Error names, messages, and available codes under
`details.diagnostics.failure_cause`; other rejection values retain their
@@ -560,8 +854,12 @@ rea uninstall --purge-data
Uninstall preserves Hopper, Node.js, Evidence files, captures, unrelated skills
and other MCP servers. Purging removes only REA's cache and state under
`~/.rea`; malformed client configuration or purge-path symlinks stop the
operation. See the [CLI guide](cli.md#output-and-exit-status) for exit statuses.
`~/.rea`. A client configuration that is malformed, unreadable, or at an unsafe
path stops the operation before anything is removed, and a client that fails
while being updated stops the remaining removals. A purge path that is a
symbolic link is retained and reported rather than followed. Uninstall checks
REA's managed shared and Claude Code personal skill locations. See the
[CLI guide](cli.md#output-and-exit-status) for exit statuses.
## MCP Registry
@@ -582,7 +880,7 @@ For a client that requires manual configuration, use:
"mcpServers": {
"rea": {
"command": "npx",
"args": ["-y", "rea-agents@6.1.0", "mcp"]
"args": ["-y", "rea-agents@6.4.0", "mcp"]
}
}
}
+12
View File
@@ -73,6 +73,18 @@ The directed relation vocabulary is `contains`, `loads`, `imports`, `maps_to`,
and `changed_from`. Provider names are deliberately absent from both
vocabularies.
For a `maps_to` edge targeting a source-map node, the edge carries
`resolved_path` and `declared_url_sha256`. The target node's reference
observation carries that same digest and the exact `declared_url`; match the
digest to select the URL belonging to that edge when several references share
one physical source map. The full URL is kept out of node identity, display
label, and edge properties, so large inline data URLs are stored once per
source-map reference.
Consumers previously reading `edge.properties.declared_url` should follow
`target_node_id` and select the observation by `declared_url_sha256` instead.
Node labels serve display; the observation preserves the original URL.
For example, a source-owned synthetic fixture proves this path without using a
third-party application:
+111 -23
View File
@@ -2,12 +2,15 @@
REA derives a complete reachable feature trace from one authenticated JavaScript
Application Graph and compares two authenticated graph versions. The MCP tools
are `trace_application_feature`, `trace_javascript_semantics`,
`compare_application_versions`, `compare_source_to_bundle`, and
`compare_javascript_export_shapes`; their CLI equivalents use the same names
with hyphens.
are `inspect_analysis_view`, `trace_application_feature`,
`trace_javascript_semantics`, `compare_application_versions`,
`compare_source_to_bundle`, and `compare_javascript_export_shapes`; their CLI
equivalents use the same names with hyphens. `inspect_analysis_view` projects a
summary, module page, or one module from already completed application
Evidence; it does not walk relationships.
These workflows consume Evidence produced by
`inspect_analysis_view` also projects retained `inspect_binary_layout`
Evidence. The remaining workflows consume Evidence produced by
`analyze_javascript_application` or `reconcile_javascript_runtime`. They do not
read an artifact, execute application code, attach to a process, or open a
native-analysis provider. Static artifact observations, passive runtime
@@ -20,6 +23,15 @@ artifact digest and structural graph ID. Semantic tracing requires the semantic
relation graph and reports when it is unavailable rather than treating missing
data as an empty graph.
The semantic graph wire format stores shared non-location provenance once in
its required `evidence_contexts` table. Each node, relation, fingerprint, and
unknown retains its exact `evidence.location` and names the owning context with
`evidence.context_id`. This is a breaking representation change: consumers
reading fields such as `evidence.authority` must look up the context by ID and
combine its fields with the fact's location. Semantic trace results include the
canonical context subset referenced by their returned facts, so those facts
remain self-contained in the response.
## Feature tracing
Select one literal seed kind: node ID, route, string, API, IPC channel, module,
@@ -57,13 +69,12 @@ validation boundaries, and built-in resource acquisition/release.
Mutation tracking covers explicit member assignments, updates, deletion, and
loop assignment targets, including the supported local aliases and shared
nested references. Calls such as `Object.assign`, `Reflect.set`, and
`Reflect.deleteProperty`, and writes reaching a caller's object through another
function's parameter, are not tracked by this mutation pass. These channels
can leave an initializer-derived literal in the graph even after the runtime
value changes. Treat such a result as an uncovered mutation channel, not as
proof of the current runtime value; a follow-up needs to model that channel
and verify its caller/alias behavior.
nested references. Calls conservatively invalidate exposed mutable references;
callee bodies and built-ins such as `Object.assign`, `Reflect.set`, and
`Reflect.deleteProperty` are not interpreted to establish exact post-call
values. This uncertainty does not prove that a call actually mutated a value.
Interprocedural aliasing beyond the supported call-site references remains
outside this mutation pass.
Function fingerprints commit normalized syntax, control-flow shape, relation
shape, literal sets, arity, and detected effects without using local names or
@@ -79,6 +90,44 @@ keep the result ambiguous. Runtime Evidence can later corroborate an exact
mapped candidate, but structural reachability, semantic influence, runtime
observation, and causal proof remain separate claims.
Semantic literal nodes keep their complete value in `properties.value`; literal
queries match that field. String labels use `string literal` when that is
shorter than the complete JSON value. A literal's `identity.role_key` commits
its canonical JSON value as `value-sha256:<digest>` when the digest key is
shorter; smaller values keep their existing JSON key. This keeps large values
out of identity and display metadata without expanding short values or
truncating their Evidence.
New analyses therefore produce different IDs for hashed literals from the
earlier payload-bearing role keys. Use IDs returned by the selected parent
graph and read literal values from `properties.value`, rather than decoding
role keys or labels. Previously stored graphs and their original IDs remain
valid inputs.
Endpoint nodes keep the exact endpoint in each observation's `properties.value`;
semantic request and response nodes keep it in `properties.endpoint`. Endpoint
identity keys use `value-sha256:<digest>` over the canonical JSON string when
that is shorter, or when the original value starts with the reserved digest
prefix. Other short endpoint keys remain unchanged. Endpoint labels use the
shorter of the exact value and `<kind> endpoint`; semantic request/response
labels use the shorter of the endpoint and operation method. These labels are
display metadata, not endpoint lookup values.
New analyses therefore change hashed endpoint IDs and longer endpoint labels.
Use IDs from the selected graph and read the complete endpoint properties;
previously stored graphs still support their original IDs. Literal endpoint
search, semantic tracing, and version comparison use the preserved values.
Event and listener nodes likewise preserve the complete event name in
`properties.event_name`. Event role keys use the same reserved-prefix string
digest rule, scoped to the emitter; repeated registrations, removals, and
dispatches keep one event per exact emitter/name pair. Long event labels use
`event`, and listener labels use the shorter of `<method>:<name>` and
`<method>:listener`. Dynamic names remain `null` with explicit uncertainty. New analyses
change hashed event IDs and longer event/listener labels; query the preserved
name or select IDs from the parent graph. Previously stored graphs keep their
original IDs and remain valid trace inputs.
## Version comparison
REA pairs entities only when a tier produces one unique candidate on each side.
@@ -134,25 +183,64 @@ Direct return expressions, including expression-bodied arrows, are evaluated
through an execution-free value lattice. Literal object fields and direct
return sites are represented in the result. Calls, dynamic spreads, computed
keys, and parser recovery remain partial or unknown.
Objects and arrays passed to calls, constructors, or tagged templates, used
as method receivers, or stored through property targets are not assumed
unchanged afterward. Property stores conservatively retain reference escape
uncertainty rather than pretending to execute later writes. References
handed back by local functions, methods, constructors, async functions, and
generators also retain escape uncertainty, including when the call is read-only;
this does not establish that a mutation occurred. Aliases
and shared children in spread and rest copies retain that uncertainty; copied
primitive slots and unrelated containing properties remain known. Object rest
excludes consumed keys, array rest excludes the consumed prefix for known
arrays, and later explicit data properties and methods replace earlier object
spread references. A known array prefix does not expose values from a following
spread. Accessors, custom or uncertain iteration, unknown computed keys, and
unknown spread lengths retain conservative uncertainty.
Nested callable returns are not assigned to their parent callable. Projected
graph observations carry source ranges but never source text.
Return variants pair only when a literal discriminant such as `/type` has one
unique occurrence on each side and pairing is reciprocal. Changes use JSON
Pointer paths with `added`, `removed`, `changed`, or `unknown` status. A missing
field is added or removed only when the relevant parent-property coverage is
complete on both shapes. The output includes exact selector candidates,
omissions, Evidence links, coverage, and limitations; it does not execute
JavaScript. When runtime semantics matter, run behavioral probes directly
against the relevant application versions and capture them through the
available browser, Electron, or process workflows.
unique occurrence on each side and pairing is reciprocal. Source order never
implies correspondence. Each retained variant contributes a property inventory
of observed JSON Pointer names, including fields whose static values stay
unknown, plus that variant's parent-property coverage.
Changes use JSON Pointer paths with `added`, `removed`, `changed`, or `unknown`
status and a separate `presence` object (`present`, `absent`, or
`unknown-coverage`) on each side. A name is `added` or `removed` when one paired
shape proves presence and the other proves absence. Complete parent-property
coverage can establish absence even when field values stay unresolved. Identical literals are
omitted. Unresolved values that remain on both sides stay `unknown` when the
projections differ, and are omitted when presence is unchanged and the unknown
projections match. Incomplete spreads and other partial parent coverage keep
one-sided names `unknown` with `unknown-coverage` on the incomplete side.
Unpaired variants remain visible as unknown changes and still list their
property inventories, each with its own `source_range`. Inventories exclude
array holes and slots whose presence was invalidated by mutation; an unresolved
value alone does not make an observed property uncertain. `summary.added` and
`summary.removed` count
presence-level add/remove as well as literal value add/remove;
`summary.unknown` does not absorb complete-coverage presence-only gaps.
A partial comparison still records an unknown in the MCP session when matching
uncertain projections produce no changes and `summary.unknown` is zero.
The output includes exact selector candidates, omissions, Evidence links,
coverage, and limitations; it does not execute JavaScript. When runtime
semantics matter, run behavioral probes directly against the relevant
application versions and capture them through the available browser, Electron,
or process workflows.
## CLI and verification
All five CLI commands accept inline JSON or a path to a JSON file. The CLI
All six CLI commands accept inline JSON or a path to a JSON file. The CLI
returns an Evidence record directly. Put the full records in a later CLI input;
a separate CLI process has no retained MCP connection state.
File inputs must be regular files; symlinks to regular files are accepted.
Directories, named pipes and device files produce an input error before JSON
parsing.
For a literal string trace, analyze your supplied tree once, then build the
input from the saved Evidence (replace the target and seed):
@@ -167,8 +255,8 @@ writeFileSync("trace-input.json", JSON.stringify({
rea trace-application-feature ./trace-input.json --json
```
MCP analysis returns an envelope containing `result`, `evidence_id`, and full
`evidence`. If the connected server advertises retained references, reuse its
MCP analysis returns the complete Evidence record, with the operation result
in `normalized_result` and its identity in `evidence_id`. If the connected server advertises retained references, reuse its
exact returned ID as `{"kind":"retained-evidence","evidence_id":"RETURNED_ID"}`
in `application`, or `left`/`right` for comparisons. `RETURNED_ID` is a template,
not a literal valid ID. Native Evidence arrays still use complete records.
+149 -15
View File
@@ -22,7 +22,7 @@ The tool reads the caller-selected local directory or ASAR path directly:
```bash
rea analyze /absolute/path/to/apps/app.asar --json
rea analyze-javascript-application /absolute/path/to/apps/app.asar \
--json
--integrity-policy record-and-continue --json
```
Generic `rea analyze` selects this static provider for directories and `.asar`
@@ -47,24 +47,37 @@ The equivalent MCP input is:
```json
{
"input_path": "/absolute/path/to/apps/app.asar",
"format": "auto"
"format": "auto",
"integrity_policy": "fail"
}
```
`input_path` must be absolute. `format` accepts `auto`, `asar`, or `directory`.
`integrity_policy` accepts `fail` or `record-and-continue`; both CLI routes and
the MCP tool default to `fail`.
The result retains the canonical local path, root artifact digest, artifact
manifest and graph commitments, JavaScript Application Graph, static
Electron summary, reconstruction statistics, and explicit limitations. It does
not require a live Hopper, Ghidra, browser, or Electron process.
The application graph selects the shallowest `package.json` outside
`node_modules` as its package root, breaking equal-depth ties by Unicode
code-point order. Dependency manifests remain package observations but do not
declare Electron main or renderer entries. If only dependency manifests are
present, the inventory artifact remains the graph root.
## ASAR integrity
ASAR inventory checks Electron integrity metadata for embedded archive entries
and supplied `.asar.unpacked` companion files. An integrity failure identifies
the logical path, declared and calculated SHA-256 values, and whether the entry
was unpacked. By default, a mismatch is returned as a failure with its artifact
context. Requests that support `integrity_policy` can explicitly select
`record-and-continue` to inspect verified siblings while retaining the mismatch.
context. Application analysis can explicitly select `record-and-continue` to
analyze observed bytes while retaining each contradiction's declared and
observed hashes and `observed-untrusted` trust. Such results mark application
graph coverage partial and include every contradicted path in the limitations.
Mismatched nested ASARs stay opaque rather than being expanded. An unpacked
entry whose companion bytes were not supplied remains `unavailable`.
An unpacked entry whose companion bytes were not supplied remains
`unavailable`. REA continues analyzing embedded JavaScript and records the
@@ -82,9 +95,9 @@ queries use per-file range indexes, while call sites use exact-range lookups.
Existing node budgets and coverage reporting remain in effect.
Progress identifies the source file being parsed and projected. Cancellation is
checked between files, with event-loop yields that allow notifications and
completed file-local allocations to be released. A single file's synchronous
parser and semantic extraction still need to finish before that boundary.
checked between files and throughout result transfer. The owned analyzer can
be stopped while its synchronous parser or semantic extractor is active;
the CLI/MCP process remains available for control requests.
Graph and Evidence identifiers hash canonical JSON incrementally, without
assembling a single string for the whole graph. The canonical bytes and existing
@@ -105,17 +118,85 @@ Field selection remains useful when the caller needs a
smaller view, for example `--format json --filter-output
evidence_id,normalized_result.statistics`. Streaming output does not bound the
memory needed to construct the analysis graph itself.
JavaScript source parsing, static analysis and semantic projection run in one
owned analysis process, reused sequentially across files. Target code is never
executed. The analyzer defaults to 1024 MiB of V8 old-space and a 300000 ms
deadline per source, including startup and fact transfer. Select
`max_heap_mb` and `analysis_timeout_ms` through MCP, or `--max-heap-mb` and
`--analysis-timeout-ms` on the dedicated CLI command. These choices control the
analyzer; the caller's `NODE_OPTIONS` still controls the CLI/MCP process heap.
V8 old-space limits do not impose a process RSS limit.
A source that exhausts the analyzer heap does not terminate the CLI/MCP
process. Completed static facts are retained, other files can still be analyzed,
and unexamined semantic relationships remain explicit unknowns. The parent
also checks transfer expansion and accumulated results against its remaining
heap before accepting semantic facts. A resource-limited result has partial
coverage, the observed limits and an `analyze-javascript-source` unknown scope
with the specific failure, including captured diagnostics when available.
Resource failures do not increment syntax parse failures. There is no fixed
source-length cutoff.
Static observations also need memory when expanded into nodes, relationships
and Evidence. If that expansion does not fit, the file node retains
`static_analysis` and any admitted `semantic_module_analysis` observations,
including their exact values and source locations. Use the public modules item
view to read them. The graph marks those unexpanded relationships as unknown.
If cumulative result capacity is exhausted, analysis stops; inventoried but
unexamined files remain present with explicit unknown scopes.
A timeout stops the remaining analysis and returns typed failure details with
completed partial Evidence. MCP failure details return
`partial_observation: { kind: "retained-evidence", evidence_id: "..." }`
after recording succeeds, so `inspect_analysis_view` can open that analysis
directly without serializing the entire partial graph into the error response.
CLI failure output retains the complete partial Evidence.
Cancellation after source analysis begins likewise
retains completed facts; an SDK client may reject its cancelled request before
receiving that reply. On the same MCP connection, inspect the Evidence bundle
and use the retained analysis ID with `inspect_analysis_view`. Owned analyzer
cleanup is verified before its private files are released. Cleanup uncertainty
is reported separately and retains ownership for retry.
CLI workflows parse larger JSON input files incrementally from one verified
regular-file handle, without constructing a document-sized string. Smaller
files retain native JSON parsing. Both paths require strict JSON and valid
UTF-8, and return one complete value; the assembled object still needs memory.
An individual JSON string exceeding the native length limit or the available
heap headroom for assembly returns
`resource_constraint` with `input_reason: "too-large"`. Supply a smaller valid
value; for Evidence workflows, re-analyze a smaller selection of the original
target and use its complete Evidence. Splitting JSON text or trimming Evidence
fields does not produce a valid workflow input.
Evidence bundle and analysis snapshot file readers still decode whole
documents. Their runtime string-limit failures report a resource constraint
with the selected path, observed bytes and UTF-16 limit, rather than malformed
JSON.
`analyze_javascript_application` returns the complete analysis Evidence by
default. Select `"detail": "summary"` to retain that complete Evidence in the
current session and receive only its `inspect_analysis_view` summary: artifact
identity, statistics, Electron surface counts, application and semantic
coverage, limitations, and `normalized_result.parent_evidence_id`. Pass that ID
to `inspect_analysis_view` for module pages or items, or to the application
workflows as a retained reference. The summary does not repeat or truncate the
analysis; a server without session retention refuses summary detail with
`capability_unavailable`. CLI output is unchanged and always complete.
MCP prepares the complete repeated response incrementally against the pinned
SDK's 10 MiB stdio receive-buffer budget. Oversized results return an actionable
transport constraint and the exact same-session Evidence reference. Use
`trace_application_feature` to inspect a selected module's relationships, or
`export_evidence_bundle` to write the complete canonical bundle without a
document-sized allocation. Same-session analysis reads reuse authenticated
immutable snapshots; foreign inline Evidence is still parsed and authenticated.
`inspect_analysis_view` with the retained Evidence ID for a summary, one
module, or a stable page of module identities. Use `trace_application_feature`
once a module, route, or string seed is known, or `export_evidence_bundle` to
write the complete canonical bundle without a document-sized allocation.
Same-session analysis reads reuse authenticated immutable snapshots; foreign
inline Evidence is still parsed and authenticated.
See [MCP tool results](mcp-contracts.md#tool-results) for larger client buffers
and `REA_MCP_MAX_RESPONSE_BYTES`. Follow-up results remain complete and can also
exceed the transport budget. Compact result views are tracked separately in
[#1050](https://github.com/morluto/rea/issues/1050).
exceed the transport budget.
## What is reconstructed
@@ -172,6 +253,46 @@ while locally shadowed receivers can still contribute network endpoint
candidates. A template recovered with a parser error and no cooked value stays
dynamic; its raw spelling is not treated as a valid JavaScript string.
RPC client syntax also contributes network endpoint candidates, in both
`analyze_javascript_application` and `analyze_web_bundle`, distinguished by
`mechanism`:
- `trpc:procedure:<method>` records the static member path between the root
expression and the method, such as `invoice.list` in
`root.invoice.list.useQuery(...)`. tRPC proxies keep these property names
through identifier minification. React hooks and TanStack option factories
(`useQuery`, `useMutation`, `useInfiniteQuery`, `useSubscription`, suspense
and prefetch variants, `queryOptions`, `infiniteQueryOptions`,
`mutationOptions`, `subscriptionOptions`) are recognized directly. The
vanilla `query` and `mutate` methods are recognized on a root bound to
`createTRPCClient` or `createTRPCProxyClient` in the same lexical binding, or on a
path of at least two segments in a source containing `TRPCClientError`,
`trpc-accept`, or `/trpc`. Factory bindings must have one unconditional
initializer and no binding assignments; shadowed locals do not inherit client
identity. `subscribe` additionally requires a tRPC observer
argument (`onData`, `onError`, `onStarted`, `onStopped`, `onComplete`, or
`onConnectionStateChange`). `this` roots, browser globals, and any path
containing an RTK Query `endpoints` segment are never procedures; cache-key
helpers such as `queryKey` issue no request and are excluded.
- `trpc:link:<link>` records the literal `url` option of `httpLink`,
`httpBatchLink`, `httpBatchStreamLink`, and `httpSubscriptionLink` when the
link's callee name survives bundling, including `(0, module.httpBatchLink)`
import-call wrappers.
- `graphql:query`, `graphql:mutation`, and `graphql:subscription` record a
named operation found at the start of a string or cooked template literal —
the name must be followed by variable definitions (`($`), a directive, or a
selection set starting with a field name — or in a precompiled
`OperationDefinition` document object. A graphql-tag `loc.source.body` copy is
not reported twice. Anonymous operations are not reported.
A procedure path is the server-side procedure name, not a resolved URL; the
transport URL depends on the link configuration and batching. When the proxy is
reached through a member expression, such as a webpack module binding
(`l.S.invoice.list`) or a property holding the proxy (`o.api.post.byId`), the
recorded path keeps those leading carrier segments; the procedure path is its
suffix. Utility calls such as `useUtils().invoice.list.fetch()`, `useQueries`,
and links whose callee was renamed by a minifier are not recognized.
Each recovered bundle module retains the exact factory-source digest. A complete
bounded AST also receives a `babel-ast-v1` structural fingerprint that ignores
ordinary identifier names while retaining syntax, literals, operators, object
@@ -195,6 +316,14 @@ substitute version-dependent Electron defaults for omitted `webPreferences`.
Dynamic option objects, bridge keys, API objects, and IPC channel expressions
remain unknown and make coverage partial.
Electron API identity follows proven lexical module aliases. Reassigned bindings,
dynamic selections, and visibly overwritten namespace members are unresolved.
Direct and destructuring assignment, loop, update, and delete targets are checked
through namespace aliases; unrelated member writes do not discard observed API
identity. This static check does
not evaluate arbitrary call side effects or runtime registration. Missing findings
do not establish that an application has no Electron boundary usage.
IPC pairing is an inference, not an observation. A renderer `invoke` pairs only
with one unique `ipcMain.handle`/`handleOnce` candidate on the same exact literal
channel; a renderer send pairs only with one unique `ipcMain.on`/`once`
@@ -282,6 +411,8 @@ such as `./web3:app.js` still names a local artifact.
Package `exports` fallback arrays are supported both at the top level and under
the root `"."` entry. The resolver selects targets in declared order using the
same conditional and invalid-entry handling as nested exports arrays.
For imports and requires, the active Node conditions include `module-sync`;
earlier active conditions retain precedence over later ones.
ESM relative module paths and selected package exports targets use URL suffix handling
and one percent-decoding pass. CommonJS relative paths and legacy package main
@@ -293,8 +424,11 @@ do not select a later entry. Rejected references retain the package metadata
path, original target, failed constraint, and importing source location.
HTML script references resolve to exact inventoried files after applying the
document base and query/fragment rules. CommonJS module lookups retain extension
and directory resolution.
document base and query/fragment rules. As in a browser, the script URL and base
href are read without surrounding whitespace or embedded tabs and newlines, and
their percent-encoded path bytes are decoded; encoded dot and separator bytes
are still rejected. CommonJS module lookups retain extension and directory
resolution.
Unresolved HTML references retain their declaration, source range, and resolution
reason in the renderer observations.
HTML script source ranges follow the HTML parser across LF, CRLF, and bare CR
+34 -7
View File
@@ -7,19 +7,46 @@ never executes the selected or recovered application code.
## Caller-supplied engine
The initial adapter is verified on Linux x64 with Wakaru **1.13.0**. Set
`REA_WAKARU_COMMAND` to the absolute path of an executable supplied by the caller.
The adapter uses util-linux `prlimit` (default `/usr/bin/prlimit`; override with
an absolute `REA_JAVASCRIPT_PRLIMIT_COMMAND`). REA does not install either tool.
Engine configuration is checked only when recovery is requested; other REA
capabilities remain available without it.
REA accepts Wakaru **^1.13.0** on Linux x64. The report parser is verified with
Wakaru **1.14.0**. Another release in that range is accepted, the observed
version is reported, and a limitation records that the parser was not verified
against that release. Wakaru changes `--version`, `--json` and `provenance.json`
only by addition within a major version
([compatibility policy](https://github.com/pionxzh/wakaru/blob/v1.14.0/docs/cli.md#machine-readable-output-compatibility)),
so the parser keeps unknown report fields and reported module statuses.
Set `REA_WAKARU_COMMAND` to the absolute path of an executable supplied by the
caller. The adapter uses util-linux `prlimit` (default `/usr/bin/prlimit`;
override with an absolute `REA_JAVASCRIPT_PRLIMIT_COMMAND`). REA does not install
either tool. Engine configuration is checked only when recovery is requested;
other REA capabilities remain available without it.
Unmodified upstream source is retained in `third_party/wakaru`, pinned to
`6070266d24b32951fa2fe1d2dad5b4313bd5c81b` (v1.13.0, Apache-2.0).
`8219bf5016a063d7fb215101a8c45d5959ec733f` (v1.14.0, Apache-2.0).
The result reports the executed binary's exact path, SHA-256 and observed version.
The audited source revision is distinct from `executed_source_revision: null`:
a version string cannot prove which source produced a caller-supplied binary.
### Install Wakaru
Use the official release binary, the same one CI verifies:
```sh
curl -fL https://github.com/pionxzh/wakaru/releases/download/v1.14.0/wakaru-linux-x64.tar.gz | tar -xz wakaru
export REA_WAKARU_COMMAND="$PWD/wakaru"
```
Or install it from npm. Point at the platform binary, not the Node.js shim in
`node_modules/.bin`:
```sh
npm install wakaru@1.14.0
export REA_WAKARU_COMMAND="$(realpath node_modules/@wakaru/cli-linux-x64/wakaru)"
```
Both give the same binary (SHA-256
`664fa06782a61eda7ed15885134b52525fd565dd77607e642062ceb6cd927c38`).
## Recover and analyze
```sh
+36
View File
@@ -0,0 +1,36 @@
# JEB instrumentation and analysis
REA exposes JEB-backed project, unit, and decompilation inspection through the CLI and MCP, served by JEB's own MCP interface. JEB is a bring-your-own engine: REA never installs it, launches it, or opens its project databases itself.
## Bring-your-own engine
Start a JEB client that serves MCP and point REA at it:
- Default endpoint: `http://127.0.0.1:8425/mcp`. Override with `REA_JEB_MCP_URL` (absolute `http`/`https` URL with literal host `127.0.0.1` or `[::1]`; redirects, remote hosts, credentials, query strings, and fragments are rejected rather than silently dropped).
- In the JEB GUI client, start the MCP server from the _File_ menu (or via the VIBRE assistant).
- Headless, use JEB's documented programmatic route (`JebMcpServerInstance` from the JEB API) with the JEB client on your classpath; JEB 5.48's `-c` headless mode does not accept `--mcp` directly.
Verified against JEB 5.48.0 (Linux x64, licensed build) serving `jeb-mcp-server` 1.3.0 over streamable HTTP.
## Operations
| MCP tool / CLI command | Purpose |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `inspect_jeb_client` / `inspect-jeb-client` | Engine version, GUI or headless mode, startup time |
| `open_jeb_project` / `open-jeb-project` | Open or create a project from an artifact or `.jdb2` on the engine host; returns input-file SHA-256 digests and top-level units |
| `list_jeb_units` / `list-jeb-units` | Page units by stable path and type (`filter`, `parent-unit-path`, `index`, `count`) |
| `decompile_jeb_item` / `decompile-jeb-item` | Decompile one type or method to engine pseudo-code |
All four are read-only with respect to the target file; only `open_jeb_project` changes engine-side project state, and Evidence records the endpoint, the caller-selected parameters, and the engine-reported digests. Mutation workflows the engine also offers (renames, comments, `save_project`, `close_project`) are intentionally not exposed yet.
**Engine coverage note (verified):** JEB 5.48.0 headless MCP instances do not advertise `open_project` — the target must be selected when the engine client starts (`--infile` on the programmatic launcher, or the GUI's file opening). REA preserves that refusal with the engine's reason instead of failing silently; `open_jeb_project` completes only against engine builds that advertise the tool, such as GUI clients.
## Semantics
- Paths in `open_jeb_project` are resolved by the JEB process, not by REA; REA does not require the artifact to exist locally.
- The engine caps `list_units` pages at 100; a full page is reported as `coverage: "partial"` because more units may exist. An empty remainder is `complete` only when fewer units than requested were returned.
- When `decompile_jeb_item` omits `unit_path`, the engine implicitly selects the project's first code unit; REA reports `unit_path: null` and a limitation instead of guessing the effective unit.
- Engine refusals (`success: false` envelopes) are preserved as unsupported-target errors carrying the engine's own message, for example a nonexistent item address.
- An unreachable endpoint is a provider-availability failure with recovery guidance; REA does not retry or spawn the engine.
Real-engine verification lives in the JEB lane described in [testing.md](testing.md); mock transport tests do not establish real-engine compatibility.
+63 -227
View File
@@ -1,4 +1,4 @@
# Managed-code analysis and planned extensions
# Managed-code analysis
REA inspects .NET PE/CLI artifacts without loading or executing their code.
It can identify an assembly, inspect metadata and CIL, compare members across
@@ -20,12 +20,11 @@ The seven shipped tools are:
Each has a matching CLI command: replace underscores with hyphens and prefix
the name with `rea`, for example `rea inspect-managed-artifact`.
Native-body bridge mapping remains planned; managed runtime execution is not
part of the current tool set.
Native-body bridge mapping and managed runtime execution are outside the
current tool set.
This guide describes the implementation and verification of
[ADR-0003](adr/0003-managed-code-evidence-and-provider-boundary.md). The canonical
tool inventory is the [build-generated catalog](mcp-contracts.md#generated-catalog).
The canonical tool inventory is the
[build-generated catalog](mcp-contracts.md#generated-catalog).
## Shipped scope
@@ -36,10 +35,22 @@ NativeAOT identity from an ordinary native PE. Inputs without admitted CLI
metadata do not become managed assemblies through naming or routing guesses.
Inspect separately obtained components explicitly and preserve their identities.
The broader deployment classification and native-body mapping below are design
goals from ADR-0003, not claims that every row has an implemented parser. A
valid marker can establish a candidate native boundary, not recovered native
semantics or runtime behavior.
A valid implementation marker establishes a candidate native boundary, not
recovered native semantics or runtime behavior.
### Resource admission
The static provider admits regular input files up to 128 MiB before retaining
their bytes. Reads remain bounded if a file grows after admission. Metadata,
CIL decoding, and projected inspection records have a separate conservative
64 MiB representation budget; shared heap strings are cached, but repeated
output occurrences still consume that budget. These are inspection resource
policies, not PE format limits or a hard bound on total V8 heap use.
Input overflow returns a resource constraint. Decode or projection overflow
reports `resource-limit` with unavailable or partial coverage; omitted facts do
not become empty observations. Ambiguous PE section mappings are rejected
rather than interpreted according to section order.
## Analysis objective
@@ -57,40 +68,7 @@ collapsing them:
The ordinary workflow ends at question four. Static analysis never loads or
executes the target.
## Planned deployment classification
The intended extended classifier proceeds from outermost authenticated bytes inward:
```text
source path
-> canonical path, size, SHA-256
-> container inventory
-> PE/native header and architecture
-> CLI header and metadata root
-> deployment/runtime markers
-> per-component and per-method implementation availability
-> managed-only, native-only, composed, degraded, or unsupported route
```
The planned result is a vector rather than one label. For example, a single-file modern
.NET deployment can contain a native host, ordinary CIL assemblies, and
ReadyToRun components. Each component receives its own digest, classification,
coverage, and route while retaining the outer bundle commitment.
| Case | Required positive observations | Claims that remain unavailable or inferred |
| --------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| .NET Framework | Valid CLI metadata plus bounded Framework-specific target/reference evidence | Exact installed CLR and runtime behavior |
| Modern .NET | Valid CLI metadata plus bounded target/reference/runtime-config evidence | Exact runtime selected on another host |
| Unity Mono | Valid managed assembly plus authenticated Unity context when supplied | Engine behavior or native integration not represented by metadata |
| ReadyToRun | Valid managed metadata plus authenticated ReadyToRun header/sections | Native implementation semantics until a selected deep provider analyzes them |
| C++/CLI | Valid CLI metadata plus mixed-mode PE/header evidence | Mapping managed declarations to native implementations without explicit bridge evidence |
| Single-file | Valid authenticated bundle inventory and component extents | Components that are compressed or encoded by an unsupported bundle version |
| Unity IL2CPP | Authenticated native image/metadata pairing and supported metadata version | Canonical CIL and source-equivalent C# |
| NativeAOT | Native image plus bounded NativeAOT evidence | Ordinary CLI metadata/CIL unless independently present |
| Obfuscated assembly | Same positive byte observations as its underlying deployment form | Meaning inferred only from names |
| Malformed/unsupported | Exact admitted regions and failure locations | Completeness, successfully skipped rows, or semantics beyond the admitted parser boundary |
### NativeAOT metadata recovery
## NativeAOT metadata recovery
NativeAOT removes the ordinary CIL method bodies, so a CIL decompiler cannot
reconstruct those bodies as C# source. The executable remains a native target
@@ -110,28 +88,21 @@ lists supported OS/architecture targets and deployment limitations, while its
[native library guide](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/libraries)
describes exported shared-library entry points.
The [Ghidra NativeAOT analyzer](https://github.com/Washi1337/ghidra-nativeaot)
is a useful optional companion for recovering ReadyToRun metadata. It
rehydrates the `DEHYDRATED_DATA` section and annotates method tables, type
relationships, vtable slots, frozen objects, and strings. It does not recover
original C# method bodies. It is a separate Ghidra extension and interactive
metadata browser; REA does not currently install or invoke it through its
headless bridge. Its README describes ReadyToRun header discovery, including
symbol-based and heuristic paths, so a missed header or unsupported binary
should remain an explicit limitation rather than a failed claim about the
binary's contents.
REA supports an optional headless adapter for the Ghidra NativeAOT analyzer.
Supply a locally built `REA_GHIDRA_NATIVEAOT_JAR`; REA does not install the
extension or its toolchain. The verified boundary is .NET 8.0.22 RTR 9.1,
x86-64 ELF and native Windows PE targets analyzed on Linux x64 with Ghidra
12.1.4 and JDK 21. Other layouts, architectures, and hosts are unsupported.
See [NativeAOT recovery](ghidra-nativeaot.md) for build/configuration, recovered
metadata, derived-memory provenance, and the real verification lane.
The upstream analyzer currently gates its own analysis to x86-64. NativeAOT's
broader platform matrix does not establish REA coverage: PE/COFF, ELF, Mach-O,
shared libraries, target architectures, and runtime metadata versions each need
their own provider verification. REA's experimental Windows Ghidra boundary is
limited to admitted native x86 and x86-64 PE applications, so it does not currently
establish coverage for PE DLLs. Mobile NativeAOT targets should remain
experimental until REA has a matching provider and package-level verification.
REA's experimental Windows Ghidra boundary admits native x86 and x86-64 PE
applications and DLLs for static analysis. This does not establish Windows
NativeAOT metadata-recovery coverage.
For REA's native analysis, preserve the same artifact path and digest used by
`inspect_managed_artifact`, and report recovered type data as provider
observations. Linking those types to native function addresses requires verified
For NativeAOT analysis, preserve the selected native artifact's path and digest
and report recovered type data as provider observations. Linking those types
to native function addresses requires verified
provider evidence; names or vtable similarity alone do not prove that a native
function implements a specific managed method.
@@ -143,43 +114,18 @@ matches the normalized artifact SHA-256. A valid Evidence ID alone does not
establish that those two identities agree. Evidence without a subject remains
usable, with no subject digest available to cross-check.
Every planned operation returns a provider result and Evidence with four
commitment groups:
Artifact inspection returns the selected path, byte length and SHA-256, observed
PE/CLI classification, assembly and module identities, and metadata coverage.
Member inspection binds build-local tokens, signatures, row offsets, method
bodies, and decoded relationships to that artifact and MVID. Missing or malformed
facts remain explicit in coverage and per-member status.
### Artifact commitment
CLI `#GUID` heap values retain their exact 16-byte GUID text. REA does not impose
RFC 4122 UUID version or variant bits on MVID, EncId, or EncBaseId because
ECMA-335 metadata does not require those bit patterns. Tokens and RVAs are
build-local coordinates, not durable cross-build identities or native addresses.
- canonical local path, byte length, and SHA-256;
- outer-container identity and digest when inspecting a component;
- component name/path, byte extent, and SHA-256;
- observed PE machine, CLI flags, and conflicts;
- classification vector, supporting observations, and unresolved dimensions.
### Module commitment
- assembly simple name, version, culture, public-key/token state, flags, and
hash algorithm;
- module name, generation, and MVID;
- target framework and runtime/version strings with their exact metadata
locations;
- provider identity, analysis-affecting parameters, and their profile digest.
CLI `#GUID` heap values are committed as their exact 16-byte GUID text. REA
does not impose RFC 4122 UUID version or variant bits on MVID, EncId, or
EncBaseId because ECMA-335 metadata does not require those bit patterns.
### Entity commitment
- table kind and build-local token;
- declaring scope and normalized CLI signature;
- row/heap/body locations expressed as typed file offsets, RVAs, or CIL
offsets;
- exact raw bytes or bounded value digest;
- raw CIL digest plus separately reported method-header, locals-token, and
exception-region observations where available;
- a deterministic decoded-instruction-tuple digest for completely decoded
CIL, with the limitations below.
### Shipped decoded-CIL fingerprint
## Decoded-CIL fingerprint
`inspect_managed_members` exposes two method CIL hashes with different byte
boundaries:
@@ -208,9 +154,7 @@ reproducible decoded-tuple fingerprint, not a canonical semantic CIL identity:
it does not resolve tokens across MVIDs, does not commit full control flow or
exception semantics, and does not replace the raw CIL digest. Cross-build
comparison uses the value only as one unique-only structural tier and reports
ambiguity when that evidence is insufficient. A future normalized-CIL
commitment would need canonical token/literal identities,
complete branch and switch targets, and explicit locals/exception semantics.
ambiguity when that evidence is insufficient.
For example, a decoded `nop; ret` body serializes exactly as
`[["nop","none",null],["ret","none",null]]` and has digest
@@ -218,73 +162,10 @@ For example, a decoded `nop; ret` body serializes exactly as
This vector specifies the tuple order, `null` handling, absence of whitespace,
UTF-8 encoding, and lowercase hexadecimal output.
### Epistemic commitment
## Member comparison
- authority: static bytes, reconstruction, structural inference, independent
validation, native provider, or future runtime observation;
- state: observed, inferred, unknown, or unavailable;
- confidence independent of authority;
- coverage and admitted/dropped counts;
- exact supporting Evidence IDs and actionable limitations.
A semantic label such as `score_submission_gate` can annotate an entity, but it
is never the entity's identity. The same applies to an obfuscated name, token,
RVA, or decompiler-generated local name.
## Planned static capabilities
The caller-visible grouping and exact tool names are decided with the contracts
that implement them. The underlying capability slices are:
1. **Triage and inventory**: container/component classification, assembly and
module identity, references, files, exported types, resources, attributes,
and runtime markers.
2. **Member inventory**: file-backed types, methods, fields, properties, events,
interfaces, nesting, generics, and normalized signatures.
3. **Method inspection**: headers, max stack, locals, CIL instructions,
constants, metadata operands, exception regions, and implementation flags.
4. **Relationships**: declared overrides, interface implementations, member
references, direct CIL callers/callees, field access, construction, and
interop declarations. Dynamic dispatch remains qualified.
5. **Structural search and comparison**: signature/API/constant/flow anchors,
exact and normalized hashes, competing candidates, and explicit
exact/structural/missing/ambiguous states.
6. **Managed/native composition**: P/Invoke, unmanaged exports, COM/mixed-mode
declarations, ReadyToRun/native bodies, single-file hosts, and authenticated
IL2CPP pairs linked to selected Hopper/Ghidra evidence. The shipped
verification workflow checks P/Invoke declarations against supplied native
export or function Evidence; native-body, thunk, and token-to-address bridge
mapping remain unavailable without explicit provider-supported evidence.
7. **Application graph projection**: managed assembly/module/type/method/field,
P/Invoke, and native-implementation declarations enter the same
Evidence-backed application graph vocabulary as JavaScript/Electron
findings while preserving managed static-analysis authority.
Inventory lists preserve deterministic order and include every fact available
from the admitted PE/CLI streams. Malformed ranges and unsupported metadata are
reported as coverage issues instead of being silently omitted. Search exposes
scanned, matched, returned, and dropped counts. An unresolved indirect call or
a failed signature decode is not silently omitted from a completeness claim.
## Obfuscation-resistant method slices
Names are one weak feature among many. A behavior slice records the smallest
bounded set of observations needed to investigate a proposition:
- normalized declaring/member signatures and inheritance/interface shape;
- framework and application API references;
- exact strings, numeric constants, enum-like values, and serialization keys;
- branch, switch, exception, loop, call, and field-flow shape;
- construction and generic-instantiation sites;
- raw CIL and decoded-tuple commitments, plus separate header, locals, and
exception observations;
- callers, callees, shared fields, and competing candidates; and
- limitations from reflection, dynamic dispatch, generated code, protection,
native transitions, or incomplete coverage.
The workflow produces separate observation, inference, validation, and unknown
tables. It may say that a method is a strong candidate for a role; it cannot
turn that role into the method's durable identity.
Names and semantic labels do not establish durable member identity. Comparison
preserves observed differences, structural inferences, and unknowns separately.
Cross-version matching first prefers exact CIL/signature identity. When that
does not match, it pairs an exact declared type, method name, and raw signature
@@ -310,16 +191,14 @@ Tokens are always remapped through observed structure. A caller cannot carry
## Managed/native boundary rules
| Boundary | Managed observation | Native observation | Permitted link |
| ----------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| P/Invoke | Module, entry point, charset/calling-convention flags, declaring method | Import/export/symbol/function evidence from the selected deep provider | Exact declared-name/module link or qualified resolution inference |
| COM | Interop attributes, GUIDs, imported interfaces, method signatures | Native registration/vtable evidence when independently available | Identifier/signature inference with explicit environment limitations |
| C++/CLI | Managed declaration and implementation flags | Native body/function evidence | Only a provider-supported bridge observation; never token-as-address |
| ReadyToRun | Component/header and per-method CIL/native availability | Native section/function evidence | Authenticated image mapping with format/profile version |
| Unmanaged export | Export metadata/attribute when present | PE export and native thunk/function | Exact export identity plus provider-qualified address |
| Single-file host | Bundle entry/component identity | Host and native component evidence | Outer bundle plus component digest/extent commitment |
| Unity IL2CPP | Supported metadata entity with authenticated pairing | Generated native function/type evidence | Versioned IL2CPP mapping only; no invented CIL |
| Runtime-resolved native | API/constant/data-flow candidate | Loaded-module/symbol observation from an independently collected runtime source | Static candidate remains inference until separately observed |
`verify_managed_native_boundaries` compares declared P/Invoke module and entry
point identities with supplied native export or function evidence. Name/module
matches establish declaration links; they do not establish that a call executed.
Metadata tokens are not native addresses. Native body mapping for C++/CLI,
ReadyToRun, NativeAOT, and IL2CPP requires separately verified format and provider
support. The managed static tools do not recover those mappings. The optional
[Ghidra NativeAOT extension](ghidra-nativeaot.md) has its own supported boundary.
Declared import inventory supports a bounded positive claim. Its absence does
not exclude dynamic resolution, generated code, protected code, native helpers,
@@ -333,16 +212,12 @@ fixtures and expected semantic facts. An optional real ILSpy lane runs only when
its executable is explicitly supplied; the default lane does not establish
independent pinned-oracle parity. Production inspection needs none of those tools.
- A pinned `System.Reflection.Metadata` differential oracle is planned; it is
not part of the current verifier.
- `ICSharpCode.Decompiler`/`ilspycmd` can supply reconstruction inference.
A BYO reconstruction import records the supplied version
and remains non-canonical. When `REA_ILSPY_CMD_PATH` points to an absolute
runnable `ilspycmd`, `verify:managed` runs a source-owned real ILSpy oracle
and imports its C# output as reconstruction inference against exact static
member Evidence.
- dnlib and Mono.Cecil are potential future differential oracles. Their mutation APIs
are not exposed or included in the production parsing boundary.
- The package contains no .NET runtime, SDK, ILSpy installation, proprietary
assembly, or compiled conformance fixture.
- Setup never installs or upgrades those tools. Doctor may inspect an explicit
@@ -360,29 +235,15 @@ they do not claim that the REA application itself supports Windows. Native
ReadyToRun, C++/CLI, NativeAOT, or IL2CPP coverage is additionally constrained
by the selected Hopper/Ghidra host and format matrix.
## Source-built conformance corpus
## Conformance verification
The current lane uses source-owned byte-built fixtures and malformed-input
regressions, with optional operator-supplied applications and ILSpy verification.
The table below describes the desired expanded corpus; it is not a report that
all compiler-generated forms have been independently verified.
Fixture sources are intentionally small and behavior-focused. Build outputs
are generated outside tracked fixture directories and must not remain after
verification or packaging.
| Corpus slice | Required properties |
| ---------------------- | ------------------------------------------------------------------------------------------ |
| Identity | Assembly/module/version/culture/public key, references, attributes, resources, MVID |
| Signatures | Nested/generic types, arrays, pointers, by-ref, function pointers where supported, varargs |
| CIL | Short/long branches, switch, prefixes, constants, locals, calls, fields, boxing, tokens |
| Exceptions | Catch, finally, fault/filter where the compiler/toolchain supports them |
| Generated structure | Async and iterator state machines, lambdas, closures, properties, events |
| Interop | P/Invoke flags, module/name mapping, managed/unmanaged implementation metadata |
| Architecture | AnyCPU, preferred-32-bit where applicable, x86, x64 |
| Obfuscation resistance | Unicode/meaningless/duplicate-looking names and structure-preserving renames |
| Cross-build comparison | At least two builds with changed MVID/token order/layout and known same/changed behaviors |
| Malformed/adversarial | Truncated/overflowing headers, streams, tables, heaps, signatures, bodies, and EH sections |
Run the deterministic lane with `npm run verify:managed`. See
[testing](testing.md#real-toolchain-verification-lanes) for prerequisites and
coverage. Generated outputs belong outside tracked fixture directories and must
not remain after verification or packaging.
Verification compares semantic facts, not decompiler text. It checks resource
ceilings, deterministic ordering, complete cleanup, CLI/MCP parity, Evidence
@@ -492,32 +353,7 @@ evidence is collected. A direct process capture can retain declared inputs,
outputs, filesystem and protocol activity for a target run; it does not prove
which managed methods executed or how the CLR resolved them.
## Delivery sequence
The managed-code track advances as reviewable pull requests:
1. accepted evidence/provider boundary (this document and ADR);
2. read-only artifact triage and exact identity (shipped);
3. file-backed metadata, signatures, method bodies, raw CIL hashes, and the
decoded-instruction-tuple fingerprint (shipped; complete normalized-CIL
semantics remain planned);
4. obfuscation-resistant slices and cross-version comparison (shipped for
static member observations);
5. decompiler reconstruction import (shipped as analyst inference; REA does
not run ILSpy/dnSpy, and metadata/CIL remain canonical);
6. managed/native composition and truthful deployment degradation (declaration
inventory and native export/function Evidence matching shipped; native-body
bridge mapping remains planned);
7. source-built managed conformance and package/CLI verification (source-owned
PE/CLI corpus shipped through `npm run verify:managed`; optional BYO
`ilspycmd` real-tool oracle shipped through `REA_ILSPY_CMD_PATH`; dnSpy and
pinned Windows checks remain planned); and
8. managed static Evidence projection into the application graph (shipped).
Each implementation PR updates generated product facts only for behavior it
actually ships and states which real-tool checks were performed.
### Method metadata during build comparison
## Method metadata during build comparison
Managed member comparisons report a `metadata` dimension when an observed
MethodDef flags or implementation flags value differs, including accessibility
+217 -36
View File
@@ -2,7 +2,7 @@
## Generated catalog
Run `npm run build:cached` in a source checkout to generate the machine-readable
Run `npm run docs:generate` in a source checkout to generate the machine-readable
catalog at `docs/public/product-catalog.json`. Documentation deployments serve
the same file at [/rea/product-catalog.json](/rea/product-catalog.json). PR CI retains it with the packaged
skill and portable conformance projections in the `generated-docs` artifact.
@@ -24,22 +24,92 @@ health transition leaves that catalog unchanged and does not emit
`notifications/tools/list_changed`.
Advertised input and output schemas contain no reachable recursive references.
The input compatibility profile limits nesting to ten object, array, and
`anyOf`/`oneOf`/`allOf` levels, following local references per path. Property
maps, reference definitions, and example data do not add schema levels. Tests
check the complete catalog after SDK conversion and its generated counterpart.
This is REA's local compatibility profile; individual model APIs can impose
additional limits.
Schemas share repeated definitions through schema-local references while
preserving complete nested fields and validation rules. Input properties retain
their descriptions and literal examples.
For passive `compare_web_captures` inputs, pass each complete
`inspect_web_page` result in `before.inspection` or `after.inspection`, with an
optional complete `discover_webmcp_tools` result in the matching `webmcp` field.
The input schema describes these producer-result objects as round-trip payloads.
For scenario comparisons, pass complete `capture_browser_scenario` results in
`before_scenario` and `after_scenario`. REA validates all nested fields with the
original capture schemas; observation output schemas remain complete. Scenario
authoring inputs and comparison normalization options retain their full
advertised structure.
Hosts forward input schemas to the model with every request, so advertised
examples never copy complete producer Evidence. An embedded Evidence record is
shown as its exact `{"kind":"retained-evidence","evidence_id":"ev_..."}`
reference where the tool accepts one. An example that can only carry inline
Evidence stays in the canonical contract and its executable tests, but is not
advertised. Every advertised example is a distinct valid canonical input.
Root object unions are presented as
one object without root `anyOf`, `oneOf`, or `allOf` for model API compatibility.
The projection merges properties, retains shared required fields and
group-specific field dependencies, and describes the accepted input groups.
Canonical runtime validation enforces the exact union, including exclusions
that the advertised projection does not express. Tests validate the schemas
after SDK conversion and check advertised validation and actual calls.
Individual model APIs can impose additional nesting limits; complete producer
captures can exceed ten structural levels.
### Compact input schema profile
Some function-calling providers reject a request while any single tool's
`parameters` schema exceeds a literal serialized size cap; Moonshot clients
such as kimi-cli fail every request while the default catalog is attached
([#1484](https://github.com/morluto/rea/issues/1484)). Setting the server's
`REA_MCP_INPUT_SCHEMA_PROFILE` environment variable to `compact` renders every
advertised input schema within a 13,312-byte budget, measured to sit below
Moonshot's observed cap (community measurements: a 13.7 KB schema is accepted
while a ~15 KB one is rejected). The setting is read at startup; restart the
server to apply changes, as with `REA_MCP_MAX_RESPONSE_BYTES`. The default
value `full` keeps the complete advertisement unchanged.
The compact profile renders the same tool set, output schemas, annotations,
and canonical server-side validation. It changes only the advertised input
JSON Schema:
- Annotation prose leaves the advertised form: nested property descriptions,
literal examples, defaults, and titles are dropped. The root keeps its
description because it states the accepted input groups.
- Schema-local references are inlined within the budget. Kimi Code expands
references before sending provider requests, so sharing definitions cannot
establish the provider-facing size. Expansion stops at the budget before
allocating an oversized presentation. Unconstrained JSON fields advertise
all JSON value types explicitly so Kimi cannot infer string for Evidence
objects or arrays.
- The few schemas whose validation structure alone exceeds the budget
(`compare_web_captures`, `build_reconstruction_obligation_ledger`,
`evaluate_reconstruction_coverage`, `project_managed_application_graph`,
`compare_application_versions`, `capture_browser_scenario`) are advertised
in a reduced form: property names, reference-resolved types (including union
alternatives), first-level guidance, and the root's required-field constraints,
with nested validation detail elided. The
canonical schema still rejects malformed calls server-side, so callers
following the reduced advertisement receive the canonical typed error
instead of silent acceptance.
Boundary tests pin every advertised compact schema to the budget, keep them
valid JSON Schema that still accepts every canonical example, and hold the
set of six reduced presentations as contracts evolve. Client verification
also checks provider-facing sizes and canonical examples after conversion by
the actual Kimi Code CLI; local captures do not establish Moonshot acceptance.
Self-contained output schemas advertise a content-bound `$id`, including their
declared dialect. SDK validators can reuse compiled schemas across complete
catalog refreshes and equivalent tool outputs; changing the schema changes its
identity. Explicit schema IDs and relative external reference bases are
preserved. This keeps every tool and validation rule in discovery and does not
change the SDK's catalog invalidation or availability checks.
`compare_web_captures` accepts exactly one of two input shapes:
- Passive: `before` and `after` each contain `inspection`, the complete
`normalized_result` from `inspect_web_page`. Each may also contain `webmcp`,
the complete `normalized_result` from `discover_webmcp_tools`, or null.
- Scenario: `before_scenario` and `after_scenario` contain complete
`normalized_result` objects from `capture_browser_scenario`. Optional
`normalization` defaults to `{ "rules": [] }`.
The advertised schema includes complete nested capture fields and rejects
incomplete pairs and structurally malformed captures. Mixed comparison families
can pass advertised validation; the SDK rejects them against the canonical
input schema before invoking the handler. Domain validation additionally checks
relationships such as event sequence references and retained counts; JSON
Schema does not express those cross-field invariants.
Call `binary_session` with `{}` and read `result.tool_availability` to choose a
callable operation for the current target, provider, host, and negotiated client
@@ -71,9 +141,24 @@ inventories, and do not claim that no short-lived descendant existed.
## Progress and cancellation
Tool execution failures return `isError: true` and the complete canonical
`{ "error": ... }` diagnostic as JSON in text `content`. Read that diagnostic
for the error code, target details, partial observations, and remediation.
Failures omit `structuredContent`, since each advertised `outputSchema`
describes successful results. Successful replies retain their schema-validated
structured data and matching text projection. Oversized errors are retained
as Evidence before delivery of a bounded diagnostic with an export reference;
if retention is unavailable or fails, the diagnostic reports that reason.
REA accepts ordinary `tools/call` progress tokens. Updates are monotonic,
rate-bounded to at most one intermediate update per 100 ms, and always allow a
terminal update. Unknown totals are omitted; REA does not fabricate percentages.
`capture_process_scenario` uses that boundary only when the client supplies a
progress token. Notifications set `progress` to the count of collected terminal
frames, process samples, and interaction events, omit `total`, and put the
lifecycle phase, elapsed time, and final cleanup status in `message`. A client
that does not send a progress token receives no progress notifications. The
tool result is unchanged either way.
Provider calls receive the request cancellation signal. Artifact traversal,
hashing, version comparisons, Hopper requests, and process capture
check the same signal. Cancellation is distinct from timeout. A cleanup failure
@@ -82,6 +167,9 @@ Native call tracing and process capture retain available observations in
`details.partial_observation` on failure, including when cleanup succeeds.
The observation reports its partial coverage; cleanup details describe host
state separately from the execution failure.
A process capture that fails during a finalization interval keeps every signal
attempt and its delivery result in `details.partial_observation`, with
`elapsed_ms` and `exit_code` null when no exit was observed.
Derived comparisons and reconstruction verification yield before computation
and before publication, so cancellation cannot race with successful Evidence.
@@ -97,9 +185,11 @@ still run synchronously, so control messages can wait for those
phases to release the event loop. A rejected client promise alone does not
establish that the server has stopped its work.
CLI calls work without a progress token and translate SIGINT into the same
AbortSignal used by providers. Existing controlled-process cleanup and provider
shutdown rules still apply; REA never kills a process it cannot prove it owns.
Direct CLI analysis calls work without a progress token and translate SIGINT or
SIGTERM into the same AbortSignal used by providers. Signal guards remain active
through provider cleanup, including repeated delivery by package runners.
Existing controlled-process cleanup and provider shutdown rules still apply;
REA never kills a process it cannot prove it owns.
## Ghidra first-query deadlines and recovery
@@ -111,11 +201,11 @@ auto-analysis, bridge connection, and health readiness before returning analysis
These deadlines have different owners:
| Deadline | Owner and effect |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MCP initialize | The client bounds transport/REA connection startup, before any target query. |
| Ghidra startup | REA allows 330,000 ms by default; `REA_GHIDRA_STARTUP_TIMEOUT_MS` accepts 1–2,147,483,647 ms. Invalid values keep the default. Startup failure is reported by the first provider query. |
| Individual tool call | The client bounds its wait, including cold engine startup. The pinned client SDK 2.3.1 defaults to 60,000 ms and can cancel earlier than REA's startup deadline. |
| Deadline | Owner and effect |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MCP initialize | The client bounds transport/REA connection startup, before any target query. |
| Ghidra startup | REA allows 330,000 ms by default; `REA_GHIDRA_STARTUP_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid supplied values fail configuration validation. Startup failure is reported by the first provider query. |
| Individual tool call | The client bounds its wait, including cold engine startup. The pinned client SDK 2.3.1 defaults to 60,000 ms and can cancel earlier than REA's startup deadline. |
For an already connected client using the pinned SDK, request options are the
**second** argument of `callTool`:
@@ -164,33 +254,79 @@ the current client, so it is not a fresh-start recovery. On the same connection:
This close/reopen flow was exercised on one real Linux stdio connection after a
controlled startup timeout, followed by a successful overview and function
analysis. It is not a Windows/macOS coverage claim. REA cleans only resources it
owns and never switches to another provider automatically. A provider timeout,
installation failure, or host permission denial needs its own reported recovery;
increasing a client deadline alone does not fix those failures.
analysis. A separate Windows x64 stdio run with Ghidra 12.1.4, JDK 21 and Node
22.19.0 exercised the same connection and caller-selected native PE: the default
60-second client request timed out, close succeeded, and reopening before a
240-second request completed the cold overview in about 163 seconds. The next
overview took about 19 ms. The cold and warm overviews reported two procedures
and two segments; the input digest was unchanged and no owned runtime root or
observed process-family member remained after final close. This was a small
1,024-byte fixture, so the longer request setting remains an example, not a
guarantee for larger targets. No macOS cold-start recovery was exercised.
With a supplied progress token, the Windows run received an operation-start
notification before timeout and start/completion notifications for the
successful retry. It received no intermediate import or auto-analysis progress.
These operation markers do not measure analysis work completed or extend the
client's deadline. Each new provider session still imports the target into a
fresh temporary project.
REA cleans only resources it owns and never switches to another provider
automatically. A provider timeout, installation failure, or host permission
denial needs its own reported recovery; increasing a client deadline alone does
not fix those failures.
## Tool results
Evidence-producing tools return `{ result, evidence_id, evidence }` in both
text and structured content. `evidence` is the complete canonical Evidence
record, including `normalized_result`, which equals `result`. The same record
is retained in the session bundle. Read `result` directly, or pass `evidence`
to a compatible comparison tool: `analyze_function` Evidence can be passed
Custom clients upgrading from 6.1 should follow the
[6.2 migration guide](migration-6.2.md#mcp-results-and-evidence).
Evidence-producing tools return the complete canonical Evidence record in both
text and structured content. Read `structuredContent.normalized_result` for the
operation result and `structuredContent.evidence_id` for its identity.
`raw_result` holds a provider representation distinct from that result, such
as an upstream tool's original report, and is `null` when there is none. The same
record is retained in the session bundle. `analysis_profile` is always present:
a concrete profile object or `null`; either value participates in semantic
identity. Records omitting this field are rejected. Pass the returned Evidence
directly to a compatible comparison tool: `analyze_function` Evidence can be passed
directly to `compare_functions`, and `inspect_artifact` Evidence to
`compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
retained session history or an explicit bundle for transfer.
REA prepares complete MCP results within the pinned stdio client's 10 MiB
receive-buffer budget, including both text and structured representations and
room for the JSON-RPC envelope. If a result cannot fit, REA returns
room for the JSON-RPC envelope. Tool errors carry only their text
representation, so only that text counts against the budget. Response budget settings are captured at startup;
restart or recreate the server to apply changes. If a result cannot fit, REA returns
`resource_constraint` with `details.resource: "transport"` before constructing
a document-sized string. Analysis Evidence remains complete in the current
session. Its exact reference is reported in
`details.reported_limits.evidence_reference`; use it with a focused application
workflow, or call `export_evidence_bundle` with a destination path. Complete
`details.reported_limits.evidence_reference`; call `inspect_analysis_view` with
that reference for a summary, one section/module, or a stable page, or call
`export_evidence_bundle` with a destination path. Complete
bundle exports stream canonical JSON into an atomically published file. A broad
follow-up or `get_evidence_bundle` can also exceed the response budget; exporting
preserves the complete session without sending it through a single MCP frame.
To discover existing records without their large payloads, call
`get_evidence_bundle` with `detail: "summary"`. Its `result.records` contain
Evidence IDs, artifact/provider identities, analysis-profile digests and native
procedure metadata. Optional `filters` match exact `evidence_id`, `operation`,
`target_sha256`, `analysis_profile_digest` or `procedure_address`. Use a discovered
ID with `inspect_analysis_view`; neither discovery nor retained selection starts
a provider. `retention: "complete-record"` describes stored Evidence, while
`native_dossier.value_flow` independently reports truncation, unavailable or
unknown metadata. Missing omission counts remain null. Summary output carries
every matching record; actual transport admission still applies. Omitted
`detail` preserves complete canonical bundle delivery; filters require summary.
For a portable exported bundle, the CLI shares this projection:
`rea inspect-evidence-bundle '{"path":"/tmp/evidence.json","detail":"summary","filters":{"operation":"analyze_function"}}' --format json`.
The CLI validates and materializes that local bundle under its existing memory
budget; summary delivery does not make arbitrary large files cheap to import.
Cancelling an export stops further serialization and removes its staging file.
The destination changes only when a complete export is atomically published.
Clients that explicitly configure a larger receive buffer can set the REA
server's `REA_MCP_MAX_RESPONSE_BYTES` environment variable to the same byte
@@ -202,6 +338,33 @@ Ordinary responses keep their existing complete result contract.
## Retained application Evidence inputs
`analyze_javascript_application` and `inspect_binary_layout` accept `detail`:
`complete` (default) returns the complete analysis Evidence; `summary` records
that complete Evidence in the session and returns the derived
`inspect_analysis_view` summary Evidence instead. Its
`normalized_result.parent_evidence_id` and `evidence_links` name the retained
analysis, so later views and application workflows read it without repeating
analysis or moving the complete record through the response. A server without
session retention refuses summary detail with `capability_unavailable`.
`inspect_analysis_view` projects a caller-selected view of already completed
`inspect_binary_layout`, `analyze_javascript_application`, or `analyze_function`
Evidence. Native views select procedure, pseudocode, assembly, basic blocks,
comments, callers/callees, references, unresolved calls, referenced strings and
names, the native API record, and high-pcode facets without starting a provider. Native offset
and limit default to 0 and 64; pseudocode uses UTF-16 code units and never
splits surrogate pairs, while other pages count rows. Unavailable facts and
provider limitations remain explicit. Source is
an exact same-session retained reference or portable inline Evidence. Views are
a summary, a layout mitigations or linkage facet, one section/symbol/module, or
a stable page with a caller-selected positive `limit`. Module pages include
JavaScript assets, bundled modules, and source modules. Select an exact
`node_id` when a path is ambiguous or unavailable. Module items retain their
recorded property values and source locations; summaries include parent
application and semantic coverage. The result carries a digest of the selected
facts. Actual serialized size determines MCP transport admission: reduce the
page size or export retained Evidence if the view is too large.
`trace_application_feature`, `trace_javascript_semantics`,
`compare_application_versions`, `compare_source_to_bundle`, and
`compare_javascript_export_shapes` accept complete inline application Evidence
@@ -300,3 +463,21 @@ Contradictory bytes are quarantined from nested expansion and recorded with
declared and observed hashes, trust, provenance, path, and unpacked state.
Verified siblings continue. Comparisons classify the result as a contradiction
and reconstruction cannot treat it as unchanged.
`analyze_javascript_application` accepts the same policy in MCP and as
`--integrity-policy` on both JavaScript CLI routes. Its result returns the
canonical `integrity_contradictions` records and marks application graph
coverage partial when any mismatch is continued. Contradicted nested ASARs
remain opaque.
`extract_artifact` accepts the same policy in MCP and as `--integrity-policy`
on `rea extract-artifact`. With `record-and-continue` it writes the observed
bytes and returns the `integrity_contradictions` records for the extracted
files. An active ASAR unpacked entry whose companion file is absent cannot be
materialized; extraction fails as `unavailable` with that logical path.
Packaging tools commonly sign or strip `.asar.unpacked` native binaries after
writing the archive header, so their declared hashes no longer match. Electron
does not check unpacked companions against those hashes at runtime. Integrity
failures for such entries name this cause and the operation to rerun with
`record-and-continue`; REA does not exempt unpacked entries silently.
+3 -1
View File
@@ -27,7 +27,9 @@ prompt argument or tool explicitly accepts one.
For a JavaScript/Electron application directory, `investigate_feature` points
directly to `analyze_javascript_application` with `input_path`; it does not
require `open_binary`. The CLI equivalent is `rea analyze <directory>`.
require `open_binary`. When that Evidence, or `inspect_binary_layout` Evidence,
is already retained, it suggests `inspect_analysis_view` before tracing a
feature seed. The CLI equivalent is `rea analyze <directory>`.
`open_binary` and the doctor target check admit files and macOS app bundles.
A directory outside that opening route is reported with an available analysis
action; this does not establish support for every directory format.
+157
View File
@@ -0,0 +1,157 @@
# Upgrading from REA 6.1 to 6.2
REA 6.2 includes stability fixes and changes to public result and saved-data
contracts. The repository uses `always-bump-minor`, including breaking releases;
the minor version increment does not imply backward compatibility. Refresh cached
MCP tool definitions after upgrading and adapt custom consumers using this guide.
## MCP results and Evidence
Evidence-producing tools now return the complete Evidence record directly in
`structuredContent` and JSON text. The old `{ result, evidence_id, evidence }`
wrapper is gone.
For a successful Evidence-producing call, change:
```javascript
// 6.1
const value = reply.structuredContent.result;
const evidence = reply.structuredContent.evidence;
// 6.2
const evidence = reply.structuredContent;
const value = evidence.normalized_result;
const evidenceId = evidence.evidence_id;
```
Check `isError` before reading success fields. Error results have `isError: true`
and carry their typed JSON diagnostic in a text content block; they omit
`structuredContent` so they cannot violate the advertised success output schema.
```javascript
if (reply.isError === true) {
const text = reply.content.find((part) => part.type === "text");
if (text === undefined) throw new Error("REA error has no text diagnostic");
const { error: diagnostic } = JSON.parse(text.text);
// Handle diagnostic.code, diagnostic.message and diagnostic.details.
}
```
Lifecycle and other non-Evidence tools still use their own advertised output
contracts. Do not assume every successful tool returns Evidence. Consult
[`tools/list` and the result guide](mcp-contracts.md#tool-results).
A transport `resource_constraint` error can include a retained
`details.reported_limits.evidence_reference`. Use `inspect_analysis_view` or
`export_evidence_bundle` on the same connection to consume the complete retained
Evidence. Response-budget settings are captured when the server starts; recreate
the server to change them, and keep the client's receive budget aligned. Raising
the server budget does not change the client's limit or analysis coverage.
Every Evidence record now requires `analysis_profile`, either its observed
profile object or `null`. The field participates in Evidence identity. Records
that omitted it cannot be migrated by inserting `null` while retaining the old
`evidence_id`. Keep the original files and regenerate affected observations with
6.2; use the new returned identities when linking or comparing them. Existing
records that already satisfy the complete canonical contract remain usable.
The `binary_session` result removes the redundant top-level `provider` and
`providers` aliases. Read `analysis_provider_binding`,
`analysis_provider_candidates` and per-operation `capabilities` for selection
and availability. Select a deep provider through `open_binary.provider_id`
or CLI `--provider`, using the advertised values.
These changes establish one complete result representation and explicit
provider/profile ownership rather than accepting incomplete producer records.
See [63bf914](https://github.com/morluto/rea/commit/63bf91405cf97b114a84f337fb1272d98a267999)
and [#1277](https://github.com/morluto/rea/pull/1277).
## Saved snapshots and artifact inventories
Analysis snapshots require `workflow_entries` and a corresponding profile-bound
Evidence record for every cached query. Import rejects incomplete bindings
instead of silently discarding them. Preserve an incompatible snapshot and
choose a new output path when rerunning analysis, for example:
```bash
rea analyze /absolute/path/to/program --provider ghidra --snapshot /absolute/path/to/analysis/program-6.2.json
```
In MCP, open the target without the incompatible `snapshot_path`, run the
required queries, then save to a new path through `close_binary.snapshot_path`.
Do not fabricate missing provider profiles or query bindings. See
[snapshot usage](cli.md#save-and-reuse-analysis-snapshots).
Artifact inventory nodes identify content bytes. Path-specific role and
permissions now belong to each occurrence:
| Previously read | Read in 6.2 |
| -------------------------------- | ----------------------------------------- |
| `nodes[].kind` | `occurrences[].artifact_kind` |
| Path-specific `nodes[].format` | `occurrences[].artifact_format` |
| `nodes[].executable` | `occurrences[].executable` |
| Content identity and byte format | `nodes[].artifact_id`, `sha256`, `format` |
Join an occurrence to its content node using `artifact_id`; inspect the selected
occurrence's role rather than choosing one role for all paths with equal bytes.
An executable binary format can have `artifact_kind: "executable"` while its
current filesystem permission produces `executable: false`. A `.js` and `.txt`
file with identical bytes can share a node and retain different roles.
Regenerate old inventories: a merged content node alone cannot recover the
per-path facts that were lost. These changes are part of
[63bf914](https://github.com/morluto/rea/commit/63bf91405cf97b114a84f337fb1272d98a267999).
## Process captures and cleanup failures
REA no longer converts legacy v3 process captures on import. Captures require
explicit selected/launch executable identity and `event_journal`; missing data
is rejected instead of being filled during parsing. Preserve old captures for
historical reference and recapture with 6.2 when current comparisons are needed.
Do not infer the original launched binary from a later file digest, or invent
event ordering from independently recorded collections. An explicitly empty
journal is valid under its advertised contract; the field cannot be omitted.
See [2a77469](https://github.com/morluto/rea/commit/2a7746998d47446c4db6d4f524e0f183d6803f3f).
Filesystem effects can now report `status: "unknown"` with a reason when a
partial snapshot cannot establish creation or deletion. Update exhaustive
status readers and retain observed facts separately from absence assumptions.
A completed one-shot analysis can report `cleanup_incomplete` rather than
silently returning success when provider cleanup fails. Preserve its
`details.partial_observation` or primary execution diagnostics, inspect the
reported owned resources, and address cleanup before retrying. A successful
analysis observation does not prove successful cleanup. This behavior is covered
by [#1211](https://github.com/morluto/rea/pull/1211). That change also makes
configured agent-evaluation fixture checks grade cited Evidence; routing or
answer wording alone no longer passes an assessed fixture.
## JavaScript and function comparisons
JavaScript return-field projections require `presence` with `present`, `absent`
or `unknown-coverage`. Export-shape change rows retain both sides' presence,
and `property_inventories` report examined properties and coverage. Unknown
values and unknown presence are distinct; callers must not treat an unknown
value as a missing property. Semantic object-operation graph observations use
`properties.property_path`, an array of complete path segments or `null`,
rather than a flattened property name. Regenerate old application analysis
before depending on nested mutation or presence facts. See
[475a0f8](https://github.com/morluto/rea/commit/475a0f84dac63d710e032bc7f731c1a3bda624ec).
Function comparison dimension statuses are `unchanged`, `changed` or `unknown`.
The unreachable `truncated` status and `summary.truncated` counter have been
removed. Update exhaustive enum handling and display logic; unavailable facts
remain `unknown`. See
[5510b27](https://github.com/morluto/rea/commit/5510b27d7f863a3df26212fba4a59f8df0da3712).
## Historical-source symlinks
Source graph symlinks with `target_state: "unreadable"` or `"unknown"` require
`target: null`. Internal, external and missing targets retain their actual
recorded target strings. External targets use the observed absolute target;
display placeholders such as `<outside-root>` cannot serve as lookup data.
Reimport the source tree when the old graph retained only a placeholder, and
handle nullable targets in custom readers. See
[b7b4333](https://github.com/morluto/rea/commit/b7b433370310c3ffe33d5027d8393151d5e862da).
Keep original saved artifacts until their replacements and consuming workflows
have been checked. Fresh analysis may establish different facts if the target,
source tree or runtime changed; it does not rewrite what an older capture proved.
+55 -3
View File
@@ -96,8 +96,18 @@ complete observation.
So an external superclass resolves from its `_OBJC_CLASS_$_` bind (for
example `NSObject`). The `pointer_fixups` coverage facet names the mechanism.
Class properties, with parsed attributes, and `__objc_catlist` categories are
also decoded. Categories record the extended class, local or external, plus
Class properties preserve each encoded attribute as a raw `{name, value}`
pair, for example `{ name: "N", value: "" }`, and report atomicity on the
property: `N` means `nonatomic`; a complete typed attribute string without
`N` means the Objective-C default `atomic`;
missing or incomplete attribute metadata leaves `atomicity` and any
unestablished read-only value null. `is_meta_class`, `is_root_class`, and
`ivar_count` are also nullable when the selected provider exposes only symbol
names. Class implementation methods have null `is_required` and `is_optional`
fields because those facts apply to protocol declarations; decoded protocol
method lists retain their observed required/optional values. Class properties
and `__objc_catlist` categories are also decoded. Categories record the
extended class, local or external, plus
their methods, protocols and properties; category methods appear as
implementations with a `category`. Swift field-offset globals that are only
initialized at runtime stay unresolved. Generic, resilient, async and
@@ -128,6 +138,9 @@ an explicit `0x` or address-space prefix selects an address; otherwise an exact
database symbol name takes precedence over a bare hexadecimal address. Thus a
function renamed to `dead` remains selectable by name. Use the names returned
by the inventory, including their namespaces and any platform symbol prefix.
Ghidra also accepts secondary symbols at a function entry, such as an imported
`_main` label. A label inside a function is not a procedure-name selector; use
its address when selecting the containing function.
Overloads can share a fully qualified name; ambiguity errors return every
matching entry address so the caller can select the intended function directly.
@@ -182,10 +195,43 @@ outside-memory and undecodable addresses have separate outcomes. Effective
memory base/index/displacement roles and per-instruction context mode remain
unavailable; `mode` is the program language variant.
Compact instruction references and call-target references preserve the source
address, operand index, DATA/READ/WRITE classification, primary status, provider
`provenance`, and reference `source` (for Ghidra: `analysis`, `default`, `imported`
or `user_defined`). Primary status reports the provider's chosen reference; it
does not establish literal addressing. Analyzer-inferred indexed targets remain
static references, not observed runtime reads or writes. Older evidence may omit
the additive fields, and null or omitted facts mean unavailable rather than false.
Ghidra distinguishes a return using decoded instruction p-code's `RETURN`
operation. `flow.classification_evidence` preserves the Listing flow type and
the observed return evidence; mnemonic spelling alone is not the classifier.
Other terminal or trap flows retain the provider's classification, and this
inspection does not change function extents or prove a calling convention.
The analysis profile commits this decoder behavior. Snapshots from the earlier
profile produce a profile mismatch rather than replaying the former generic
terminal result. The old snapshot's `evidence_bundle` remains valid retained
Evidence: copy that object to a separate JSON file and use `rea evidence-import`
to validate it. Run analysis without the old snapshot and save a fresh one
under the current profile. Other providers and older captures may omit the
classification evidence field.
Call resolution reports direct, resolved indirect, ambiguous, unresolved and
non-call outcomes from static call references. It does not establish runtime
execution or classify Objective-C/Swift/vtable/closure mechanisms from names.
`batch_decompile` keeps each caller-selected symbol or address in `items[].address`.
The separate `procedure` field reports the canonical entry and the provider's
observed entry label. An interior address therefore remains visible without
being mistaken for the function entry. Identity failures are reported as
`procedure.status: "unknown"`; label failures leave a null name and `name_error`.
Neither failure discards usable pseudocode, and names are not parsed from it.
Resolved entries also appear in the composed Evidence locations. New batch
Evidence commits the revised workflow profile; retained historical Evidence
remains valid. This tool
has no dedicated CLI command; the existing `decompile` command remains the
single-procedure CLI operation.
Type inspection selects one exact database pathname or typed data address.
Struct/union fields, enums, pointers, arrays, typedefs, size, alignment, packing
and bitfields retain database authority. Child types use exact IDs for further
@@ -341,7 +387,7 @@ the tool fails with a `debugger-attach-denied` reason.
Install a Ghidra 12.1.x release and the 64-bit full JDK it declares, then configure REA to
use them. Ghidra analysis supports Linux x64/arm64 and macOS x64/arm64; each installation requires
the matching native decompiler. Experimental Windows x64 P0 admits native
x86-64 PE applications on local NTFS using bundled Job Object ownership,
x86 and x86-64 PE applications and DLLs on local NTFS using bundled Job Object ownership,
protected runtime DACLs, and handle-based path admission. See [Windows Ghidra P0](windows-ghidra-p0.md) and
[issue #527](https://github.com/morluto/rea/issues/527).
On Linux and macOS, `annotate_native_function` atomically edits a function name
@@ -351,6 +397,12 @@ unpaired Unicode surrogate; a rejection identifies the field and UTF-16 index
and leaves every annotation unchanged. CRLF, supplementary Unicode characters,
and combining characters are preserved. Windows P0 remains read-only. Ghidra has no
GUI authority, and REA never falls back automatically to Hopper.
`set_address_name` and `set_addresses_names` give Ghidra sessions the same
compact naming results as Hopper: a local function entry renames that function,
and any other mapped address, such as a global, receives a new or renamed primary
label. A batch applies each address separately and reports one success boolean
per address. Use them to name many globals and helpers cheaply; use
`annotate_native_function` when you also want comments and a refreshed dossier.
Ghidra name edits preserve the existing namespace. Supply either a leaf name
such as `renamed` or a fully qualified name in that namespace, such as
`alpha::renamed`. The returned qualified name can be reused as an idempotent
+252 -1
View File
@@ -51,6 +51,34 @@ format is TOON. The file contains the complete capture Evidence record.
Choose an output file distinct from the scenario input: shell redirection opens
and truncates the output before REA reads the scenario.
While the capture runs, REA writes live status to stderr as one JSON object per
line. Stdout stays the final Evidence document:
```json
{
"rea_progress": {
"phase": "running",
"completed": 3,
"total": null,
"message": "elapsed_ms=1200 frames=1 samples=2 interactions=0",
"sequence": 4
}
}
```
`phase` is the observed lifecycle stage: `prepare`, `running`, `settling`, or
`cleanup`. `completed` counts collected terminal frames, process samples, and
interaction events. `total` stays null; REA does not invent a unit total or a
percentage. `message` reports elapsed time and those counts. The final line uses
`phase` `cleanup`, sets `terminal` to true, and adds `disposition` (`exited`,
`timeout`, `idle_timeout`, `cancelled`, or `failed`) plus the owned-process,
renderer, and temporary-root cleanup states. Updates use the shared progress
boundary and are limited to one intermediate line per 100 ms; the terminal line
is always emitted. If a receiver is slow, intermediate observations are merged
into the latest status, and stale live observations are discarded before final
cleanup status. Progress never copies child output. Child output remains in the
capture Evidence on stdout.
For example:
```json
@@ -86,6 +114,12 @@ from launch, must be ordered, and must fall within `timeout_ms`. Inputs marked
Environment overrides are recorded in the scenario commitment; inherited
values are not copied into Evidence.
Terminal dimensions must satisfy `columns × (rows + scrollback) ≤ 1,000,000`.
Every scheduled resize uses the same selected scrollback and must fit this
working-buffer budget. REA rejects oversized scenarios before launching the
command; it never clamps the requested dimensions. This limit is independent
of `limits.output_bytes`, which bounds retained terminal observations.
The capture contains raw PTY output chunks and rendered terminal states,
interaction dispatch outcomes, exit reason, sampled process-tree observations,
and settlement status. When filesystem paths are selected, REA records
@@ -94,7 +128,52 @@ deleted, modified, or unchanged. These are bounded snapshots, not a syscall
trace; short-lived changes between snapshots may be missed. With no selected
paths, filesystem effects remain unknown.
Output, file count, file size, process sampling, filesystem depth, total
A missing entry proves creation or deletion only when the corresponding
observation root's path enumeration was exhausted. Otherwise its effect has
`status: "unknown"`, the available before/after state, and a reason; a null
state in this variant means unobserved. Paths below symlinks that REA did not
follow also remain unknown. Partial enumeration of one root does not erase
known effects in another, and unavailable content hashes do not by themselves
make path absence unknown.
Terminal frame `data` is the comparison text after the selected normalization.
New captures also preserve `raw_data` when normalization changes a PTY chunk;
otherwise `data` is already the original text. Older captures may lack the
original text for changed chunks. Both values participate in Evidence identity,
while comparisons and trace assertions use the normalized text. Retaining the
original adds at most `limits.output_bytes` of text, because it comes from the
same admitted PTY chunks rather than a second unbounded stream.
Rendered frame `lines` hold the visible rows after normalization, with trailing
U+0020 spaces removed. Blank rows and internal spaces remain. `columns` records
terminal cell width; normalization and Unicode can make string lengths differ
from that width. `serialized_state` holds terminal serialization after the
selected normalization. Original admitted PTY chunks are available through
`raw_data ?? data`, as described above. Captures commit this line format in their
comparison contract, so a capture whose lines were padded to full width does not
compare as the same contract.
Custom `normalization.patterns` replace literal text with the caller's literal
replacement, including dollar sequences such as `$&` and `$$`. An empty pattern
also matches the first and last string positions. Captures with custom patterns
commit `pattern_normalization_version: "literal-replacements-v1"`. Legacy captures
remain readable. Cross-version comparison is rejected; capture both sides with
the same replacement semantics. Captures without custom patterns keep their
existing comparison contract.
Port normalization recognizes explicit `port`, `tcp_port`, `udp_port`, and
`listen` fields, URL authorities, IP endpoints, and `localhost` endpoints, with
ports from 0 through 65535. A port may end a sentence, as in `port: 8080.`;
a period followed by a letter or digit continues a decimal, version, or host
name instead. Each PTY chunk is normalized on its own, so a port whose period
ends the chunk is left unchanged because its continuation is not yet known. It preserves ordinary counters, dimensions, file line numbers,
and ambiguous bare host labels. Use explicit literal `patterns`
for a different application-specific spelling. Set `ports: false` to preserve
all endpoint numbers in comparison text. Captures commit the port-normalization
version so older broad numeric normalization cannot silently compare as the
same contract.
Output retention, file count, aggregate file-hashing bytes, process sampling, filesystem depth, total
runtime, idle time, and post-exit settlement are bounded by the scenario's
limits. The result marks truncated observations and residual unknowns rather
than treating missing data as proof of equivalence. Cancellation and timeout
@@ -102,6 +181,139 @@ run the same owned-process cleanup path. Settlement reports whether the
sampled process group quiesced or whether cleanup was needed or unverifiable;
sampling cannot prove that every short-lived or detached descendant was seen.
### Finalization interval
By default a deadline sends `SIGKILL` at once. Set `finalization_ms` to give the
target time to finish: when `timeout_ms` or `idle_timeout_ms` fires, REA sends
`SIGTERM`, keeps capturing output and selected files, and sends `SIGKILL` once
if the interval ends first. Cancellation is not delayed: it sends `SIGKILL`
immediately, also during finalization, and ends the run as cancelled.
```json
{
"executable": "node",
"arguments": ["./job.mjs"],
"filesystem_observation_paths": ["./reports"],
"timeout_ms": 30000,
"finalization_ms": 1500
}
```
REA binds the captured root's first start identity to its ownership token,
checking the identity before and after reading that token. A missing or
mismatched token, or an identity change during validation, leaves the identity
unverified rather than adopting a replacement process. Both finalization
signals recheck that retained identity immediately before the call; the check
and signal remain separate operating-system operations. REA does not fall back
to a bare PID kill for either finalization signal; failed identity or ownership
validation is recorded as `unverified` with its reason. Cancellation before any
deadline keeps the existing terminal kill. Descendants are not signalled during
finalization; owned-process cleanup handles them afterwards.
`exit.reason` keeps the initiating deadline (`timeout` or `idle_timeout`).
`exit.code` is `null` for every deadline exit; the code of an exit observed
during finalization is `exit.finalization.exit_code`, and the observed signal
stays in `exit.signal`. `exit.finalization` records what was observed and is
absent when no finalization was attempted:
```json
{
"code": null,
"signal": 0,
"reason": "timeout",
"finalization": {
"requested_ms": 1500,
"elapsed_ms": 12,
"exit_code": 0,
"signals": [
{ "signal": "SIGTERM", "sent_at_ms": 0, "delivery": "signaled" }
]
}
}
```
- `signals` lists each attempt in order: `SIGTERM` first, at most one `SIGKILL`.
`sent_at_ms` is the attempt time on a monotonic clock, relative to the start of
finalization, also for an attempt that could not be delivered.
- `delivery` is `signaled` (the identity matched and the signal call returned),
`gone` (no live process matched), `identity-changed` (the PID now belongs to a
different process, which was not signalled) or `unverified` (the identity could
not be established or the call failed). None of them proves the process
exited.
An `unverified` attempt may carry a `reason` string naming why: an unavailable
identity and its reason, an inspection or signal error, or delivery that did
not settle within the bound (1000 ms). An attempt recorded `unverified` after
that bound can still complete later; it stays identity-checked, and its late
result is not added to the record.
- `elapsed_ms` is when REA observed the exit, relative to the start of
finalization, or `null` when no exit was observed. The PTY layer can deliver the
exit slightly after the operating system ended the process.
- `exit_code` is the code the PTY reported when the exit was observed during
finalization and was not caused by a signal (`exit.signal` is `0`); a
finalizer that exits with `3` records `3`, one that exits cleanly records `0`.
It is `null` when no exit was observed or the target ended on a signal, and it
is never inferred. A target that exited on its own near the deadline is
recorded the same way.
- The observed signal stays in `exit.signal`; `exit.code` is `null` for every
deadline exit. The record does not attribute an exit to a particular signal,
and a `SIGKILL` from a scenario event next to the escalation cannot be told
apart from it.
- If the `SIGKILL` cannot be delivered, REA stops waiting for an exit, keeps every
observation collected so far with the delivery results, and releases the run
through owned-process cleanup.
- The `SIGKILL` is not sequenced after the `SIGTERM` delivery result: the two
deliveries are independent, because cancellation must not wait for a slow
identity check.
`timeout_ms + finalization_ms + settle_ms` must stay at or below
`Number.MAX_SAFE_INTEGER` (9007199254740991), the largest total exactly
representable as a JavaScript number; the scenario is rejected otherwise. This is
a representability limit, not a timer limit. The nominal lifecycle budget is that
sum; polling, snapshotting and cleanup lie outside it. Scenario `events` keep
being dispatched during finalization and are recorded as usual. `finalization_ms`
of `0`, the default, keeps today's behaviour and the committed identity of every
existing scenario. `elapsed_ms` and `sent_at_ms` are timing data and take part in
exit comparison like `settlement.elapsed_ms`.
Every capture requires `truncation_details`, with separate accounting for:
- `raw_terminal`: original UTF-8 PTY chunk bytes and observed/retained chunk
counts. A chunk that does not fit `limits.output_bytes` is omitted whole;
a later smaller chunk can still fit.
- `rendered_terminal`: cumulative UTF-8 serialized-state and visible-line
bytes, plus observed/retained frame counts. This is independent of the raw
chunk budget and does not count JSON encoding. Repeated screen snapshots can
exhaust it even when all raw output fits. Rendered states use retained PTY
input, so raw omissions also limit rendered coverage.
- `filesystem_before` and `filesystem_after`: file-count/depth limits,
enumeration failures, whole-file hash budget and bytes successfully hashed.
Directory names are read incrementally within the remaining entry capacity.
When a directory exceeds that capacity, the retained subset follows filesystem
enumeration order and is then sorted; it is explicitly incomplete and cannot
establish that an omitted path is absent.
Each retained regular file without a digest has an aliased path, size,
remaining budget and reason: `file_bytes_budget`,
`file_changed_or_short_read`, or `file_unavailable`. Its `system_code` is
null unless an OS file operation failed, in which case it preserves the
reported error code. A file too large for the remaining budget is
skipped; a later smaller file can still be hashed. Hash omissions do not
imply incomplete path enumeration.
- `process`: sampling limit and whether sampling ended partially. Coverage
remains `sampled`, including when that limit was not exhausted.
The aggregate `truncated` flag summarizes these observations. Comparisons retain
results for unaffected dimensions and mark affected dimensions unknown; an
incomplete capture cannot locate the first divergence across all dimensions.
Trace assertions use coverage for the sources they select, so an assertion
about complete raw terminal output need not fail because rendered snapshots
were omitted. Captures missing `truncation_details` are rejected on import;
preserve them as historical files and recapture for current comparisons.
`limits.file_bytes` is already the cumulative whole-file hashing budget,
independent of `limits.output_bytes`, which bounds retained terminal content.
Each filesystem checkpoint starts with a fresh `file_bytes` budget across all
selected roots; it is not a per-file allowance. File contents are read in
64 KiB chunks for hashing and are not embedded in capture Evidence.
When the host withholds an unrelated process’s ownership token, REA leaves that
process untouched and records its PID and reason in `cleanup.unverified_processes`
and process residual unknowns. Successful cleanup verifies the owned group;
@@ -116,6 +328,45 @@ as well. A newly started unreadable process can prevent verified cleanup even
after the selected command exits. REA preserves this uncertainty and leaves
that process untouched.
## Hash a report independently of terminal output
Select the producer's report directory and give `file_bytes` enough room for
the complete files you need, including other files in those roots. For example,
save this scenario and run `rea capture-process ./scenario.json --json > capture.json`:
```json
{
"executable": "node",
"arguments": [
"-e",
"const fs=require('node:fs');fs.mkdirSync('reports',{recursive:true});fs.writeFileSync('reports/final.json',JSON.stringify({status:'complete',data:'X'.repeat(131072)}));console.log('x'.repeat(8192));"
],
"working_directory": ".",
"filesystem_observation_paths": ["./reports"],
"limits": { "output_bytes": 1024, "file_bytes": 262144 }
}
```
The report exceeds the terminal budget but fits the independent 256 KiB hash
budget. Its complete SHA-256 appears in `normalized_result.files_after` at
`root_0:final.json`; check `truncation_details.filesystem_after` for omissions
and actual bytes hashed. The verbose terminal output is truncated without
preventing the report digest. The same scenario object is the MCP
`capture_process_scenario` input. REA never returns a prefix hash as a full-file
digest: an insufficient remaining budget produces a null digest and an
explicit omission reason.
A digest binds the complete bytes observed at that checkpoint, not the
producer's notion of a finished report. A stable periodic or running report
can also have a complete digest. Choose the final file and verify the
producer's documented completion marker, exit outcome and settlement
observations before calling it final. `after_settlement` names a filesystem
checkpoint, not a guarantee that an application finished successfully or
that an unobserved writer will never change the file. REA checks opened-file
identity/state around hashing and reports observed changes or unavailable
files; cancellation stops the hash. If an external sealer produces a manifest,
keep its completion claims and digest separate from REA's checkpoint facts.
## Compare two captures
Compare saved capture Evidence with:
-219
View File
@@ -1,219 +0,0 @@
# Static-analysis provider evaluation
This guide describes repository main. Check the [released package boundary](installation.md#released-package-and-main) when using npm.
Ghidra read-only analysis is available on Linux x64/arm64 and macOS x64/arm64.
Install a Ghidra 12.1.x release and the 64-bit full JDK that release declares,
then configure REA to use them. Current 12.1 releases require JDK 21 or newer
and set no maximum. The bridge is verified with Ghidra 12.1.4 and JDK 21.
Each installation needs the matching native decompiler.
REA imports one target into a temporary project and exposes 25 read-only
operations after analysis completes. They cover inventories, search,
decompilation, assembly, function metadata, resolved calls, references, control
flow, instructions, and recovered types. Results identify the provider version,
analysis settings, target digest, and any unavailable or incomplete facts.
On Linux and macOS, `annotate_native_function` additionally edits names and entry
comments atomically, verifies readback, and returns refreshed function analysis.
Changes live only in the session database and leave executable bytes unchanged.
Ghidra does not expose GUI controls; Windows P0 remains read-only.
Windows x64 P0 supports native x86 and x86-64 PE applications on local NTFS with
bundled Job Object ownership, protected runtime DACLs, and handle-based path
admission. Real ordinary-user verification covers all 25 read-only operations
through the packaged CLI and MCP, target integrity, and cleanup. This remains
an experimental boundary; see [Windows Ghidra P0](windows-ghidra-p0.md) and
[issue #527](https://github.com/morluto/rea/issues/527).
[ADR-0001](adr/0001-provider-selection-and-analysis-profiles.md) fixes the
provider registry, deterministic selection, target binding, analysis profile,
snapshot migration, and compatibility semantics that implementation must
follow.
## Approved Ghidra v1 boundary
- Keep the existing provider-neutral CLI and MCP tool names.
- Bind one deep-analysis provider to a target for the target's lifetime; never
fail over silently between Hopper and Ghidra.
- Use an existing Ghidra installation and a compatible Java runtime. Setup must
not install or upgrade Ghidra or Java.
- Run Ghidra headlessly in an owned process with a private temporary project,
startup and cleanup deadlines, caller cancellation, and complete replies.
- Prefer a packaged Java bridge loaded through Ghidra's script path. PyGhidra
remains useful for prototypes but is not a mandatory production dependency.
- Treat authenticated `ping` and `shutdown` as lifecycle proof only. Inventory,
xref, CFG, and decompilation claims require separately admitted operation
contracts and real-provider conformance.
- Implement read-only inventories, assembly, decompilation, function metadata,
calls, references, containment, and complete inventory search first.
- Report GUI cursor/navigation and persistent mutation operations as unavailable
until their semantics and project ownership are explicitly designed.
- Verify real claims on Linux with at least two distinct source-owned binaries.
Verify the Windows host claim with the deterministic source-owned x86 and x86-64 PE
fixtures and all admitted operations; compare normalized semantic facts rather
than provider-specific pseudocode text.
## Shipped foundation boundary
`GHIDRA_INSTALL_DIR` must identify an extracted Ghidra 12.1.x release. Optional
`JAVA_HOME` must identify a 64-bit full JDK inside that installation's
`application.java.min` and `application.java.max` (JDK 21 or newer, with no
maximum, when the release leaves those at the 12.1 defaults). Otherwise doctor
probes `java`/`javac` or `java.exe`/`javac.exe` from `PATH`. Supported Linux and macOS
hosts accept compatible ELF, PE, and Mach-O executable targets. Host admission
and target compatibility are separate checks. Windows x64 P0 admits only native,
non-managed, non-DLL x86 and x86-64 PE applications on fixed local NTFS, with the packaged
native authority available before launch.
The launcher creates one ephemeral runtime root with project,
home/cache/config/data/temp, logs, descriptor, endpoint, target snapshot, and
ownership manifest.
It passes `-readOnly` and `-deleteProject`, and uses Ghidra's default analysis
and resource settings; inherited Java option injection variables are cleared.
On Linux, the mode-0600 descriptor carries the random token without
exposing it in argv or environment and the Java bridge binds a mode-restricted
Unix socket. macOS uses the same local transport. The bridge reports actual
Ghidra/language/compiler/analysis/import-digest metadata and accepts only
authenticated `ping`, `shutdown`, thirteen read-only inventory/load-image methods,
and twelve function-analysis methods. Linux/macOS also admits atomic function
annotation changes in the ephemeral database. Close, cancellation, timeout, malformed protocol,
or process exit stops the owned process resources, closes the socket, and
removes the runtime root.
The experimental Windows transport uses authenticated IPv4 loopback with a
token-free endpoint record. The bundled native authority establishes Job Object
ownership, protected runtime DACLs, and handle-based path admission before
launch. If the bundle or an admission constraint is unavailable, the provider
remains unavailable; a `taskkill` fallback does not establish that authority.
The provider catalog lists 25 read-only Ghidra operations and the Linux/macOS
session annotation operation. GUI cursor/navigation and persistent mutations
remain unavailable; Windows P0 admits no database mutation. The router therefore
reports them unavailable instead of borrowing Hopper semantics or inferring
capability from a successful import.
## Admitted inventory semantics
| Concern | Ghidra contract |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Program identity | One `analyzeHeadless` import produces exactly one Program; `list_documents` therefore returns exactly one name. |
| Addresses | Default memory uses lowercase `0x` hexadecimal. Non-default and external spaces use `<percent-encoded-space>:0x<hex>` and remain round-trippable. The handshake commits image base and default address-space name. |
| Symbols | `list_names` includes address-bearing memory and external symbols, including dynamic symbols, while excluding variable and no-address namespace records. Each item reports primary, dynamic, external, symbol type, and source facts. |
| Procedures | Both non-external and external functions are listed. A local thunk remains distinct from its resolved target; exact and qualified name lookup fails on ambiguity rather than guessing. |
| Strings | Only Ghidra-defined string `Data` is observed. Items report charset, byte length, and whether a required null terminator is missing. The API cannot distinguish a present terminator from fixed/Pascal layouts when no terminator is missing, so that state is named `present_or_not_required`. |
| Memory | Memory-block end addresses are exclusive. Read/write/execute, initialization, overlay, address space, and image base are direct Ghidra observations. |
| Inventory | Procedure, symbol, and string listings plus searches return the complete matching collection in one response; callers do not provide offsets or result-count limits. |
| Search | Literal and Java-regex searches scan the complete immutable inventory and return all matching entries inline. Search waits for a reply or caller cancellation; there are no caller-supplied offsets or result-count limits. |
| Analysis state | The socket is exposed only after default auto-analysis completes. Established operations wait for their reply or caller cancellation; there is no fixed response-size ceiling. |
## Admitted function-analysis semantics
| Concern | Ghidra contract |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Decompiler lifetime | One persistent `DecompInterface` is opened for the imported Program and disposed during bridge shutdown. Native decompilation has no fixed per-function deadline. External functions or functions without bodies return `null`; cancellation and native failure remain distinct. |
| Serialization | A FIFO sends one Program request at a time. Caller cancellation removes queued work promptly and is passed to active socket waits. This is an adapter safety commitment, not a claim that every Ghidra API is thread-safe. |
| Function identity | Every function result carries the entry address and Ghidra FunctionManager classification for external, thunk, and resolved thunk target. These are observations, not proof that unresolved targetless calls have been recovered. |
| Assembly and pseudocode | Assembly is complete Ghidra Listing text; pseudocode is Ghidra decompiler output. Neither is original source, and cross-provider comparison never treats Hopper and Ghidra text as equal or unequal semantic facts. |
| Instruction fast path | `read_function_instructions` returns every raw Listing instruction for the requested function without invoking the decompiler or whole-program name/string inventories. |
| Calls and references | Callers/callees contain only resolved functions. Reference edges preserve exact ReferenceManager type and call/jump/data/read/write/indirect/computed/conditional/terminal/external facts. Targetless computed flow remains unknown. Synthetic entry-point references without actionable memory sources are omitted explicitly. |
| CFG | Dossiers use `BasicBlockModel` and retain only non-call successors inside the function body. CFG topology is address-normalized for comparison; provider-specific block construction remains a declared difference. |
| P-code value flow | Function dossiers include up to 3,000 high-p-code operations, at most 64 inputs per operation, and 12,000 def-use edges. Results identify memory reads/writes, branches, and calls by p-code opcode, and mark decompiler-dead operations. Large results report truncation, an omitted-operation lower bound, and known omitted-input/edge counts. The dossier is an intra-function graph; `trace_native_values` composes derived parameter/argument and return/output dependencies across resolved calls. It does not resolve memory aliasing, call side effects, runtime behavior, persistent state, or business meaning. |
| Result extent | Function instruction scans and native API boundary observations remain complete. P-code flow is the explicit bounded exception; its count fields distinguish exact retained counts from lower-bound or known-omitted counts. Caller cancellation and provider failures remain distinct. |
`npm run verify:ghidra` compiles the versioned C oracle into debug and stripped
host-native targets (x86-64/AArch64 ELF on Linux or Mach-O on macOS), plus a native
DWARF 4 type-layout object. It proves the admitted operations, external functions, resolved thunks, exports, stripped-name
behavior, direct and targetless indirect calls, typed references, strings/xrefs,
multi-block CFG, bounded p-code def-use/effect links, semantic enhanced workflows, cancellation, startup deadlines,
serialized concurrency, malformed-target rejection, profile identity, and
process/project cleanup against real Ghidra 12.1.4. Unit fixtures separately
cover startup deadlines, process exit, queued cancellation, and malformed wire
output.
`npm run verify:ghidra:cross-format` adds AArch64 ELF, x86-64 PE, and x86-64
Mach-O target coverage. It requires `clang`, LLD, and `lld-link`; set
`REA_CLANG`, `REA_LLD`, or `REA_LLD_LINK` to select them. The verifier checks
these tools before compilation. Keeping this matrix separate lets Linux
host/provider acceptance run with only the host compiler.
`npm run verify:ghidra:windows` and its `-- --x86` variant check the source-owned native x86 and x86-64 PE
fixture, all 25 read-only operations, target/snapshot/import SHA-256 linkage,
and project, endpoint, process, and runtime cleanup. The independent native
lane checks DACLs, handle admission, cancellation, and Job Object lifecycle.
`npm run verify:ghidra:windows:package` packs and installs REA into an isolated
prefix, then checks ordinary-user CLI/MCP operations against canonical contracts.
All lanes require matching native controls; package startup alone establishes
only package compatibility.
## Shared provider-process foundation
`src/process/` now provides the mechanisms that a long-lived Hopper or Ghidra
adapter shares: POSIX run-token-authenticated process-group ownership,
ephemeral temporary runtime roots, one absolute startup deadline, correlated
request cancellation and lifecycle-deadline cleanup, bounded stdout and stderr retention with
exact byte counts, process-exit diagnostics, and bounded TERM-to-KILL shutdown.
Reusable fixtures exercise exit, timeout, cancellation, graceful termination,
forced termination, double-close, spawn failure, and resource release. Windows
Ghidra uses its native Job Object, private runtime, and path-admission boundary;
generic process-tree termination alone cannot establish provider availability.
The foundation does not define a bridge schema, socket framing, health payload,
analysis model, or shutdown acknowledgement. Hopper keeps its authenticated
NDJSON-over-Unix-socket protocol in `src/hopper/`; Ghidra has a separate strict
NDJSON protocol implemented by the packaged Java `HeadlessScript` and reuses
only the generic process mechanisms.
## Shortlist
| Provider | License / automation surface | What it brings | REA fit and blockers |
| ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Ghidra](https://github.com/NationalSecurityAgency/ghidra) | Apache-2.0 source license; `analyzeHeadless`, Java APIs, and PyGhidra | Static analysis, multiple processors and formats, scripting, and project/database workflows | 25 read-only operations shipped on Linux/macOS with installation checks, temporary projects, a serial API queue, and real ELF/PE/Mach-O conformance. Experimental Windows x64 P0 supports native x86 and x86-64 PE on local NTFS with bundled native controls and ordinary-user CLI/MCP verification; Linux/macOS additionally support atomic session function annotations; Windows mutation and all Ghidra GUI operations are unavailable. |
| [Rizin](https://github.com/rizinorg/rizin) / [rz-pipe](https://github.com/rizinorg/rz-pipe) | Rizin repository contains LGPL-3.0 and GPL-3.0 components; `rizin`, `rz-bin`, and language bridges through `rzpipe` | Portable CLI analysis, disassembly/debugging, many architectures and file formats, JSON command output | Good candidate for a process-backed Linux provider and fast metadata fallback. License/component inventory must be preserved; command output needs version-pinned parsers and semantic conformance before evidence is trusted. |
| [LIEF](https://github.com/lief-project/LIEF) | Apache-2.0; C++, Python, and other bindings | Deterministic parsing and modification of ELF, PE, Mach-O, COFF, and related executable formats; headers, sections, symbols, relocations, and functions | Best near-term complement, not a decompiler replacement. It can cover format metadata and artifact evidence without a long-lived analysis process; function semantics, pseudocode, CFG, and cross-reference parity remain out of scope unless separately demonstrated. |
| [Binary Ninja](https://docs.binary.ninja/dev/index.html) | API/documentation components are MIT, while the analysis product is licensed by edition; commercial, Ultimate, or Headless license is required for headless automation | Python/Core/C++/Rust APIs, headless loading, IL layers, function analysis, plugins, and configurable analysis | Strong technical fit for a native provider, especially function dossiers. Commercial licensing, license-secret handling, native runtime packaging, and multithreaded lifecycle rules are material deployment blockers. |
## Recommended order
1. Use the implemented explicit provider registry and target binding without
changing Hopper behavior.
2. Maintain the admitted Ghidra function boundary through the shared
conformance corpus and add formats or semantics only after real proof.
3. Connect Electron/native-add-on application findings to the selected native
analysis provider without introducing provider-prefixed tools.
4. Evaluate LIEF or Rizin later as complementary metadata/disassembly providers,
and Binary Ninja as an optional licensed provider, using the same admission
gate.
## Required admission gate
Before implementation, an adapter proposal must provide:
- a capability matrix covering supported, unsupported, and degraded results;
- provider identity, version, analysis profile, target digest, authority,
limitations, and deterministic locations in every Evidence record;
- bounded subprocess or library lifetime, cancellation, timeouts, and cleanup;
- actionable local diagnostics that retain paths, digests, mismatch locations,
and provider metadata while redacting credentials, authorization headers,
license secrets, and other genuine secrets;
- the same source-owned fixture corpus across architectures and formats;
- repeatable checks for function identity, addresses, strings, names, xrefs,
CFG, and pseudocode wherever those capabilities are claimed.
These gates turn the accepted direction into verified capabilities rather than
prematurely claiming equivalence or redistribution support.
## Primary-source notes
- Ghidra 12.1.4 documents headless batch mode and its Java runtime requirements
in its [release-specific Getting Started guide](https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1.4_build/GhidraDocs/GettingStarted.md);
the [official release](https://github.com/NationalSecurityAgency/ghidra/releases/tag/Ghidra_12.1.4_build)
supplies the corresponding distribution and checksums.
- Rizin lists supported formats, architectures, tools, and `rzpipe` bridges in
its [repository README](https://github.com/rizinorg/rizin); `rz-pipe` documents
JSON command transport and pipe backends.
- LIEF's [format tutorial](https://lief.re/doc/stable/tutorials/01_play_with_formats.html)
and [Python API](https://lief.re/doc/latest/api/binary_abstraction/python.html)
document parsing and format-agnostic binary access.
- Binary Ninja documents its [headless automation model](https://docs.binary.ninja/dev/batch.html),
[edition licenses](https://docs.binary.ninja/about/license.html), and the
[MIT license for API/documentation components](https://docs.binary.ninja/about/open-source.html).
File diff suppressed because it is too large Load Diff
+49
View File
@@ -15,6 +15,52 @@ the original run after a partial publication.
For a release that needs an independently frozen application checkpoint, use
the optional manual path below. It retains explicit prepare and publish phases.
## Contributor-aware release notes
Use [the rea-changelog-update skill](https://github.com/morluto/rea/blob/main/.agents/skills/rea-changelog-update/SKILL.md)
to turn the bot draft into grouped Highlights, Changes, and Fixes with inline
`Thanks @...` credit. `npm run release:notes -- inventory` collects the full
selected Git range and paginated GitHub PR/author/closing-issue metadata;
`record --summary` produces a compact provenance link for public notes, while
`record` produces the full record for review. Credit a contribution once even
when it appears in highlights, details and migrations; omit maintainer
`@morluto` self-thanks. Keep complete authorship metadata in the inventory
instead of duplicating a credit ledger in the release body. `check` validates credits
and optional PR-body equality, and `render` writes the verified release section.
Run a subcommand without its required options to see its usage. GitHub reads
require an authenticated `gh`; record/check/render work offline from the saved
inventory and complete local Git history.
Save a finalized inventory on the release branch at
`docs/releases/VERSION.contributions.json`. Review unknown identities and
reverted/backported work explicitly; GitHub metadata does not establish the
quality of a user-facing claim. Preserve the existing breaking-change section
and checkpoint checks. The contribution inventory is a reviewed snapshot, not
a signed attestation; the offline checker verifies local range coverage and
credit consistency, not GitHub's authorship independently.
Before editing the live PR, add `rea:release-notes-finalized` to prevent ordinary
main-push proposals from overwriting the editorial notes. Wait for any already
running proposal to finish. The guard applies to main-push automation; do not
run manual checkpoint preparation over finalized notes. Remove the label to
resume bot regeneration. The label does not freeze the base branch: new base
commits require re-inventorying and re-reviewing the notes.
Update both the release branch's `CHANGELOG.md` and the PR body, preserving
Release Please's surrounding metadata. Before creating a release, the workflow
checks an inventory when present, requires its target to equal the reviewed
merge's first parent, and compares the freshly fetched PR body to the changelog.
It rejects changes outside the release metadata paths and stale credit records
before any tag or publication. Review the diffs within allowed metadata paths
as well, especially package dependencies and scripts. Existing candidates without inventories retain their current
checks. Merging still starts publication; a notes edit does not authorize a
merge or release by itself.
The checker supports inline Release Please PR bodies up to GitHub's 65,536
character limit, including the surrounding header/footer. Overflow-link PR
bodies need a separate integration and fail explicitly; credits are never
silently truncated.
## 1. Select a source for a manual checkpoint
Use the next minor version proposed by Release Please, including releases with
@@ -35,6 +81,9 @@ registry metadata or changelog disagrees with that version before creating a tag
### Compatibility and version selection
For the 6.2 candidate, review the [6.1 to 6.2 migration guide](migration-6.2.md)
alongside the changelog before publication.
REA uses Release Please's `always-bump-minor` strategy: every release increments
minor and resets patch, including releases with breaking changes. For example,
the next release after 6.0.0 is 6.1.0. Version numbers use the SemVer format,
+27 -117
View File
@@ -1,125 +1,35 @@
# REA roadmap
## Tool direction
The [platform tracker](https://github.com/morluto/rea/issues/32),
[process/Hopper tracker](https://github.com/morluto/rea/issues/48), and
[browser tracker](https://github.com/morluto/rea/issues/39) track capability and
verification work. Available tools and setup are documented in the
[investigation guides](https://rea.tools/guides/),
[installation guide](installation.md), and
[generated catalog](mcp-contracts.md#generated-catalog).
REA provides inspection, capture, and comparison tools that return evidence
directly. Agents choose commands, paths, browser actions, scripts, and local
fixture servers, then compose experiments from those results. CLI and MCP must
expose equivalent behavior and preserve observations, inferences, and unknowns.
## Priorities
[#555](https://github.com/morluto/rea/pull/555) removed REA permission grants,
scope ceilings, elicitation, and repeated approval fields.
[#572](https://github.com/morluto/rea/pull/572) removed the replay engines,
Node characterization prepare/execute flow, and plan-only managed runtime
correlation tool. Those systems are retired roadmap items. Existing evidence
authority labels remain readable as provenance; they do not imply a current
replay executor.
- Expand native architecture, type, and indirect-call verification.
- Connect static findings and runtime observations across application layers.
- Improve obfuscated managed-code comparisons and verified native links.
- Extend process, protocol, filesystem, reconnect, and build-comparison coverage.
- Evaluate additional providers and targets when an analyst workflow demonstrates
a capability gap.
Local operations use the current user's OS permissions. Input and protocol
validation, provider prerequisites, target identity, cancellation, and owned
resource cleanup remain part of each tool's contract. Setup still discloses
installation changes and requires approval before writing or installing.
## Admission criteria
## Planned work
New capabilities must return useful evidence through shared CLI/MCP workflows,
preserve observations and unknowns, and declare actual authority and lifecycle
constraints. Agents compose experiments using ordinary commands, scripts, and
fixture servers; custom orchestration needs a demonstrated requirement.
The [website guides](https://rea.tools/guides/) and
[generated catalog](product-catalog.json) describe available workflows.
Current development priorities are:
Provider and platform claims require their corresponding
[real verification lanes](testing.md#real-toolchain-verification-lanes).
See [tool design](tool-design.md) for choosing a tool boundary and
[Ghidra semantics](ghidra-provider.md) for the existing deep-provider contract.
- Keep generated metadata and narrative documentation aligned with tools,
providers, setup options and releases.
- Expand native architecture, type and indirect-call verification across
Hopper and Ghidra.
- Connect additional static extractors and runtime observations to
cross-layer feature traces.
- Improve obfuscated .NET comparisons and links between managed findings
and verified native analysis.
- Extend process, protocol, filesystem, reconnect and build-comparison
coverage, plus browser and Electron scenario actions.
- Evaluate native runtime observation through LLDB, Frida, system logs and
API tracing, and additional tools and targets such as Binary Ninja, Rizin,
LIEF, Windows-native workflows, mobile applications and firmware.
Provider additions and platform support require the corresponding real
verification lanes; see [testing](testing.md) and
[provider evaluation](provider-evaluation.md).
## Remaining evidence and provider work
The [platform roadmap](https://github.com/morluto/rea/issues/32),
[process and Hopper fidelity tracker](https://github.com/morluto/rea/issues/48),
and [browser tracker](https://github.com/morluto/rea/issues/39) track remaining
capabilities and proof. Their scope follows direct tools and agent-composed
experiments; custom replay languages and grant systems are not completion gates.
[Inline Evidence composition](https://github.com/morluto/rea/pull/585) now returns
the complete record accepted by comparison tools. Managed inspection uses an
explicit PE/CLI target independently of the native provider selection. Comparisons
preserve unknowns when observation is incomplete, and PTY diagnostics retain the
actual loader or startup failure. Browser cleanup reports incomplete teardown
alongside the primary failure; transient documents invalidate only the affected
frame's WebMCP registrations. Real-provider and platform claims still require
their corresponding verification lanes.
## Shipped behavior
REA setup lets you select agent integration and optional Hopper installation.
It installs the bundled workflow, configures detected agents, and can save
verified paths for an existing Ghidra installation. It configures Claude Code,
Claude Desktop, Codex, Cursor, Gemini CLI, Windsurf, Devin, OpenCode, Antigravity,
GitHub Copilot CLI, Command Code, VS Code, and Grok Build using each client's configuration format. Grok Bot is detected locally, but its connector is added from the Grok Bot chat because the signed-in account store is not a data-directory file.
Ghidra analysis supports Linux x64/arm64 and macOS x64/arm64 with Ghidra 12.1.x and the
64-bit full JDK that installation declares. Current 12.1 releases require JDK 21
or newer and set no maximum; the bridge is verified with Ghidra 12.1.4 and JDK 21.
Each installation requires the matching native decompiler. The
adapter exposes thirteen inventory operations and twelve function-analysis
operations, for 25 read-only operations total. Linux and macOS additionally support
atomic function-name and entry-comment edits with refreshed analysis; metadata
is discarded on close and executable bytes stay unchanged. Approved setup saves verified
installation paths in agent configurations without installing or changing
Ghidra or Java.
Real-provider verification uses host-native debug and stripped fixtures plus
a native type-layout object. A separate lane covers AArch64 ELF, PE, and
Mach-O cross-target fixtures. See [testing](testing.md) for the prerequisites
and exact commands.
Experimental Windows x64 P0 now supplies bundled Job Object ownership,
protected runtime DACLs, and handle-based admission for native x86 and x86-64 PE
applications on local NTFS. Real ordinary-user CLI/MCP verification covers
all 25 read-only operations and cleanup. The [Windows P0 guide](windows-ghidra-p0.md)
describes this boundary and unverified broader coverage.
## Ghidra maintenance boundary
Extend formats or semantics only with normalized provider-neutral contracts and
real source-owned conformance. Hopper and Ghidra pseudocode or assembly text is
not expected to match; unresolved targetless flow remains unknown. Automatic
Ghidra acquisition, if ever added, remains a separately planned and approved
related-tool change; setup must never install Java.
Maintain Windows P0 with independent DACL readback, handle-based admission,
private authenticated IPC, and Job Object assignment before provider execution.
Process capture, Hopper, and broad filesystem-sensitive workflows remain
separate Windows projects; P0 does not imply their parity.
## Capability-selective setup
Setup already lets users select agent integration and Hopper installation.
Once REA supports installing additional analysis tools, it can expand these
choices to match the work a user wants to do. It may ask whether the operator wants to investigate
native binaries, websites, mobile applications, firmware, or runtime protocols,
then propose only the tools needed for the selected work.
That future installer must preserve the current safety boundary:
- detect and reuse existing tools;
- disclose every source, destination, license, command, and system effect;
- prefer user-local installation;
- install only explicitly selected toolchains;
- require tool-specific authorization for unattended system changes;
- verify each installed tool before reporting readiness.
No placeholder tool choices or speculative installer registry are implemented
until another supported toolchain makes the abstraction concrete.
Setup remains additive, reuses existing tools, and requires approval for disclosed
configuration and Hopper installation changes. Additional installer choices need
an implemented toolchain and explicit scope; setup does not install or upgrade
unrelated runtimes or dependencies.
+515 -155
View File
@@ -1,62 +1,36 @@
# Testing REA
Prefer evidence in this order: full end-to-end workflows with real production
providers, integration tests across data/API boundaries, then golden regressions
from real captured inputs. Keep focused module tests for distinct failure or
semantic cases that these workflows cannot reliably reproduce. A test's path
or suite name does not establish its behavioral depth.
Use this guide when choosing coverage, pruning tests, or running a verification
lane. For commands, jump to [developer commands](#developer-commands); for engine
prerequisites, use [real-toolchain lanes](#real-toolchain-verification-lanes).
Avoid tests that mirror getters, enum mappings, fixture helpers, or prescribed
call sequences, or assert cache object identity without a caller-visible contract.
Prefer representative workflows over a Cartesian matrix when rows cross the
same boundary. Retain combinations that exercise a distinct interaction, such as
filtering within a full-output envelope. Keep distinct command handlers,
producer representations, failure reasons, and lifecycle states covered.
Consolidate their shared setup without hiding the inputs or expected evidence.
Prefer real public CLI/MCP workflows, then production-boundary integration,
then goldens captured from real producers. Keep module tests for distinct
failures or semantics that stronger workflows cannot reliably reproduce.
Paths, compiled imports, and suite names do not establish test depth.
Tests are grouped into Vitest projects so ownership, allowed dependencies and
runtime cost are visible from their paths. Before pruning a distinct boundary
regression, identify the replacement scenario and its assertions; passing
success journeys do not replace malformed input, cancellation, permission or
cleanup coverage. Trivial helper checks do not need a replacement. If only
tests consume a production module, trace CLI/MCP and verifier imports,
including imports of compiled files, and remove abandoned scaffolding with its
tests when it has no runtime consumer.
Prune tests that mirror implementation details or duplicate a stronger claim.
Before deleting a distinct regression, identify the replacement scenario and
assertions. Preserve malformed formats, cancellation, cleanup, permissions,
capacity, target identity, and combinations with distinct interactions.
Trivial helper assertions need no replacement. Remove abandoned production
scaffolding only after checking runtime and verifier consumers, including
compiled imports.
When a test expects a `Result` to succeed, throw its error before asserting the
returned value. An `.ok` assertion immediately before the same throwing guard
adds no coverage and hides the typed failure. A removed parser matrix can leave
one golden malformed-input case and a real filesystem lifecycle that proves
configure, update, readback, and removal; an add-only journey does not cover the
whole lifecycle.
Use representative scenarios rather than Cartesian matrices of equivalent
cases. Share setup without hiding inputs or expected evidence. For successful
`Result` values, throw the typed error before asserting the value; a preceding
`.ok` assertion adds no coverage. Protocol fixtures must reject unmodeled
commands and preserve actual producer reply shapes.
Protocol fixtures must model the commands they support and their producer reply
shapes. Reject unmodeled commands instead of returning a generic success; an
empty result is appropriate only for a supported command with no result fields.
Report unavailable authority as a named skip. Await owned cleanup before a
verifier reports success. Native process inspectors are released at Vitest
worker teardown; fork termination does not run Node exit hooks, and per-file
teardown would retire inspectors still needed by other files.
Keep transport-only in-memory MCP sessions in the MCP boundary lane and direct
filesystem workflows in the filesystem boundary lane. Real process-tree capture
belongs in the serial process boundary lane, including captures invoked through
MCP. Report unavailable capture authority as a named skip rather than returning
from the test without assertions. Reserve acceptance paths for journeys
through the compiled public CLI or MCP runtime. Calling a compiled private
workflow or injecting a provider still establishes its narrower integration
claim, even if a directory name calls it acceptance.
Emit a verifier's final success report only after awaited cleanup. Observe final
process lineage after closing its owned resources.
The Vitest runner releases cached native process inspectors during awaited
worker teardown. Fork termination does not run Node's normal exit hooks; a
per-file teardown would instead retire shared inspectors before later files
can use them.
Measure slow files before removing capacity regressions. Optimize repeated
process startup, fixture construction, and production algorithms when they
dominate runtime. Keep at least one input beyond each formerly failing size or
depth; smaller fixtures do not establish that truncation or stack exhaustion
has been fixed. Record the toolchain, coverage mode, and cache conditions when
comparing durations.
Measure slow cases before pruning capacity coverage. Retain inputs beyond the
formerly failing size/depth and distinguish cold runs, warm builds, coverage,
and toolchain conditions when comparing timings.
## Behavioral depths
@@ -79,12 +53,6 @@ registries but do not cross production filesystem, process, socket, or browser b
Boundary tests cross one production boundary. Only acceptance tests assemble
the complete runtime or invoke the compiled product surface.
Binary session, registry, lazy-client and snapshot module cases live under
`src/application/binary/`. Their composition cases stay in
`tests/composition/analysis-sessions/`; snapshot persistence and actual SDK calls
stay in the filesystem and MCP boundary lanes. The shared injected session fixture
serves several capabilities and remains under `tests/fixtures/`.
Focused immutable builders and recording ports shared by one test family live
beside their production owner as `src/**/*.fixture.ts`. They are typechecked
with the suite and excluded from package builds; broader runtime and provider
@@ -120,6 +88,191 @@ entrypoint and include its verifier/fixture files in their cache inputs.
## End-to-end, integration and golden evidence
The optional `verify:qwen-client`, `verify:pi-client`, and `verify:hermes-client`
lanes require an installed native client. Select its executable with
`REA_VERIFY_QWEN_COMMAND`, `REA_VERIFY_PI_COMMAND`, or `REA_VERIFY_HERMES_COMMAND`.
They configure disposable profiles through the public REA CLI, preserve caller
settings and backups, and exercise real stdio MCP calls and skill loading. The
`call` mode checks complete catalog discovery and actual JavaScript Evidence;
pass `-- chat` to check plain chat with REA enabled. Qwen also reads the full
result that its client offloads, and Pi exercises default codemode execution.
Use `REA_VERIFY_RUNTIME_ROOT` to select a production-only installed REA package.
Receipts retain client versions, result digests, host coverage and owned-process
cleanup. These POSIX lanes use a deterministic loopback model, so they do not
prove live model-provider or native Windows compatibility. Qwen, Pi and Hermes
bind both `HOME` and `USERPROFILE` to the disposable account. Qwen and Pi discover
the shared personal skill through their default search paths without an explicit
skill setting; Hermes discovers it through the selected `HERMES_HOME`.
Set `REA_VERIFY_HERMES_STICKY_PROFILE=1` to exercise native Hermes selection of
a named sticky profile with `HERMES_HOME` still pointing to its root.
`verify:gemini-client` requires an installed Gemini CLI (verified with
`@google/gemini-cli@0.63.0`); select it with `REA_VERIFY_GEMINI_COMMAND`.
The optional POSIX lane uses native `GEMINI_CLI_HOME` discovery in an isolated
Git project, checks setup plans, backups and idempotence, activates the installed
personal skill, validates all forwarded input JSON Schemas against their declared
dialect, forwards the complete REA catalog and checks full JavaScript
Evidence for a Unicode path. Use `-- chat` for ordinary chat with REA enabled,
or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed REA package.
The local fixture exercises the real Gemini API adapter, including its
`untrusted_context` tool-result envelope. Token counts are synthetic; live
Google API and native Windows compatibility remain unverified. The lane disables
the client's memory-based relaunch to preserve the caller's Node heap budget.
`verify:opencode-client` requires an installed OpenCode (verified with
`opencode-ai@1.18.35`); select it with `REA_VERIFY_OPENCODE_COMMAND`.
The optional POSIX lane configures isolated XDG roots and `OPENCODE_CONFIG_DIR`,
checks setup plans, backups, preserved JSONC comments and idempotence, activates
the installed skill, validates all forwarded input schemas and verifies complete
JavaScript Evidence for a Unicode path. JSONC is the default fixture; set
`REA_VERIFY_OPENCODE_CONFIG_FORMAT=json` for JSON. Use `-- chat` for ordinary
chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The native core runs with external plugins disabled through `OPENCODE_PURE`;
the local OpenAI-compatible fixture has a caller-declared one-million-token
context and synthetic usage. Skills use an explicit isolated `skills.paths`
directory, so default OS-home discovery remains unverified. Live model APIs and
native Windows are also unverified.
`verify:claude-client` requires installed Claude Code (verified with
`@anthropic-ai/claude-code@2.1.296`); select it with `REA_VERIFY_CLAUDE_COMMAND`.
The optional POSIX lane uses native `CLAUDE_CONFIG_DIR` discovery, an independent
Git workspace, user settings and default built-in tools. It preserves caller
preferences and backups, checks idempotent setup, waits through the native
`WaitForMcpServers` tool when discovery is pending, and validates the complete
catalog and forwarded input schemas. Call mode loads the personal skill through
native `Skill`, checks its full body and verifies named-schema JavaScript Evidence
for a Unicode path. Use `-- chat` for ordinary chat with REA enabled, or
`REA_VERIFY_RUNTIME_ROOT` for a production-only installed package. The local
Anthropic Messages/SSE fixture preserves native resource-hint envelopes in its
request artifacts. Usage is synthetic; live Anthropic API, native Windows and
bare-mode personal-skill activation remain unverified by this lane.
`verify:copilot-client` requires installed GitHub Copilot CLI (verified with
`@github/copilot@1.0.95`); select it with `REA_VERIFY_COPILOT_COMMAND`.
The optional POSIX lane uses native `COPILOT_HOME` discovery, an independent
Git workspace, guarded setup plans, preserved registrations, backups and
idempotence. Native `skill add` registers the isolated installed skill; call
mode loads its full body, validates all forwarded input schemas and checks
named-schema JavaScript Evidence for a Unicode path. When Copilot spills a
large MCP result, the model requests native `view` with `forceReadLargeFiles`
and validates the complete returned Evidence rather than its preview.
Use `-- chat` for ordinary
chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The native offline BYOK adapter uses a loopback OpenAI completions/SSE fixture
and `gpt-5.4` model metadata; model inference and token usage are synthetic.
Set `REA_VERIFY_COPILOT_MODEL` to examine another client model ID and
`REA_VERIFY_COPILOT_WIRE_MODEL` for its backend model name (defaults to the client
ID). Every actual HTTP request's model is checked and recorded separately.
Both `HOME` and `USERPROFILE` point to the disposable account; native `skill add`
still selects the installed skill directory explicitly.
The same native client passed full-profile chat and analysis with the actual
wire model `gpt-4.1` under a distinct BYOK model ID:
```bash
REA_VERIFY_COPILOT_MODEL=rea-gpt-4.1 REA_VERIFY_COPILOT_WIRE_MODEL=gpt-4.1 npm run verify:copilot-client -- chat
REA_VERIFY_COPILOT_MODEL=rea-gpt-4.1 REA_VERIFY_COPILOT_WIRE_MODEL=gpt-4.1 npm run verify:copilot-client -- call
```
These runs retain full canonical input/output schemas, all tools, installed-skill
loading and complete Evidence readback. They use the fixture's requested
one-million-token BYOK prompt setting; effective capacity and live API acceptance
remain unknown. With the built-in `gpt-4.1` model ID, the verified client still
blocks the full input-schema profile before HTTP with
`compaction_static_context_blocked`, even when requesting a larger BYOK prompt
capacity. The effective capacity is unknown. The default verifier preserves
the complete catalog and full schemas. To verify the existing compact profile:
```bash
REA_VERIFY_COPILOT_MODEL=gpt-4.1 REA_VERIFY_COPILOT_SCHEMA_PROFILE=compact npm run verify:copilot-client -- chat
REA_VERIFY_COPILOT_MODEL=gpt-4.1 REA_VERIFY_COPILOT_SCHEMA_PROFILE=compact npm run verify:copilot-client -- call
```
Both native workflows passed with the complete tool inventory. The verifier selects the
profile only in its disposable Copilot registration and records it in the
receipt. Compact advertisements can reduce nested validation structure; the
server still validates complete canonical inputs. This is a tested alternate
workflow, not a fix for the full-profile client/model limit tracked in #1554.
Live model APIs, native Windows and default OS-home skill discovery remain
unverified.
`verify:grok-client` requires installed Grok Build (verified with the official
Linux x64 1.0.50 binary); select it with `REA_VERIFY_GROK_COMMAND`. This optional
POSIX lane isolates `GROK_HOME`, an independent Git workspace and additional
skill roots, disables foreign configuration discovery, guards setup writes,
preserves unrelated registrations/backups and checks idempotence. Call mode
loads the full skill through native `read_file`, queries all REA names and input
schemas through native `search_tool`, and calls analysis through `use_tool`.
If discovery reports `partial`, the native agent diagnoses REA registration and
retries discovery. No startup-timeout override or fixed readiness delay is used.
A larger Unicode-path fixture exercises native result offloading: the full
retained Evidence is validated against its named schema, then native terminal
queries recover the selected export facts, subject and full artifact digest in
the next model request. This verifies useful artifact recovery without claiming
that every offloaded graph fact enters model context. Native line-number and
truncation envelopes remain in the request artifacts. Use `-- chat` for ordinary
chat, or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The loopback OpenAI completions/SSE custom model declares a one-million-token
context and synthetic usage. Live xAI APIs, native Windows and default OS-home
skill discovery remain unverified.
`verify:commandcode-client` requires installed Command Code (verified with npm
1.79.2); select it with `REA_VERIFY_COMMANDCODE_COMMAND`. Auth, MCP tokens and
sessions use the actual OS home, so provision a disposable POSIX account rather
than overriding `HOME`. Set `REA_VERIFY_COMMANDCODE_ACCOUNT_HOME` to that account's
actual home and create `.rea-client-verification` there with exactly
`Disposable REA client verification account` followed by a newline. The lane
owns that account's `.commandcode` configuration and shared REA skill. Build the
runtime as the checkout owner, then run `node scripts/verify-commandcode-client.mjs`
as the disposable account; the npm shortcut also needs a writable checkout.
The verifier does not create accounts or install clients. It guards setup
targets, preserves an unrelated registration and backups, checks idempotence,
and verifies native default shared-skill discovery and complete activation.
Default deferred-schema delivery stays enabled: the native prompt advertises
every REA tool, exact-name `search_tools` returns every input schema, and a native
shell query recovers the saved catalog's count and digest when the client spills
it. Actual analysis of a Unicode-path fixture delivers full named-schema Evidence
to the next model request. Use `-- chat` for ordinary chat or
`REA_VERIFY_RUNTIME_ROOT` for a production-only installed package. The loopback
OpenAI completions/SSE model is a keyless BYOK endpoint declaring a million-token
context with synthetic usage. A synthetic account-key value satisfies the
client's print-mode gate; native local-only mode refuses hosted API calls.
Updates, telemetry and cron are disabled. Hosted authentication, live models
and Windows remain unverified.
`verify:omp-client` requires installed OMP (verified with the official Linux x64
18.8.7 binary); select it with `REA_VERIFY_OMP_COMMAND`. This optional POSIX lane
isolates the default agent, global config and XDG roots, guards setup targets,
preserves unrelated registrations and backups, and checks idempotence. It
compares native rejection of an invalid profile with REA's refusal to plan
fallback writes. OMP's default `xd://` interface mounts the complete REA catalog
as devices: call mode reads the complete installed skill and tool documentation,
then dispatches analysis through native `write`. It checks full named-schema
JavaScript Evidence with a Unicode path in the next model request. Device
metadata and documentation are distinct from forwarding all JSON schemas as
model functions. Native print-mode MCP readiness uses its defaults.
Use `-- chat` for ordinary chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only
installed package. The loopback OpenAI completions/SSE model fixture declares a
one-million-token context and synthetic usage. Live model APIs, native Windows,
named-profile native execution and default OS-home skill discovery are
unverified; skill discovery uses an explicit isolated custom directory.
`verify:deepseek-client` requires an installed DeepSeek Harness (`dsh`;
verified with `@deepseek-ai/dsh@0.2.0-rc.2`) and Git. Set
`REA_VERIFY_DEEPSEEK_COMMAND` to select its executable. This optional POSIX lane
installs the skill through `rea setup --skill`, writes the native Cordis MCP
patch into an isolated `DSH_HOME`, and binds `HOME` and `USERPROFILE` to the
disposable account. The native default `~/.agents/skills` search path discovers
the installed skill without a `DSH_AGENTS_HOME` override. A separate Git root prevents inherited project skills from
masking a missing installation. The default `call` mode checks skill loading,
complete catalog discovery, the actual forwarded input schemas and regexes,
and full JavaScript Evidence for a Unicode path. Use `-- chat` for ordinary
chat with REA enabled, or `REA_VERIFY_RUNTIME_ROOT` for an installed package.
The fixture uses Harness's custom OpenAI adapter and the one-million-token
context capacity declared by its default DeepSeek Flash model; it does not
establish live DeepSeek API or native Windows coverage. Receipts include
request artifacts, result digests and owned-process lineage.
Full E2E tests invoke the production command dispatcher and real providers,
without fake launchers, runners or responses. `verify:keyed-archive` writes an
actual Foundation binary archive, runs the CLI and a separate stdio MCP
@@ -151,29 +304,6 @@ an empty versioned scan or a suffix that only repeats the original path.
It runs in macOS CI.
Apple artifact verifiers live in `scripts/verify/apple/`, with the macOS bundle
builder under `scripts/fixtures/apple/` and NIB byte fixtures beside the decoder
in `src/artifacts/apple/`. The npm entrypoints are unchanged. Format-specific
Swift/XIB/asset sources and goldens retain their locations; real Apple workflows
resolve them from the verifier file URL and run in the macOS CI lane.
Portable native semantics and their tests live in `src/domain/native/`; shared
analyst workflows and service-lane tests live in `src/application/native/`.
Named native contracts live in `src/contracts/native/`. Provider protocol and
host UI tests retain their adapter/boundary lanes, and real verifier command
names remain unchanged.
The existing Apple CI job also runs the host Swift-demangling CLI/MCP regression
suites, including option-like symbols, carriage returns and multiline rejection.
Process semantics/tests live in `src/domain/process/`; PTY capture implementation
and forked helper tests live in `src/process/capture/`. Evidence projection and
file workflows live in `src/application/process/`; producer-backed Evidence/host
cases run in the serial `tests/boundary/process/` lane. Installed-package probes
load the compiled capture capability owner, including the missing-optional-module
case. Real capture tests preserve actual descendant and cleanup checks.
The existing Apple job also exercises the relocated filesystem snapshot identity,
cancellation and descriptor cleanup regressions on macOS.
Prepare the native inspector before cases that measure producer output or exit
behavior; keep startup deadlines and cancellation in distinct cases. Run real
process-capture verification separately from package or build checks. On macOS,
@@ -184,8 +314,7 @@ MCP SDK transport tests with recording providers remain integration tests.
They are useful for schema drift and failure projection but do not prove that
Hopper, Ghidra or another substituted engine works. `verify:package` proves
packaging/install behavior and fake-provider integration; use the corresponding
real-provider lanes for engine claims. Packed-bridge checks verify shipped files
and Python syntax without deleted mock fixtures or source-spelling assertions.
real-provider lanes for engine claims. Packed-bridge checks verify shipped files and Python syntax.
Real Apple dispatch and Interface
Builder verifiers currently prove format integration through production readers.
@@ -230,7 +359,12 @@ subsequent wire recovery and clean shutdown. Caller timeout does not interrupt
Hopper's synchronous native operation. Socket boundary tests deterministically
cover active and queued expiry, late replies and timer cleanup.
The Linux demo lane remains a separate `verify:hopper:linux` command.
The Linux demo lane remains a separate `verify:hopper:linux` command. Its
lifecycle checks attempt competing CLI launches for the active target and a
different target, requiring rejection before either can change the owning
MCP session's documents or procedures. Lease boundary tests also preserve
unresponsive or malformed live endpoints while allowing confirmed stale
sockets to recover.
`verify:hopper:fat` is a separate macOS lane requiring installed Hopper and the
existing Xcode clang/lipo toolchain. It compiles arm64/x86-64 thin executables and
@@ -255,13 +389,24 @@ Do not call handcrafted utility output or synthetic binary builders real-data
goldens. Keep unsupported binary layouts and malformed boundaries as targeted
regressions until a real fixture establishes equivalent coverage.
`verify:browser` exercises source-map failure isolation and expanded-output limits through the compiled CLI and stdio MCP with real Chrome. It also submits five 2 MiB source-map annotations, checks retained script identities and explicit map omissions, and closes its owned fixture target. These public workflows replace redundant metadata-admission assertions; replacement and document-reset boundaries remain focused producer regressions.
`verify:browser` exercises source-map failure isolation and expanded-output limits through the compiled CLI and stdio MCP with real Chrome. It also submits five 2 MiB source-map annotations, checks retained script identities and explicit map omissions, and closes its owned fixture target. Replacement and document-reset behavior has separate producer-boundary coverage.
The raw Chrome fixture launchers use `--password-store=basic` so Linux startup
does not wait for an unlock prompt from a reachable but locked desktop keyring.
Such a stall leaves the initial page unloaded with empty or placeholder CDP URLs;
it does not establish permission to capture that page. See
[the keyring diagnosis](https://github.com/morluto/rea/issues/1384#issuecomment-6093781686).
`verify:browser` also captures a source-owned noise canvas as a real PNG above
8 MiB through the CLI and stdio MCP, with complete byte/digest parity and real PNG
decoding. Its SDK client explicitly permits the larger inline JSON response;
this lane does not establish large image-comparison request transport coverage.
The scenario checks read locale, timezone, device scale and viewport dimensions
from actual page JavaScript through CLI and stdio MCP DOM captures. They also
verify that attached-page emulation is released after success, initialization
failure, action failure and cancellation while the external target stays open.
`verify:browser:network` is a focused real-browser lane for transaction identity,
selected request/response bytes, binary and compressed responses, duplicate
headers, credential and declared-secret redaction, redirects, streaming cutoff,
@@ -305,13 +450,21 @@ installation (`application.java.min` through `application.java.max`). Current
12.1 releases require JDK 21 or newer and set no maximum. The lanes below still
prove behavior on the verified Ghidra 12.1.4 and JDK 21 build.
| Ghidra lane | Supported runner/target | Additional local tools |
| ------------------------------------------ | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `npm run verify:ghidra` | Linux x64/arm64 ELF or macOS x64/arm64 Mach-O | Host C compiler, Ghidra 12.1.4, and full JDK 21 |
| `npm run verify:ghidra:switch` | Linux x64 ELF; GCC/Clang optimized and stripped switch fixtures | GCC, Clang, GNU nm/objdump/strip, Ghidra 12.1.4, and full JDK 21 |
| `npm run verify:ghidra:aarch64-jump-table` | Any supported Ghidra host; AArch64 ELF; byte/halfword tables; host ARM64 Mach-O | Clang with AArch64 target support, Ghidra 12.1.4, and full JDK 21 |
| `npm run verify:ghidra:cross-format` | Any supported Ghidra host; also analyzes AArch64 ELF, x86-64 PE, and x86-64 Mach-O | `clang`, LLD, and `lld-link` in addition to host-lane prerequisites |
| `npm run verify:ghidra:windows` | Controlled Windows x64 with native x86-64 PE; `-- --x86` selects native x86 PE | Ghidra 12.1.4, full JDK 21, and the matching native artifact |
| Ghidra lane | Supported runner/target | Additional local tools |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `npm run verify:ghidra` | Linux x64/arm64 ELF or macOS x64/arm64 Mach-O | Host C compiler, Ghidra 12.1.4, and full JDK 21 |
| `npm run verify:ghidra:seeds` | POSIX host; source-owned 32-bit x86 raw fixture; function order and BSS labels | Ghidra 12.1.4 and full JDK 21 |
| `npm run verify:ghidra:swift` | macOS x64/arm64 Mach-O | Host Swift compiler, Ghidra 12.1.4, and full JDK 21 |
| `npm run verify:ghidra:switch` | Linux x64 ELF; GCC/Clang optimized and stripped switch fixtures | GCC, Clang, GNU nm/objdump/strip, Ghidra 12.1.4, and full JDK 21 |
| `npm run verify:ghidra:aarch64-jump-table` | Any supported Ghidra host; AArch64 ELF; signed/unsigned byte/halfword tables; host ARM64 Mach-O | Clang with AArch64 target support, Ghidra 12.1.4, and full JDK 21 |
| `npm run verify:ghidra:cross-format` | Any supported Ghidra host; also analyzes AArch64 ELF, x86-64 PE, and x86-64 Mach-O | `clang`, LLD, and `lld-link` in addition to host-lane prerequisites |
| `npm run verify:ghidra:windows` | Controlled Windows x64 with native x86-64 PE; `-- --x86` selects native x86 PE | Ghidra 12.1.4, full JDK 21, and the matching native artifact |
The optional Swift lane compiles a source-owned fixture and checks modern and
provider-demangled procedure names through real stdio MCP, with and without the
dSYM companion. It checks unfiltered, structs, and literal-name filters,
same-address alias evidence, deduplication, and explicit unresolved categories.
It does not add a Swift prerequisite to the host C fixture lane.
The host lane also verifies namespaced C++ ABI symbols and annotation identity.
That facet requires Ghidra's matching `demangler_gnu_v2_41` native component in
@@ -368,9 +521,7 @@ Instruction inspection and containing-function lookup also agree across
hexadecimal case, leading zeros, and encoded default address-space spellings.
The same source-acquisition workflow exercises missing and directory-replaced
inputs, plus real read-permission denial on a non-root host. Root runs report
that permission-denial check as unverified. A focused filesystem integration
check retains selected-platform routing and exclusive creation; two copy/digest
checks duplicated by the real workflow have been removed.
that permission-denial check as unverified. Filesystem integration separately checks selected-platform routing and exclusive creation.
Namespace annotation probes compile a separate host C fixture with C++ ABI
symbols, avoiding a C++ runtime prerequisite. Real Ghidra demangling supplies
duplicate leaf names in two top-level namespaces and a nested namespace. The
@@ -385,8 +536,7 @@ Successful-result and oversized-error delivery constraints must identify their
successfully retained Evidence records;
export must recover every source byte, complete annotation and original error
diagnostic, with CLI parity
and an unchanged executable. The focused formatter check retains only the
separate case where recording was not acknowledged.
and an unchanged executable. Formatter integration separately checks unacknowledged Evidence recording.
Long ordinary procedure names and encoded address-space selectors must produce
normal validation errors without exhausting Java's regex stack or losing the
private bridge connection. Each rejection is followed by a real provider lookup;
@@ -426,17 +576,19 @@ the CLI and stdio MCP, including special filenames, unresolved discovery
locations, and independently resolved loaded scripts. Double-quote filenames
are tested on POSIX only because Windows does not support them.
Inspector adapters live in `src/inspector/`, with loopback fixtures under
`tests/fixtures/inspector/` and forked producer boundaries under
`tests/boundary/inspector/`. The real lane is owned by
`scripts/verify/inspector/runtime-observation.mjs` and
`tests/conformance/inspector/`. Browser and Inspector deliberately share the
existing browser CDP transport/value and file-location helpers. Node fixture
success proves this Inspector workflow on the tested host; it does not prove
Electron GUI behavior or another engine.
Node Inspector verification does not establish Electron GUI or other engine
behavior. Browser and Inspector share CDP transport/value and file-location
helpers; their producer workflows remain distinct.
## Android APK analysis
The real Android lane also runs on Windows x64 with its matching bundled native
controls. It verifies bidirectional protocol input, CLI/MCP result parity,
real MCP cancellation/disconnect and Java exit after abrupt CLI owner
termination. The forced Windows exit does not exercise the POSIX SIGTERM
handler and can leave temporary workspace files. `verify:windows-native`
separately checks binary input, backpressure, EOF and pending-write job closure.
`npm run verify:android` requires an existing Java 17+ and an explicit
`REA_JADX_MCP_JAR` for jadx-headless-mcp 0.7.1. Set `REA_ANDROID_TEST_APK` to the
fixed public ApiDemos v6.0.18 fixture. Obtain both with the explicit
@@ -445,25 +597,88 @@ kept under ignored `_reference/`. No Gradle build, Android SDK, emulator or
application execution is required. The lane compares real CLI/MCP package,
class search, class inventory, method decompilation and incoming references.
See [Android analysis](android-analysis.md) for boundaries and resource budgets.
`verify:jeb` requires a caller-started JEB client serving MCP at
`REA_JEB_MCP_URL` (default `http://127.0.0.1:8425/mcp`) with a project
already open, and verifies real CLI client inspection, unit listing coverage,
and method decompilation. The script records the engine's exact response to
`open_jeb_project`; JEB 5.48.0 headless instances do not advertise that tool.
REA does not install or launch JEB; see [JEB analysis](jeb-analysis.md) for
the bring-your-own boundary. Verified against JEB 5.48.0 serving
`jeb-mcp-server` 1.3.0 at four scales: a compiled Java class fixture, a
locally built signed probe APK with a launcher activity (manifest, v1/v2/v3
certificates, dex bytecode, filtered and paginated listing), the published
Signal 8.30.3 universal release APK (109 MB, R8-processed Kotlin/Compose,
four signature schemes, native arm64 ELF units) with MainActivity method
decompilation through both CLI and MCP, and the official Flutter Gallery
2.9.2 release APK (112 MB): per-ABI `libapp.so` Dart AOT snapshot images
analyzed as native code (75k methods on arm64) and decompiled through both
CLI and MCP with explicit unit selection, plus the thin Java wrapper and
decoded manifest. The dedicated Dart snapshot processor and `run_script`
remain GUI-only surfaces in JEB 5.48.0 headless.
Authenticated IPA and macOS application inventory projection is documented in
[Apple application analysis](apple-application-analysis.md).
The lane and owned-process cancellation helper live in `scripts/verify/android/`.
The explicit downloader and fixed manifest live in `scripts/fixtures/android/`;
their default remains repository-root `_reference/apk-integration/`. Producer
fixtures live in `tests/fixtures/android/`, boundary cases in
`tests/boundary/android/`, and inventory projection composition cases in
`tests/composition/android/`. Real engine success and synthetic protocol success
are separate proof levels.
Synthetic producer regressions run independently:
```sh
npm run test:focused -- tests/boundary/process/jadxIntegration.test.ts tests/boundary/process/androidAnalysisMcp.test.ts
```
## Apktool resource decoding
`npm run verify:apktool -- --apk PATH` exercises both Apktool operations
against a real launcher (`REA_APKTOOL_COMMAND` or PATH) and one APK. No
download or build step is involved. Record: apktool 2.7.0-dirty (Debian
packaging) on Linux with OpenJDK 25, against a signed aapt2-built probe APK
carrying two resource locales — launcher version, on-disk digest agreement
with the reported target identity, apktool.yml metadata projection
(1.2.3, SDK 24–34), manifest package agreement, and both the default and
`de` string tables projected through the locale option. Parser goldens in
`src/apktool/ApktoolDecodeOutput.test.ts` come from the same decode. See
[Apktool resource analysis](apktool-resource-analysis.md) for boundaries and
budgets.
## ADB device acquisition
`npm run verify:adb` exercises every ADB operation against a live device or
emulator through the caller's adb binary (`REA_ADB_PATH` or PATH). No SDK
installation or emulator management is involved; the device-mutating tools
run only in the explicit lifecycle section (`--install-apk` drives a
lane-owned install → resolve → start → observe → force-stop → uninstall
probe). `--pull` acquires a real package and re-digests the pulled files on
disk against the returned SHA-256 values; `--serial` selects a device when
several are attached.
Record: adb 34.0.5-debian on Linux against an Android 14 (API 34) x86_64
emulator. The lane covered the complete observation surface — 337-process
listing, 287 binder services including AIDL `/`-suffixed names, 92 features
including hex GL versions, display size/density, window focus (legitimately
null on headless devices), `settings get global adb_enabled`, bounded
logcat, directory listings — plus a real two-APK split set
(`base.apk` plus `split_probe.apk`, built and installed through
`install-multiple`) pulled with byte-exact digests, a push/pull roundtrip
verified by the device's own sha256sum, a 1.3 MB screen capture with PNG
dimensions, `dumpsys package` projection, and the full lifecycle: unique
resolution before launch, launcher-activity start through
`cmd package resolve-activity` with `am start -W`, the started app visible
in the process listing, force-stop, uninstall, and zero matches after
removal. System-package pulls whose APKs keep non-`base.apk` names report
the `unknown` role with the file-name basis, verified with
`com.android.settings` (single 73.9 MB APK). Parser goldens for
`adb devices -l`, `getprop`, `pm list packages -f`, and `pm path` come from
the same device. See [ADB device analysis](adb-device-analysis.md) for
boundaries and budgets.
## Optional NativeAOT Ghidra analysis
The source parser lane is independent of the optional annotation JAR. Its
synthetic RTR 9.1 PE golden checks captured-byte digest admission, rehydration
into an immutable parser overlay, MethodTable/slot relationships, and frozen
literal extraction; provider tests exercise `inspect_native_load_image` and
address-based `inspect_native_data_type` with the database result still
unavailable. These tests do not establish Windows Ghidra host behavior.
This lane is separate from the default native lane. `build:fixtures:nativeaot`
requires an existing .NET SDK 8.0.416, the platform NativeAOT compiler/linker and
runtime pack 8.0.22. It builds benign sources into ignored `_reference/` and
@@ -560,6 +775,42 @@ not make native host acceptance unavailable.
## Native platform baseline in CI
Pull requests that change only root `README*.md` files, `docs/`, `AGENTS.md`,
or `CONTRIBUTING.md` run formatting and generated-document validation without
the source-test shards or native package lanes. Classification compares the PR
head with its merge base, so later base-branch changes do not expand that scope.
Static and coverage aggregate jobs remain present and fail if classification
fails. Every code change retains the complete four-shard Linux suite; individual
test files are not selected by imports or filenames.
`scripts/ci/plan.mjs` selects lanes using the ownership table in
`scripts/ci/scopes.mjs`. Provider implementation changes run their real-provider
verifiers and the Linux x64 installed-package/Inspector baseline. Test-only
changes run the Linux suite without native package verification. Website changes
run website checks. Provider workflow changes validate the workflow and run that provider's verifier.
Manual-provider/Android workflow changes run workflow validation only.
Shared process/contract/CLI boundaries, dependencies, packaging inputs, unknown
paths, and changes to the planner select the full baseline. Package script-only
edits select their owning verifier when its entrypoint is identifiable; unknown
or shared script changes select everything. Android build-script edits retain
the Linux suite and workflow validation; real Android verification stays manual.
Renames account for both paths.
Main pushes and manual dispatch retain the full baseline, including all portable
provider lanes and the native matrix below. A `ci:full` PR label selects the full
baseline on the next PR run; manual dispatch can request it immediately. Each
classification job records its selection and broad-fallback reasons in the run
summary. Representative Git-diff cases live in
`tests/boundary/filesystem/ciChangeScope.test.ts`.
`CI required` checks classification and every selected lane, rejecting failed,
cancelled, or unexpectedly skipped work. Existing required check names are
preserved; changing branch protection to require the new aggregate is a separate
repository-settings operation. Newer commits cancel superseded CI for the same
PR or main branch. Release publication has its own concurrency group and retains
its package verification and public-registry canary. Licensed/self-hosted
provider workflows and the Android smoke test retain their explicit triggers.
CI exercises the pinned Node.js runtime on native hosted runners:
| Host | Runner | Baseline checks |
@@ -570,23 +821,48 @@ CI exercises the pinned Node.js runtime on native hosted runners:
| macOS 15 x64 | `macos-15-intel` | Installed package and real Node Inspector CLI/MCP |
| Windows x64 | `windows-latest` | Curated capabilities, native controls, installed package and real Node Inspector CLI/MCP |
Package and Inspector matrices assert the actual Node platform/architecture
before verification and record those values with the Node version. Each matrix
Package lanes assert the actual Node platform/architecture before verification
and record those values with the Node version. The four-host package matrix
runs at most two jobs concurrently with explicit timeouts and Node heap/thread
limits. Package checks cover installation, CLI/MCP discovery, target-free
limits; Windows retains its curated capability lane. Package checks cover
installation, CLI/MCP discovery, target-free
analysis, configuration backups/recovery, Evidence and owned lifecycle; Inspector
checks execute source-owned loopback targets and special filename cases.
macOS uses one OS version with one native baseline job per architecture. Each job
runs package and Inspector checks after a single dependency installation. The
separate Inspector matrix covers Linux and Windows; Apple artifact checks retain
their own macOS 15 arm64 job for Xcode-dependent workflows.
These native baseline checks complement the Linux source-test shards and the
separate Apple-artifact and real-provider lanes. Actual Hopper, Ghidra, IDA,
browser and managed-tool claims require their corresponding verification lanes.
Runner labels follow the [GitHub hosted-runner reference](https://docs.github.com/en/actions/reference/runners/github-hosted-runners).
### Termux Android browser smoke test
The **Real Termux browser verification** workflow is manual-only while its
emulator setup is being validated. After the workflow reaches the default
branch, select a revision under **Actions → Real Termux browser verification →
Run workflow**. It boots an Android 11 (API 30) x86_64 emulator, installs the
checksum-verified Termux 0.118.3 APK, and lets the app initialize its bootstrap.
The host stages the selected revision using `git archive HEAD`; no workstation
build outputs or dependencies are copied into Android.
`scripts/verify/termux/emulator.sh` sends a `RUN_COMMAND` intent to Termux's app
service. Root access is limited to staging files, sending the intent, and reading
diagnostics; installation, compilation, Node, and Chromium run as Termux's app
UID. The in-app script installs Termux's Android-linked Node distribution,
checks its version against `.nvmrc`, pins npm from `packageManager`, runs
`npm ci`, and builds with `build:termux`. Termux repository packages, including
Chromium, are resolved at run time; their installed versions are logged.
The verifier leaves Playwright's cache environment overrides unset, requires
a healthy public MCP doctor result, and captures URL plus DOM from a loopback
HTTP fixture through `capture-browser-scenario`. It checks completed steps,
the exact URL, a DOM marker, and reported browser cleanup. This lane covers one
Android emulator and Termux combination, not physical ARM devices, Electron,
or the complete desktop browser suite. A workflow definition alone does not
establish passing Android coverage; inspect its execution receipt.
The `termux-browser-diagnostics` artifact retains the Termux command log, exit
status, and Android logcat on success or failure. The emulator is disposable.
## Developer commands
Use source feedback while editing, explicit boundary checks for the changed
@@ -626,6 +902,17 @@ The dry-run option reports the chosen merge base, scope and build prerequisite
without executing tests or building. A missing Git base reports how to fetch
it or select another revision.
Source typechecking needs no compiled runtime or generated test metadata.
`npm run build:cached` compiles the CLI/MCP runtime and its packaged skill.
`npm run test:prepare` also generates the MCP contract test catalog, product
catalog, and portable managed evidence used by the complete suite. Focused
tests prepare those extra outputs only when their selected files consume them.
The MCP test catalog is JSON in `.cache/mcp-tool-catalog.json`; the tracked
test loader supplies its types without making generation a source-check
prerequisite. Run `npm run mcp-catalog:generate` to refresh it independently.
Documentation generation and managed conformance run through their separate
`docs:generate` and `evidence:generate` task graphs.
Changed selection can miss runtime registration, generated data, shell
entrypoints, bridges, or other relationships absent from the import graph.
An empty changed selection means no tests were selected, not verified
@@ -640,23 +927,15 @@ broad changes or diagnosing CI, rather than after every edit. Package/install
changes additionally need package verification; provider changes need actual
provider evidence.
Each Vitest project uses up to two workers, bounded by available host parallelism.
Default-group projects can run together. Only `process-boundary` runs in the
later sequence group and serializes its files because process-tree observations
share host sampling resources. Tests that launch the real process harness belong
in `tests/boundary/process/`, including CLI command and environment tests.
Acceptance and process-global files retain isolated
forks but are not serialized; isolation does not imply serial scheduling. CI uses
the same per-project worker bound.
The pure domain/contracts and recording-port service projects share one worker
module context because their tests own no mutable runtime resources. MCP
boundary files also share the immutable server module graph while creating and
closing independent in-memory sessions. Adapter, composition, acceptance,
process-global, and other boundary projects retain per-file isolation.
Build and documentation writers use checkout-local locks for their respective
output files. `npm test` delegates its build to the build lock; the Vitest suite
does not hold a test-command lock. `check:pr` runs its test task before starting
generated-document validation.
Vitest projects use up to two workers, bounded by host parallelism.
`process-boundary` runs later with serial files because process-tree sampling
shares host resources. Acceptance and process-global cases use isolated forks
without serial scheduling. Pure domain/service and MCP boundary projects share
immutable module graphs; each MCP session still owns its resources. Other
projects retain per-file isolation. See `vitest.config.ts` for current settings.
Build/documentation writers hold checkout-local output locks. Tests do not
hold a broad command lock; `check:pr` finishes tests before document validation.
Vitest and Node persistent compile caches are deliberately not enabled by
default. To evaluate repeated local runs, opt in for both cold and warm
@@ -672,13 +951,9 @@ instrumentation remains equivalent.
## Coverage and timing
CI owns coverage. The aggregate floors are 65% statements, 60% branches, 60%
functions, and 68% lines. `src/domain/**` must reach 80% statements, 75%
branches, 75% functions, and 80% lines. `src/contracts/**` must reach 85%
statements, 80% branches, 80% functions, and 85% lines. Thresholds are
glob-specific rather than per-file and are never updated automatically.
Coverage does not replace named boundary, acceptance, or real-provider scenario
matrices.
CI owns coverage; aggregate and domain/contract thresholds are maintained in
`vitest.config.ts`. They are glob-specific and never updated automatically.
Coverage does not replace named boundary or real-provider scenarios.
CI runs four native Vitest shards without retries. Each shard emits a blob
report; the merge job produces aggregate coverage plus JUnit and JSON timing
@@ -752,22 +1027,18 @@ unknown chunks, depth limits and extracted child digests. The optional
Neither optional toolchain is a base-lane prerequisite. See
[firmware analysis](firmware-analysis.md) for limits and unverified formats.
The real entrypoint is `scripts/verify/firmware/analysis.mjs`; the fixture runner
and unchanged Python producer belong together in `scripts/fixtures/firmware/`.
Producer fixtures and boundaries remain in `tests/fixtures/firmware/` and
`tests/boundary/firmware/`. Source-fixture generation proves the runner and
independent oracle; actual Binwalk/Unblob CLI/MCP proof requires selected tools.
### JavaScript source recovery
Build once with `npm run build:cached`, then run `npm run verify:javascript:recovery`.
This focused lane requires Linux x64, util-linux `prlimit`,
`REA_WAKARU_COMMAND` pointing to the official Wakaru 1.13.0 Linux x64 binary,
`REA_WAKARU_COMMAND` pointing to the official Wakaru 1.14.0 Linux x64 binary,
and `REA_JAVASCRIPT_FIXTURE_TOOLS` pointing to an isolated npm prefix containing
esbuild 0.25.10 and webpack 5.101.3. No global installation is required.
The lane compiles source-owned fixtures, exercises CLI and stdio MCP, verifies
published bytes and provenance, feeds recovered modules into existing analysis,
and compares a finite set of known fixture results. It does not establish
and compares a finite set of known fixture results. The provider also accepts
other ^1.13.0 releases and reports them as unverified; this lane proves the
audited release. It does not establish
arbitrary recovered-application equivalence. CI installs these prerequisites only
in `.github/workflows/real-javascript-recovery.yml`; the existing `real-browser`
lane uses real Chrome for browser capture and website workflows.
@@ -880,8 +1151,97 @@ real local Codex CLI with:
npm run verify:agent
```
Its report records tool selection, repeated calls, token use, completion quality,
and handling of permissions and unknowns.
The lane runs scenarios sequentially in standalone Codex (`--no-daemon`) with a
disposable HOME and CODEX_HOME under `~/.cache/rea-agent-evaluations/`. Set
`REA_AGENT_EVAL_ROOT` to choose another parent directory outside the OS temporary
directory: current Codex refuses helper aliases under `/tmp`, preventing shell
commands and skill reads even if MCP works. Each owned run directory is removed
after verification unless fixture retention is requested. The lane
installs the packaged skill and MCP registration through public `rea setup`,
rather than copying a skill into a project that also inherits the caller's
skills and configuration. Only authentication is copied, when present, and it
is removed even with `REA_AGENT_EVAL_KEEP_FIXTURES=true`. No user configuration,
rules, plugins or history is copied; shell snapshots and additional agents are
disabled. Existing API-key environment authentication remains available.
The native missing-provider scenario preapproves only `open_binary` and
`close_binary` in the disposable client so it reaches REA's actual provider
boundary instead of stopping at Codex approval. This does not validate a real
native engine or authorize arbitrary runtime execution.
Select a smaller run with `REA_AGENT_EVAL_SCENARIOS`, a comma-separated list of
scenario IDs. `asar-zh` exercises the packaged desktop rubric from a Chinese
request. `javascript-module-view` exercises summary analysis, module paging and
item inspection in a tree with unrelated modules; its routing and text checks
remain heuristic, so review the retained transcript for selector choice and
coverage claims. Set `REA_CODEX_CLI` to an installed Codex executable and
`REA_AGENT_EVAL_MODEL` to an account-supported model. Use an external resource
limit for the whole process tree when testing on a constrained host; a Node
heap limit alone does not bound client and child-process memory.
`missing-target` leaves desktop fixtures visible without selecting one in the
request. It requires zero REA calls and a structured request for an app name or
artifact path. Its `expectedFirstTool` is `null`, and
`targetClarificationPassed` grades that limited routing outcome independently
of analysis prose heuristics. Analyzing a nearby example cannot pass this case.
The packaged desktop and parser-comparison scenarios now assess a closed set of
known fixture claims. Each final answer must be a strict JSON manifest containing
exactly the requested claim IDs, values, Evidence IDs, and Evidence authority and
confidence. Golden values are not included in the prompt. The evaluator checks
exact values against both the fixture oracle and authenticated successful REA
results; an Evidence ID by itself is insufficient. Missing, duplicate, extra,
contradictory, incorrectly sourced, or unsupported claims fail the scenario.
The desktop rubric covers the exposed bridge API and members, renderer and main
IPC operations, and the resolved preload. It binds its Evidence to the exact
packaged artifact path and SHA-256. The parser rubric checks the precise heading
depth addition, discriminant, complete comparison counts, and the explicit limit
on runtime semantics. Its comparison must link to the two delivered source
analyses and use the requested module and export selectors. Boundary tests package
the same source-owned desktop fixture and compare the same source-owned parser
files through actual MCP tool results, then verify that fabricated answers fail.
Per-scenario `factualCorrectness` is `passed`, `failed`, or `not_assessed` within
the `configured_fixture_claims` scope. A pass establishes only the configured
claims, not unrestricted factual correctness. Native, managed, browser,
navigation-context, and address-context scenarios have no factual rubric and
remain `not_assessed`; the managed workflow requires both artifact and member
inspection to answer its type and entry-point question.
The closed factual scenarios request complete producer Evidence on the initial
analysis so their source selectors can authenticate all configured facts.
Summary/page/item workflows are exercised separately by `javascript-module-view`;
its heuristic gate does not establish full-producer factual correctness.
All scenarios retain routing, workflow, validation, repetition, process-exit,
and token-use gates. Configured factual scenarios additionally require a factual
pass. Their answer-text heuristics are diagnostic and do not affect the gate.
Validation counts include complete text-only REA `invalid_request` envelopes
and failed SDK calls whose arguments violate the named current REA contract.
Client approval rejections and provider unavailability remain distinct failures;
truncated JSON previews are not parsed into invented error codes.
Repeated `binary_session` observations separated by a successful `open_binary`
or `close_binary` are treated as lifecycle verification. An unchanged retry,
including one after a failed lifecycle call, still counts as repetition.
Scenarios without a rubric retain the legacy text-heuristic gate.
`answerTermCoverageMet` checks case-insensitive substrings,
`epistemicCuePresent` checks keywords, and `finalCitesEvidence` checks only an ID's
presence. These metrics can still accept fabricated prose and must not be read
as factual assessments. Set `REA_AGENT_EVAL_TRANSCRIPT_DIR` to retain complete
tool results and final answers for review.
Report schema version 4 adds negative routing scenarios with nullable
`expectedFirstTool` and a `targetClarificationPassed` outcome. Consumers must
allow an expected absence of REA calls; this does not make an analysis scenario
pass without its required tools. Version 3 changed the top-level
`factualCorrectness` from a constant
string to an assessment summary with status, scope, and assessed/passed/failed/
not-assessed scenario counts. Scenario records include the factual assessment and
configured claim IDs. The evaluation scope is
`routing_workflow_and_configured_fixture_claims`. Update report consumers for
these changes. The narrower heuristic field names introduced in version 2 remain:
`answerHeuristicsMet`, `epistemicCuePresent`, `answerTermCoverageMet`, and
`requiredAnswerTermGroups`.
Regenerate the managed conformance manifest and Evidence completion ledger from
live verification results, or check them for drift:
+75 -94
View File
@@ -1,106 +1,87 @@
# MCP tool design
Design tools around analyst tasks. A provider API is an implementation detail;
expose it directly when it gives agents a useful, reusable capability that
cannot be expressed through an existing contract. Do not impose caller-facing
limits merely to make work fit an assumed agent budget. Keep real input-format,
protocol, authority, and resource-safety constraints, and report their effects.
## Choose the tool shape
| Shape | Use it for | Contract should return |
| --------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `inspect` | Facts about one explicit target, address, object, or resource | Relevant fields, source locations, and facet-level availability |
| `search` / `list` | Finding candidate targets or entities | Stable ordering and useful result context; expose pagination when the result format or caller's query needs it |
| `trace` | Relationships across code, metadata, UI resources, or observations | Typed edges, supporting evidence, and unresolved paths; identify any genuine traversal boundary |
| `compare` | Two explicitly identified artifacts, versions, or evidence sets | Paired identity, comparable coverage, and deltas with evidence |
| `workflow` | A distinct analyst outcome that benefits from composition inside REA | A useful inline result, contributing evidence, and partial/unavailable facets |
| `observe` / `capture` | A question that requires runtime behavior | Required authority, launch/attach behavior, real operational constraints, lifecycle, and cleanup status |
These are task shapes, not required prefixes. Name a tool for the action and
object agents reason about; keep the name distinct from nearby alternatives.
## Prefer primitives; compose workflows
Start with a primitive when one call can report a reusable fact about one
identified object or relationship, such as an instruction decode, a type
layout, a reference, a dispatch target, or a resource graph. The same primitive
should be useful across different applications or analyst questions. A
format-specific decoder can still be a primitive when it describes a reusable
format rather than one application's product behavior.
Add a workflow when repeated analysis shows that callers need the same
multi-source result and REA can join the evidence without hiding important
choices or uncertainty. A useful check is whether the workflow remains
meaningful for different applications that share the relevant evidence types.
If its purpose depends on one application's business rules or product concepts,
keep that interpretation outside the general tool contract and expose the
underlying evidence through reusable primitives.
## Decide whether to add a tool
1. State the user intent and the smallest result that answers it.
2. Inspect the canonical tool contracts, current provider capabilities, and
representative CLI/MCP traces. Record the nearest competing tool.
3. Extend an existing contract when the intent and result are the same. Add a
batch or composed workflow when it materially improves a demonstrated task;
do not force agents through extra calls or collapse distinct tasks into one
tool. Add a tool when it answers a distinct analyst question or has a
materially different authority or result contract.
4. Keep public tool names and result semantics provider-neutral. Put engine-
specific parsing and protocol handling in adapters. Advertise exact support
per provider; do not create parallel tools just because engines differ.
5. Keep prompts optional and concise. They may point out useful tools, but must
not prescribe a call sequence when the task can be answered directly.
Design around the analyst question. Inspect the current canonical contracts,
provider capabilities, and nearest existing tool before changing the surface.
Extend a tool when intent and result contract match; add one for a distinct
outcome or materially different authority. Public names and semantics remain
provider-neutral, with exact coverage reported per provider.
Avoid opaque mode flags and mega-tools that combine unrelated discovery,
execution, and mutation. Prefer a useful direct tool call over a tool sequence
or model-authored loop when one call can answer the question.
Keep the catalog complete; report capability/session availability instead of
truncating schemas. Serialized bytes alone do not establish agent usability.
## Choose the tool shape
| Shape | Use it for | Result |
| --------------------- | ------------------------------------------- | ------------------------------------------------------------------------- |
| `inspect` | Facts about one target, object, or resource | Relevant fields, locations, and facet availability |
| `search` / `list` | Candidate discovery | Stable ordering and context; pagination when the query or format needs it |
| `trace` | Relationships across evidence | Typed edges, supporting facts, and unresolved paths |
| `compare` | Explicitly paired artifacts or observations | Identity, comparable coverage, and supported deltas |
| `workflow` | A recurring outcome needing composition | Inline answer, contributing evidence, and partial facets |
| `observe` / `capture` | Runtime behavior | Authority, launch/attach effects, lifecycle, and cleanup status |
These are task shapes, not mandatory prefixes. Name tools for the action and
object callers reason about. Avoid unrelated discovery/execution/mutation modes
inside one tool.
## Prefer primitives; compose workflows
A primitive reports a reusable fact about an identified object or relationship.
A format-specific decoder qualifies; one application's business interpretation
belongs outside the general contract. Expose provider APIs when they add a
useful capability that existing tools cannot express.
Compose a workflow when repeated use demonstrates a multi-source outcome REA
can join without hiding caller choices or uncertainty. Batch homogeneous reads
when that removes repeated work while preserving per-item outcomes. Keep prompts
optional and avoid prescribing call sequences that a direct tool can replace.
Agents can compose experiments with ordinary commands, scripts, and local
fixture servers. Custom orchestration languages, replay engines, or separate
prepare/execute plans need an observed requirement those primitives cannot
satisfy. A plan without execution does not establish runtime behavior.
## Define the contract
- Use strict object inputs with explicit required fields and enums. Add numeric
bounds only when the format, protocol, authority, or a measured resource
constraint requires them.
- Return complete results by default. Make real pagination, truncation, partial
failure, cancellation, and unavailable states explicit. Missing evidence is
unknown, not empty or false.
- Return task-oriented results inline with artifact identity, provider/version,
addresses or resource paths, Evidence references, confidence, and relevant
limitations. Do not require agents to fetch a resource or dereference an
opaque Evidence link to understand a tool result.
- Separate observed facts from derived and inferred edges. Cite the evidence
supporting every important relationship; preserve unresolved edges.
- Declare read-only, mutation, process, filesystem, network, and UI effects
truthfully in the contract and enforce the target and lifecycle named in the
request.
- Keep provider-specific types out of provider-neutral domain and application
layers. Normalize supported provider results without implying equal coverage.
- Use strict inputs with explicit target identity and required fields. Preserve
meaningful target, action, capture, and output choices; remove ignored options
and repeated permission declarations.
- Return complete evidence inline, with artifact/provider identity, source
locations, Evidence references, and relevant confidence and limitations.
Missing coverage is unknown, not absence. Avoid extra lookups solely to
understand the answer or its provenance.
- Keep observed, derived, and inferred relationships distinct. Preserve
unresolved edges and partial provider facts instead of requiring every
provider to supply the same metadata.
- Declare process, filesystem, network, UI, and mutation effects truthfully;
enforce the requested target and lifecycle.
- Add limits only for real format, protocol, authority, or measured resource
constraints. Report pagination, truncation, cancellation, and partial failure.
An assumed agent budget is insufficient justification for a limit.
## Implement and evaluate
- Put shared user workflows in the application layer; keep MCP translation in
the server adapter and CLI behavior aligned with the same workflow. Share
Evidence provenance, unknown projection, and eligible snapshot binding through
application/session owners. Matching result payloads alone do not establish
equivalent retention or replay behavior.
- Derive each facet's coverage from examined records, unsupported representations,
and exhaustiveness. Keep issues structured until presentation; do not select a
facet by matching diagnostic prose or infer completeness from an empty failure
list. Preserve available observations independently of cleanup success.
- Measure the resource consumed before choosing a limit. Value alternatives,
retained records, trace-frame products, output bytes, and temporary-file growth
need different accounting. Enforce a justified budget before the costly step
and report its effect; an input-byte or graph-node cap does not bound every stage.
- Update the canonical contract inventory, output schemas, examples, generated
catalog, and relevant docs together.
- Verify valid, malformed, boundary, unavailable, cancellation, and partial
results at the owning boundaries. Use real-provider checks for claims that
depend on external analysis engines.
- Evaluate representative broad and direct task prompts on the intended MCP
host when tool selection is the question. Record the host, model-facing tool
catalog, selected tool, arguments, errors, retries, and task outcome.
Schema validity or word-overlap heuristics do not prove discoverability.
Put provider protocols/parsing in adapters and shared CLI/MCP workflows in the
application layer. Share Evidence provenance, unknown projection, and session
retention semantics; matching payloads alone do not establish parity.
See [mcp-contracts.md](mcp-contracts.md) for shipped runtime behavior and
[testing.md](testing.md) for test boundaries and verification lanes.
Measure the resource before choosing a budget and enforce it before the costly
step. Account for value alternatives, trace-frame products, retained records,
serialization expansion, and temporary-file growth separately. Derive facet
completeness from examined records and exhaustiveness, rather than diagnostic
prose or an empty failure list. Preserve observations independently of cleanup
success.
Update canonical contracts, output schemas, examples, generated artifacts, and
relevant docs together. Verify converted advertised schemas and success,
malformed, unavailable, cancellation, and partial outcomes through affected
consumers. Real-engine claims require the matching provider lane; see
[testing.md](testing.md).
When discoverability changes, evaluate representative broad, direct, and negative
tasks on the intended host. Record host/model/catalog, selected tools, arguments,
errors, retries, and task outcomes. Schema validity and keyword heuristics do not
establish successful tool selection. See [mcp-contracts.md](mcp-contracts.md) for
shipped runtime behavior.
+2 -2
View File
@@ -56,7 +56,7 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement
46,src/application/Uninstall.ts:removeManagedPath symlink,Managed cache/state/skill path is a symbolic link,Refused to follow symlink {path}.,Exposes local path and does not explain manual safety check,"REA did not remove this item because its managed path is a symbolic link. Verify the link target before removing it manually.",implemented,focused assertion passed
47,src/application/Uninstall.ts:removeManagedPath failure,Managed item removal fails,{path} could not be removed.,Exposes local path and gives no recovery,"This item could not be removed. Check file permissions, then rerun uninstall.",implemented,verified by injected managed-path removal failure test
48,src/application/DoctorDiagnostics.ts:node,Runtime version is outside supported ranges,"Install Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+.",Low risk; exact dependency recovery,Keep current copy,unchanged,verified by doctor unit test
49,src/application/Doctor.ts:host,Host OS/distribution is unsupported,"REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS.",Low risk; clearly states supported choices,Keep current copy,unchanged,verified by doctor unit tests
49,src/application/Doctor.ts:host,Host OS/distribution is unsupported,"REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS.",Low risk; clearly states supported choices,Keep current copy,unchanged,verified by doctor unit tests
50,src/application/Doctor.ts:analysis engine,Optional deep-analysis executable cannot be found,"Run rea setup to install Hopper, or set HOPPER_LAUNCHER_PATH.",Low risk in setup-specific diagnostic; exact recovery paths,Keep current copy,unchanged,verified by doctor unit tests
51,src/application/Doctor.ts:target,Optional target path fails shared validation,Supply a readable local app or program path.,Low risk; tells caller valid target class,Keep current copy,unchanged,verified by doctor unit test
52,src/application/Setup.ts:approval,Setup plan lacks approval,"Review the setup plan, then rerun interactively or with --yes.",Low risk; exact authorization recovery,Keep current copy,unchanged,verified by setup unit tests
@@ -67,7 +67,7 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement
57,src/application/Setup.ts:unsupported platform,Platform is neither macOS nor Linux,REA supports Hopper on macOS and selected 64-bit Linux distributions.,Low risk; states support boundary,Keep current copy,unchanged,verified by setup unit test
58,src/application/SetupHost.ts:unsupported Node,Runtime version cannot run setup,"Install Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+ and rerun setup.",Low risk; exact dependency and retry,Keep current copy,unchanged,verified by setup host tests
59,src/application/Setup.ts:unsupported macOS,macOS version is missing or older than 12,Upgrade to macOS 12 or newer.,Low risk; exact support floor,Keep current copy,unchanged,verified by setup host tests
60,src/application/Setup.ts:unsupported Linux,Linux distribution is outside supported set,"REA supports Hopper on Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS.",Low risk; exact supported alternatives,Keep current copy,unchanged,verified by setup unit test
60,src/application/Setup.ts:unsupported Linux,Linux distribution is outside supported set,"REA supports Hopper on Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS.",Low risk; exact supported alternatives,Keep current copy,unchanged,verified by setup unit test
61,src/application/process/ProcessCli.ts:readJson read,Process scenario or evidence file cannot be read,Raw filesystem exception through CLI framework,Can expose local paths/codes and no recovery,"Process input file could not be read. Check that the path exists and is readable.",implemented,verified by focused CLI test
62,src/application/process/ProcessCli.ts:readJson size,Process scenario or evidence file exceeds 64 MiB,Process JSON input exceeds byte limit,Does not state limit or recovery,"Process input file is too large. Reduce it below 64 MiB, then try again.",implemented,verified by focused sparse-file CLI test
63,src/application/process/ProcessCli.ts:readJson parse,Process scenario or evidence file is malformed JSON,Raw JSON parser exception through CLI framework,Can expose parser implementation and lacks recovery,"Process input file is not valid JSON. Repair the file, then try again.",implemented,verified by focused CLI test
1 harm_rank location trigger current_copy user_risk proposed_replacement implementation_status verification_result
56 46 src/application/Uninstall.ts:removeManagedPath symlink Managed cache/state/skill path is a symbolic link Refused to follow symlink {path}. Exposes local path and does not explain manual safety check REA did not remove this item because its managed path is a symbolic link. Verify the link target before removing it manually. implemented focused assertion passed
57 47 src/application/Uninstall.ts:removeManagedPath failure Managed item removal fails {path} could not be removed. Exposes local path and gives no recovery This item could not be removed. Check file permissions, then rerun uninstall. implemented verified by injected managed-path removal failure test
58 48 src/application/DoctorDiagnostics.ts:node Runtime version is outside supported ranges Install Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+. Low risk; exact dependency recovery Keep current copy unchanged verified by doctor unit test
59 49 src/application/Doctor.ts:host Host OS/distribution is unsupported REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS. REA supports macOS 12+, Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS. Low risk; clearly states supported choices Keep current copy unchanged verified by doctor unit tests
60 50 src/application/Doctor.ts:analysis engine Optional deep-analysis executable cannot be found Run rea setup to install Hopper, or set HOPPER_LAUNCHER_PATH. Low risk in setup-specific diagnostic; exact recovery paths Keep current copy unchanged verified by doctor unit tests
61 51 src/application/Doctor.ts:target Optional target path fails shared validation Supply a readable local app or program path. Low risk; tells caller valid target class Keep current copy unchanged verified by doctor unit test
62 52 src/application/Setup.ts:approval Setup plan lacks approval Review the setup plan, then rerun interactively or with --yes. Low risk; exact authorization recovery Keep current copy unchanged verified by setup unit tests
67 57 src/application/Setup.ts:unsupported platform Platform is neither macOS nor Linux REA supports Hopper on macOS and selected 64-bit Linux distributions. Low risk; states support boundary Keep current copy unchanged verified by setup unit test
68 58 src/application/SetupHost.ts:unsupported Node Runtime version cannot run setup Install Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+ and rerun setup. Low risk; exact dependency and retry Keep current copy unchanged verified by setup host tests
69 59 src/application/Setup.ts:unsupported macOS macOS version is missing or older than 12 Upgrade to macOS 12 or newer. Low risk; exact support floor Keep current copy unchanged verified by setup host tests
70 60 src/application/Setup.ts:unsupported Linux Linux distribution is outside supported set REA supports Hopper on Ubuntu 24.04+, Fedora 41+, 64-bit Arch Linux, and CachyOS. REA supports Hopper on Ubuntu 24.04+, Fedora 41+, Nobara 44+, 64-bit Arch Linux, and CachyOS. Low risk; exact supported alternatives Keep current copy unchanged verified by setup unit test
71 61 src/application/process/ProcessCli.ts:readJson read Process scenario or evidence file cannot be read Raw filesystem exception through CLI framework Can expose local paths/codes and no recovery Process input file could not be read. Check that the path exists and is readable. implemented verified by focused CLI test
72 62 src/application/process/ProcessCli.ts:readJson size Process scenario or evidence file exceeds 64 MiB Process JSON input exceeds byte limit Does not state limit or recovery Process input file is too large. Reduce it below 64 MiB, then try again. implemented verified by focused sparse-file CLI test
73 63 src/application/process/ProcessCli.ts:readJson parse Process scenario or evidence file is malformed JSON Raw JSON parser exception through CLI framework Can expose parser implementation and lacks recovery Process input file is not valid JSON. Repair the file, then try again. implemented verified by focused CLI test
+5 -2
View File
@@ -10,8 +10,11 @@ verified manifest into one caller-selected, absent directory.
For passive inspection, select `include_script_sources: true` (CLI:
`--include-script-sources`). For scenarios, select
`capture.network.response_body: true`. Save either the complete Evidence record
or its normalized result as UTF-8 JSON. The compact MCP wrapper's `evidence`
field contains the complete Evidence record.
or its normalized result as UTF-8 JSON. MCP `structuredContent` contains the complete Evidence record.
The capture must be a regular file. A symlink to a regular file is accepted;
directories, named pipes and device files are rejected before reading capture
bytes or creating output.
```sh
rea export-web-scripts /analysis/capture.json /analysis/exported-scripts --json

Some files were not shown because too many files have changed in this diff Show More