Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64228f8144 | ||
|
|
576abe196f | ||
|
|
b2d2e43068 | ||
|
|
acae8a5382 | ||
|
|
1deb6e87bf | ||
|
|
fd3d29bc8d | ||
|
|
27faf8b983 | ||
|
|
3a1aa3fd03 | ||
|
|
3b272dc8e2 | ||
|
|
5bea037552 | ||
|
|
2c36f8d8e5 | ||
|
|
054be92874 | ||
|
|
67f4b79b32 | ||
|
|
b01db67586 | ||
|
|
3c4bd35180 | ||
|
|
b647e4a4e8 | ||
|
|
7f2f0b78c4 | ||
|
|
61141032f7 | ||
|
|
303dc2aa73 | ||
|
|
98c3c527d8 | ||
|
|
5f986d4869 | ||
|
|
b9539e9c1c | ||
|
|
92e17ccfce | ||
|
|
9392590f2f | ||
|
|
ef0c8005bc |
No files matched your search
@@ -1,113 +0,0 @@
|
||||
---
|
||||
name: rea-analysis-optimization
|
||||
description: Optimize REA providers and shared analysis workflows for agent context, latency, CPU, and memory while preserving correctness and Evidence. Use for analysis bottlenecks and cache or query design; CI/test-suite optimization belongs to rea-ci-tests-audit.
|
||||
---
|
||||
|
||||
# REA analysis optimization
|
||||
|
||||
Find a concrete source of unnecessary work, change it at its owner, and verify
|
||||
equivalent completed investigations. A useful outcome can also be a measured
|
||||
decision to leave an implementation alone.
|
||||
|
||||
Follow the checkout's [performance priorities](../../../AGENTS.md#performance),
|
||||
[tool design](../../../docs/tool-design.md), and
|
||||
[testing guide](../../../docs/testing.md). This skill supplies an optimization
|
||||
workflow, not additional permission to execute targets, publish, or merge.
|
||||
Use the current contracts, provider prerequisites, and user authorization.
|
||||
|
||||
Read [the Kuna case study](references/kuna-case-study.md) when selecting a
|
||||
reuse strategy or interpreting a benchmark. Its pinned observations illustrate
|
||||
tradeoffs; they are not current-provider guarantees or universal speedups.
|
||||
|
||||
## Pin the question and the correctness oracle
|
||||
|
||||
Describe the analyst's completed task, including the facts and relationships
|
||||
needed to answer it, requested detail, source access, and meaningful unknowns.
|
||||
Choose a representative real artifact and a small or empty case. Record the
|
||||
baseline revision, target digest, engine identity, options, host, and entrypoint.
|
||||
Use a separate checkout for changes without disturbing other work.
|
||||
|
||||
Establish an oracle independent of the changed implementation: source-built
|
||||
fixture expectations, independently mapped file bytes, or a native producer
|
||||
paired with checks of its interpretation. Comparing two wrappers around the
|
||||
same faulty decoder does not establish correctness. Preserve address widths,
|
||||
same-address alternatives, unresolved endpoints, coverage, and source linkage.
|
||||
An empty result proves absence only within the actually examined scope.
|
||||
|
||||
## Locate the earliest unnecessary work
|
||||
|
||||
Trace one public CLI or MCP task through shared application code to its producer.
|
||||
Measure relevant phases: admission and identity checks, native analysis,
|
||||
decoding, lookup, projection, serialization, Evidence retention, and cleanup.
|
||||
Include catalog discovery and extra calls when they affect the completed task.
|
||||
|
||||
Use the evidence to choose the smallest structural correction:
|
||||
|
||||
| Observed cost | Candidate correction | Condition to establish |
|
||||
| --------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||
| Repeated scans of validated facts | Reuse existing order or lookup structure | The owner establishes ordering and identity; every matching alternative survives |
|
||||
| Repeated equivalent engine work | Share a validated result or in-flight producer | Inputs, freshness, lifetime, and per-caller outcomes remain explicit |
|
||||
| Full reports for selected facts | Push selection or projection to the earliest capable owner | Required facts and evidence remain reachable; examined coverage is reported |
|
||||
| Large temporary transport buffers | Decode incrementally or use bounded source reads | Validate the whole admitted document; retained facts and copies still consume memory |
|
||||
| Many repeated homogeneous reads | Share admission, decoding, or batch work | Preserve item identity, order where required, and individual failures |
|
||||
|
||||
Do not introduce an index, generic cache, batch endpoint, or orchestration layer
|
||||
without identifying the work it removes and its maintenance/resource cost.
|
||||
Projection after materializing a full report may reduce output while leaving
|
||||
analysis time and peak memory unchanged. Fix missing or incorrect facts before
|
||||
benchmarking an alternative composition against a better-covered workflow.
|
||||
|
||||
## Keep one interpretation and a defined reuse lifetime
|
||||
|
||||
Let the producer boundary validate and normalize facts once. Consumers query
|
||||
that representation through the shared CLI/MCP implementation; adapters should
|
||||
not rebuild relationships or independently reinterpret raw reports. Keep lookup
|
||||
identity separate from display formatting. Reuse contracts when their intent
|
||||
matches, honoring requested detail and complete Evidence access.
|
||||
|
||||
For every cache or shared producer, state its key, owner, invalidation, retained
|
||||
size, and lifetime. Account for result-affecting target bytes, engine contents,
|
||||
analysis options, architecture/load mapping, and parser/schema versions where
|
||||
they affect reuse. Validate live state before calling a cached observation
|
||||
current. Cache a refusal only when it is deterministic for that validated key;
|
||||
malformed, partial, transient, or cancelled attempts need explicit retry policy.
|
||||
|
||||
One cancelled waiter must not invalidate a successful peer. Preserve producer
|
||||
failure context and each caller's cancellation reason. Retain ownership and
|
||||
capacity charges until shared work and cleanup settle; preserve completed
|
||||
observations when cleanup fails. Exercise invalidation, concurrent consumers,
|
||||
last-waiter cancellation, close, and cleanup retry when those paths change.
|
||||
|
||||
Bound the process family and retained state, not just a parent heap or worker
|
||||
count. Account for decoding and serialization expansion before allocation.
|
||||
Choose CPU, memory, concurrency, and disk limits from the host and workload;
|
||||
stop before OOM and verify owned cleanup. A guard-stopped task is incomplete.
|
||||
Do not replace a transport buffer cap with an unbounded retained inventory or
|
||||
hide partial results behind a success status.
|
||||
|
||||
## Compare completed tasks and limit the claim
|
||||
|
||||
Run the affected real public workflow before and after with equivalent inputs,
|
||||
results, coverage, and Evidence semantics. Include small inputs so setup costs
|
||||
and regressions are visible. Distinguish fresh sessions, warm runtime caches,
|
||||
and OS file caches. Alternate or repeat runs when variance affects the decision.
|
||||
Choose meaningful boundary regressions for cases the actual engine cannot
|
||||
reliably reproduce; a fake engine does not qualify a real provider.
|
||||
|
||||
Report task outcome, relevant phase timings, total elapsed and CPU time, peak
|
||||
process-family memory and its accounting method, resource stops, and cleanup.
|
||||
Check the payload exit status as well as the profiler's. Keep failed attempts
|
||||
and identify unmeasured costs; a passing retry does not explain a failure.
|
||||
|
||||
For token claims, count schemas/discovery, arguments, replies, retries, and
|
||||
continuations needed to finish the task. Label tokenizer estimates separately
|
||||
from actual model usage and record the client/catalog behavior. Smaller JSON
|
||||
alone establishes neither fewer model tokens nor better investigation quality.
|
||||
Do not claim a complex-software advantage without completed representative
|
||||
investigations and comparable correctness/coverage.
|
||||
|
||||
Finish with the bottleneck, owning change, preserved semantics, executed
|
||||
checks, before/after measurements, and remaining limits. Keep any integration
|
||||
record current with its tested revision and distinguish merged production work
|
||||
from experiment-only code. Stop when the demonstrated bottleneck is resolved
|
||||
or further benefit remains speculative.
|
||||
@@ -1,4 +0,0 @@
|
||||
interface:
|
||||
display_name: "REA analysis optimization"
|
||||
short_description: "Optimize analysis with preserved Evidence and measured costs"
|
||||
default_prompt: "Use $rea-analysis-optimization to find and verify a concrete analysis bottleneck while preserving correctness and Evidence."
|
||||
@@ -1,112 +0,0 @@
|
||||
# Kuna: reuse before adding machinery
|
||||
|
||||
Read this reference for concrete examples of the skill's decisions. The records
|
||||
below concern static Linux analysis with caller-supplied Kuna. They do not
|
||||
establish parity with another provider or a general advantage for Code Mode,
|
||||
atomic tools, or any particular orchestration design.
|
||||
|
||||
## Exact-address lookup: a measured, narrow improvement
|
||||
|
||||
[PR #4695](https://github.com/morluto/rea/pull/4695) reused the validated string
|
||||
inventory's numeric address order. Previously, each `list_strings(address)`
|
||||
filtered all cached facts. The owner now performs a binary lower-bound lookup
|
||||
and returns every encoding at that address: O(log n + matches), without a
|
||||
second retained lookup index.
|
||||
|
||||
The owning implementation is
|
||||
[`KunaStringInventory.ts`](../../../../src/kuna/KunaStringInventory.ts), consumed
|
||||
by [`KunaStringQueries.ts`](../../../../src/kuna/KunaStringQueries.ts). Inspect
|
||||
their current versions before adapting the example. Numeric u64 addresses,
|
||||
same-address encodings, duplicate rejection, source digests, caller selection,
|
||||
and the existing session lifetime were part of the contract. Full listings and
|
||||
literal/regex searches kept their semantics. An attempted removal of the
|
||||
duplicate-detection set was dropped: no stable memory benefit was established,
|
||||
and it delayed malformed-input rejection.
|
||||
|
||||
### Recorded workload and results
|
||||
|
||||
The benchmark used unmodified Kuna 1.833 and LLVM 16 on Linux x86-64, with
|
||||
602,544 string facts. Baseline was `be0b2d138`; the final feature was
|
||||
`5f564962da0e1b17f00a68a74a312539f0209a01`, subsequently integrated in
|
||||
`c6b62754b095a134d6d67877508fa34311a2eda2`. These are historical observations,
|
||||
not a benchmark of every subsequent main revision.
|
||||
|
||||
The same production stdio MCP task discovered the catalog, opened the binary,
|
||||
made one cold selected read and 28 warm exact reads, checked retained Evidence,
|
||||
and closed the session. Five selected addresses and two absent selectors were
|
||||
read four times. A native filtered scan selected the strings; an independent
|
||||
ELF load-header mapping checked the source bytes and terminators. Returned
|
||||
facts, source linkage, target digests, and cleanup were checked.
|
||||
|
||||
Three alternating fresh sessions per implementation used one CPU, a 4 GiB
|
||||
process-family hard limit, a 3 GiB early stop, and no swap. OS file caches were
|
||||
warm. Whole-harness costs include the independent native oracle, hashing,
|
||||
catalog/client work, and correctness checks.
|
||||
|
||||
| Median | Before | After |
|
||||
| ---------------------------------------- | ---------: | ---------: |
|
||||
| 28 warm exact MCP reads | 495.2 ms | 90.8 ms |
|
||||
| Cold selected MCP read | 11.30 s | 11.01 s |
|
||||
| Whole harness elapsed | 28.24 s | 27.43 s |
|
||||
| Whole process-family CPU | 27.71 s | 26.89 s |
|
||||
| Kernel family peak, including file cache | 2237.6 MiB | 2240.6 MiB |
|
||||
|
||||
Warm totals ranged from 491.7–544.3 ms before to 84.8–99.5 ms after: about
|
||||
5.5 times faster at this phase. Cold/whole-task timing and memory overlapped;
|
||||
no stable improvement in those costs was established. One small SQLite pair
|
||||
(7,985 facts) measured 20 warm reads at 88.6 → 80.5 ms and the whole harness at
|
||||
13.68 → 13.94 s. The large-inventory lookup benefit does not generalize to a
|
||||
whole-task speedup on small inputs.
|
||||
|
||||
Catalog hashes, call counts, and normalized facts were unchanged. A
|
||||
`cl100k_base` estimate over one pass of raw catalog JSON, arguments, and replies
|
||||
was about 846,000 tokens in both lanes, with about 802,562 from the catalog.
|
||||
This was transport serialization, not rendered model context or actual usage;
|
||||
client discovery, prompts, replay, and protocol framing were unmeasured.
|
||||
**No token reduction or improved agent investigation outcome was established.**
|
||||
|
||||
Pinned target SHA-256:
|
||||
`f62d254b7f2bf42df8c8b07d46ee3bb4c2cafeca436b2e6bc6ccbe4581f58f40`.
|
||||
Pinned engine SHA-256:
|
||||
`d858918b0766435cd96b999a77f2d5a31a0cc4f07256421c883b5b9dc4dd58e4`.
|
||||
All six normalized-result sequence digests were
|
||||
`4d2f90269da8568984090b20274163c4a7c2a0538aab63530bd2fe44840a0bba`.
|
||||
Selected byte agreement does not prove native discovery completeness; missing
|
||||
strings and relationships can remain unknown.
|
||||
|
||||
## Other transferable changes and their limits
|
||||
|
||||
- [Cached string inventory and search, #4095](https://github.com/morluto/rea/pull/4095):
|
||||
share validated facts across queries in a defined session. Audit key inputs
|
||||
and lifetime before extending reuse across targets or engine revisions.
|
||||
- [Shared single-function work, #4045](https://github.com/morluto/rea/pull/4045)
|
||||
and [repeat-request reuse, #4169](https://github.com/morluto/rea/pull/4169):
|
||||
avoid duplicate native work while retaining per-caller cancellation and
|
||||
cleanup ownership. A query count alone cannot reveal duplicate subprocesses.
|
||||
- [Streamed strings, #4318](https://github.com/morluto/rea/pull/4318)
|
||||
and [streamed call graph, #4329](https://github.com/morluto/rea/pull/4329):
|
||||
remove fixed aggregate transport-buffer failures through incremental parsing.
|
||||
Streaming transport does not bound every retained object or final reply.
|
||||
These links establish changes; no numerical speedup is asserted here.
|
||||
|
||||
Typed reference facts, native string-query projection, and shared native byte
|
||||
reads remained experimental at the 2026-10-17 checkpoint
|
||||
`65f2f9a22bc892f61d2b00f9a4611124f57d4bff` on
|
||||
`experiment/atomic-codemode-20261016`. Some experiments used a patched native
|
||||
engine. Check current integration and bring-your-own engine capabilities before
|
||||
proposing them; a working experiment is not a stock-provider guarantee.
|
||||
|
||||
## Applying the reasoning elsewhere
|
||||
|
||||
For another provider or format, inspect its actual representation and native
|
||||
capabilities before borrowing the implementation. Existing numeric ordering
|
||||
may support range reads; an on-disk native query may avoid materializing an
|
||||
inventory; an immutable parse may support several views. Measure the relevant
|
||||
alternative rather than requiring every provider to use Kuna's cached array.
|
||||
|
||||
For live observations, immutable artifact caching rules are insufficient:
|
||||
validate the process/session identity and freshness required by the caller.
|
||||
For compact replies, preserve access to source Evidence and report examined
|
||||
coverage; projection must not silently turn an unresolved edge into no edge.
|
||||
For batching, test mixed successes and failures and measure the entire task,
|
||||
including discovery, extra calls, native work, and serialization.
|
||||
@@ -59,7 +59,7 @@ availability have different remedies; avoid repeating setup for all of them.
|
||||
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, Kuna, Binwalk, or Unblob. Use existing prerequisites; do not install unrelated
|
||||
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.
|
||||
@@ -79,7 +79,7 @@ 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, Kuna, Binwalk or Unblob.
|
||||
software, including Node.js, npm, Homebrew, Java, Ghidra, IDA, JADX, Binwalk or Unblob.
|
||||
|
||||
## Route the target first
|
||||
|
||||
@@ -215,20 +215,6 @@ 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.
|
||||
|
||||
With `REA_KUNA_COMMAND` configured, `provider_id: "kuna"` answers procedure
|
||||
lists, lookups, pseudocode, assembly and `analyze_function` from Kuna's cached
|
||||
whole-program export. Callers/callees use a separate body-free graph shared by
|
||||
the session; `xrefs` returns exact-address incoming sites and filters forwarding
|
||||
aliases. These queries and inventory lookups do not trigger a C export. Indirect
|
||||
targets remain unknown and can make relationship coverage partial. Reference
|
||||
caches expire on close; a fresh CLI process repeats the native reference walk.
|
||||
Typed references, CFG, raw-memory tools and annotations remain unsupported. A cold first
|
||||
answer can come from a single-function run (its limitations say so); assembly
|
||||
waits for the export. For pseudocode and assembly, `raw_result.source` names the
|
||||
cached `.c`/`.asm` file and byte span, which you may search directly instead of
|
||||
calling per function. See the
|
||||
[Kuna provider guide](https://github.com/morluto/rea/blob/main/docs/kuna-provider.md).
|
||||
|
||||
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
|
||||
|
||||
@@ -24,9 +24,7 @@ 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 and `REA_JADX_OPERATION_TIMEOUT_MS`
|
||||
the per-operation deadline (default 120000 ms; the MCP client's tool timeout
|
||||
must also allow it). The APK is never launched,
|
||||
`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
|
||||
|
||||
@@ -94,36 +94,6 @@ 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.
|
||||
|
||||
For canonical identities and retained source-range counts, use a typed reference
|
||||
page instead of reading every full item:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": {
|
||||
"kind": "retained-evidence",
|
||||
"evidence_id": "ev_ACTUAL_PARENT_ID"
|
||||
},
|
||||
"view": {
|
||||
"kind": "javascript",
|
||||
"collection": "modules",
|
||||
"projection": "references",
|
||||
"where": { "path": "main.js", "kind": "javascript-module" },
|
||||
"offset": 0,
|
||||
"limit": 16
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Filters match exact retained strings; omit a filter to include all values, use
|
||||
`path: null` for unavailable paths, and `path: ""` for a recorded empty path.
|
||||
Rows preserve canonical `identity` and distinct observation support states in
|
||||
`basis`. `retained_source_range_count` counts retained source-range observations,
|
||||
not runtime imports or unique reference sites. Use a row's `node_id` with the item
|
||||
view above for exact locations and full supporting observations. Follow
|
||||
`coverage.next_offset`; page exhaustion describes matching retained rows only.
|
||||
Check `source_coverage` for source selection, partial/unknown graph coverage and
|
||||
unknown counts before drawing a negative conclusion.
|
||||
|
||||
## Trace only the remaining question
|
||||
|
||||
Use `trace_application_feature` on the parent application Evidence for one
|
||||
@@ -195,8 +165,7 @@ 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
|
||||
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
|
||||
@@ -204,15 +173,3 @@ 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.
|
||||
|
||||
For exact file/native metadata or processing gaps, use
|
||||
`view: {kind: "javascript-facts", where: {paths: ["package.json"]}, property_keys: ["name", "operation", "analysis_status"], limit: 32}`.
|
||||
Rows retain canonical node/observation identity and original Evidence. Paths
|
||||
match Evidence artifact-path/source-range locations; missing properties remain
|
||||
omitted and source coverage stays separate from page exhaustion. Batch paths and
|
||||
select only needed property keys; complete Evidence remains accessible by export.
|
||||
If names are unknown, opt into `include_available_property_keys: true`; it lists
|
||||
the original keys per returned observation without unselected values. Keep each
|
||||
row's node/observation identity paired when composing facts.
|
||||
These rows select application-graph observations; semantic relationships and
|
||||
semantic unknown records remain in the complete parent Evidence and trace tools.
|
||||
@@ -124,26 +124,6 @@ operation's full ordered list. Candidate capabilities describe possible
|
||||
providers. Top-level session capabilities describe the current route, and
|
||||
`analysis_provider_binding` identifies the selected provider.
|
||||
|
||||
## Static memory and original file bytes
|
||||
|
||||
For Ghidra, `read_bytes` reads initialized analysis memory, including loader
|
||||
fixups; it does not read a running process. Check `returned_bytes` and `complete`
|
||||
before decoding a table. An incomplete read is missing coverage, not a zero-filled
|
||||
tail. Use `list_segments` to inspect the selected block's initialization and address-space
|
||||
facts, and retain unavailable facts as unknown.
|
||||
|
||||
Use `address_to_file_offset` to anchor one observed address to original file
|
||||
bytes. A mapping for the first address does not establish a contiguous mapping
|
||||
for an entire table, and loader fixups can make analysis bytes differ from source
|
||||
bytes. Keep source ranges and analysis-memory observations separate.
|
||||
|
||||
A pointer table can refer to writable slots populated by a constructor rather
|
||||
than directly to immutable resources. An uninitialized block or an observed zero
|
||||
does not establish the slot's later runtime value. Follow `xrefs` and the relevant
|
||||
writer's assembly or pseudocode; distinguish recorded assignments from inferred
|
||||
execution order. Do not replace unreadable bytes with zeros or conclude that a
|
||||
resource is absent without the necessary initialization evidence.
|
||||
|
||||
## DOS MZ with Ghidra
|
||||
|
||||
For an admitted DOS MZ target, use `inspect_native_load_image` to check measured
|
||||
@@ -153,8 +133,10 @@ reported static image, not runtime DOS or PC-98 hardware behavior.
|
||||
|
||||
For Ghidra decompilation, `procedure_pseudo_code` also accepts `procedure: "file-offset:0x..."`; CLI `rea decompile <path> --file-offset=0x... --provider ghidra` resolves the source byte offset internally. An unresolved 0x-prefixed numeric procedure selector also falls back to a unique file mapping. Existing symbols and analysis addresses win; multiple mappings fail as ambiguous. Preserve the returned file-offset and address locations and raw selection observations. ELF virtual addresses are distinct from file offsets; never assume an arbitrary offset plus image base is an analysis address.
|
||||
|
||||
Complete function body ranges use inclusive ends and can contain gaps. Do not
|
||||
treat the enclosing span as code.
|
||||
Use `read_bytes` for initialized analysis memory and `address_to_file_offset` to
|
||||
anchor one observed address to original file bytes. Loader fixups can change a
|
||||
word; a source offset does not imply byte equality. Complete function body ranges
|
||||
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.
|
||||
|
||||
@@ -264,15 +246,13 @@ context. PSP/stack/device state remains unmodeled. See [DOS guide](https://githu
|
||||
|
||||
For other headerless images (embedded firmware without ELF/Mach-O/PE/MZ
|
||||
headers), open with `format: "raw-binary"`, `architecture` (`x86`, `x86_64`,
|
||||
`arm`, `arm64`, `6502`, or `m68k`), and `entry_point` (`0x` hex). File offset 0 is mapped at
|
||||
`arm`, `arm64`, or `6502`), and `entry_point` (`0x` hex). File offset 0 is mapped at
|
||||
that address. Hopper and IDA refuse this interpretation; Ghidra uses
|
||||
`BinaryLoader` with a generic language: big-endian for `m68k`, little-endian
|
||||
otherwise. Big-endian ARM, Thumb-only, and Cortex-M variants are unsupported.
|
||||
`6502` selects NMOS 6502; the entry and complete file mapping must fit within
|
||||
`0x0000..0xffff`. 65C02, 65816, cartridge containers, bank switching, and mapper
|
||||
semantics are unsupported. `m68k` requires an even entry and decodes the 68040
|
||||
superset of the 68000 family; Amiga/Atari containers and vector-table entry
|
||||
discovery are unsupported. Windows Ghidra P0 admits raw images only for `6502`. See [raw binary guide](https://github.com/morluto/rea/blob/main/docs/raw-binary.md).
|
||||
`BinaryLoader` with a little-endian generic language. Big-endian, Thumb-only,
|
||||
and Cortex-M variants are unsupported. `6502` selects NMOS 6502; the entry and
|
||||
complete file mapping must fit within `0x0000..0xffff`. 65C02, 65816, cartridge
|
||||
containers, bank switching, and mapper semantics are unsupported. Windows
|
||||
Ghidra P0 admits raw images only for `6502`. See [raw binary guide](https://github.com/morluto/rea/blob/main/docs/raw-binary.md).
|
||||
|
||||
### Function annotations in Ghidra
|
||||
|
||||
|
||||
@@ -24,7 +24,19 @@ runs:
|
||||
BUILD_CACHE_PREFIX: rea-portable-build-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc', '.nvmrc', 'package-lock.json') }}
|
||||
run: |
|
||||
npm run --silent test:prepare -- --dry=json |
|
||||
node scripts/ci/portable-build-cache.mjs key >> "$GITHUB_OUTPUT"
|
||||
node --input-type=module -e '
|
||||
import { createHash } from "node:crypto";
|
||||
import { readFileSync } from "node:fs";
|
||||
const { tasks } = JSON.parse(readFileSync(0, "utf8"));
|
||||
const hashes = tasks.map(({ taskId, hash }) => {
|
||||
if (typeof hash !== "string")
|
||||
throw new Error(`Build task ${taskId} must have an eager Turbo hash`);
|
||||
return `${taskId}:${hash}`;
|
||||
}).sort();
|
||||
const hash = createHash("sha256").update(hashes.join("\n")).digest("hex");
|
||||
console.log(`key=${process.env.BUILD_CACHE_PREFIX}-${hash}`);
|
||||
console.log(`prefix=${process.env.BUILD_CACHE_PREFIX}-`);
|
||||
' >> "$GITHUB_OUTPUT"
|
||||
- name: Restore portable build outputs
|
||||
if: inputs.build_cache_artifact == '' && inputs.save != 'true'
|
||||
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
|
||||
@@ -60,7 +60,6 @@ jobs:
|
||||
web_runtime: ${{ steps.plan.outputs.web_runtime }}
|
||||
web_source_map: ${{ steps.plan.outputs.web_source_map }}
|
||||
nativeaot: ${{ steps.plan.outputs.nativeaot }}
|
||||
ghidra_bridge: ${{ steps.plan.outputs.ghidra_bridge }}
|
||||
website: ${{ steps.plan.outputs.website }}
|
||||
matrix: ${{ steps.plan.outputs.matrix }}
|
||||
test_selection: ${{ steps.plan.outputs.test_selection }}
|
||||
@@ -140,11 +139,6 @@ jobs:
|
||||
- name: Validate workflow syntax and expressions
|
||||
if: needs.changes.outputs.workflows == 'true'
|
||||
run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.7 -shellcheck= -pyflakes=
|
||||
# Code tiers run this source-only policy test in their existing shards.
|
||||
# Workflow-only changes need the guard, without preparing runtime artifacts.
|
||||
- name: Check action pins for workflow-only changes
|
||||
if: needs.changes.outputs.workflows == 'true' && needs.changes.outputs.code != 'true'
|
||||
run: node scripts/run-exact-tests.mjs run tests/boundary/filesystem/workflowActionPinning.test.ts
|
||||
- name: Record static task source and execution identity
|
||||
continue-on-error: true
|
||||
if: needs.changes.outputs.code == 'true'
|
||||
@@ -357,15 +351,10 @@ jobs:
|
||||
# test:prepare caches only portable JS, skill, and catalog outputs.
|
||||
# Native package jobs still run their build and prepack checks; Turbo
|
||||
# restores matching outputs or rebuilds when their inputs differ.
|
||||
- name: Stage current portable build task cache
|
||||
shell: bash
|
||||
run: |
|
||||
# A new Turbo dry run can evict the entries this build just used.
|
||||
node scripts/ci/portable-build-cache.mjs snapshot < .cache/ci-build-plan.json
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: rea-build-cache
|
||||
path: .cache/ci-build-cache/
|
||||
path: .turbo/cache/
|
||||
include-hidden-files: true
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
@@ -653,7 +642,6 @@ jobs:
|
||||
tests/boundary/cli/nativePlistPrototypeKeyCli.test.ts
|
||||
tests/boundary/cli/nativePlistSelectionFailureCli.test.ts
|
||||
tests/boundary/cli/nativeDemangleCli.test.ts
|
||||
tests/boundary/cli/nativeDispatchPropertyAttributes.test.ts
|
||||
tests/boundary/mcp/nativeDemangleMcp.test.ts
|
||||
tests/boundary/providers/native/nativeSignatureTargetBinding.test.ts
|
||||
tests/boundary/cli/nativeSignatureCli.test.ts
|
||||
@@ -716,12 +704,12 @@ jobs:
|
||||
with:
|
||||
name: rea-build-cache
|
||||
path: .turbo/cache/
|
||||
- run: npm run build:cached
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: windows-native-controls
|
||||
path: native/windows/build/
|
||||
- run: npm run verify:windows-native:artifact
|
||||
- run: npm run build:cached
|
||||
- name: Record named Windows host capabilities
|
||||
run: node scripts/windows-capabilities.mjs | Out-File -Encoding utf8NoBOM windows-capabilities.json
|
||||
- name: Validate Windows host capability report
|
||||
@@ -753,8 +741,6 @@ jobs:
|
||||
tests/boundary/filesystem/javascriptApplicationWorkflows.test.ts
|
||||
tests/boundary/filesystem/webScriptManifestPaths.test.ts
|
||||
tests/boundary/process/ProcessEvidence.host.test.ts
|
||||
tests/boundary/process/packageNpmInvocation.test.ts
|
||||
tests/boundary/process/packedBridgeVerification.test.ts
|
||||
tests/boundary/process/windowsOutputCapture.test.ts
|
||||
tests/acceptance/webModuleCli.test.ts
|
||||
tests/acceptance/webSourceLocationCli.test.ts
|
||||
@@ -777,8 +763,6 @@ jobs:
|
||||
src/process/ProcessOwnership.validation.test.ts
|
||||
src/application/Update.test.ts
|
||||
tests/process-global/updateMaintenance.test.ts
|
||||
tests/process-global/runnerCancellation.test.ts
|
||||
tests/process-global/windowsOwnedCommand.test.ts
|
||||
tests/conformance/providers/ghidra/realGhidraWindowsWorkflow.test.ts
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
@@ -914,11 +898,6 @@ jobs:
|
||||
if: needs.changes.outputs.nativeaot == 'true'
|
||||
uses: ./.github/workflows/nativeaot-fixtures.yml
|
||||
|
||||
ghidra_bridge:
|
||||
needs: [changes, static]
|
||||
if: needs.changes.outputs.ghidra_bridge == 'true'
|
||||
uses: ./.github/workflows/ghidra-bridge-sources.yml
|
||||
|
||||
website:
|
||||
needs: [changes, static]
|
||||
if: needs.changes.outputs.website == 'true'
|
||||
@@ -954,7 +933,6 @@ jobs:
|
||||
web_runtime,
|
||||
web_source_map,
|
||||
nativeaot,
|
||||
ghidra_bridge,
|
||||
website,
|
||||
]
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
name: Ghidra bridge source compilation
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
HUSKY: "0"
|
||||
|
||||
jobs:
|
||||
ghidra-bridge-sources:
|
||||
name: Compile packaged Ghidra bridge sources
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 15
|
||||
env:
|
||||
GHIDRA_RELEASE_URL: https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_12.1.4_build/ghidra_12.1.4_PUBLIC_20260921.zip
|
||||
GHIDRA_RELEASE_SHA256: ddac49f903da9d5bac833e5cc79395098b9c33cfd3279be5f31bd00387d2d4db
|
||||
steps:
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
- name: Validate the SDK pin against the provider's verified release
|
||||
run: node scripts/verify-ghidra-bridge-sources.mjs --check-sdk-pin >> "$GITHUB_ENV"
|
||||
# Only the jars and application.properties are extracted: the check
|
||||
# compiles against them and never launches Ghidra or imports a target.
|
||||
- name: Acquire checksum-verified Ghidra jars in isolated runner storage
|
||||
shell: bash
|
||||
run: |
|
||||
ghidra_root="${RUNNER_TEMP}/rea-ghidra"
|
||||
mkdir -p "${ghidra_root}"
|
||||
curl -fsSL --retry 3 --write-out 'ghidra_download_bytes=%{size_download} ghidra_download_seconds=%{time_total}\n' -o "${ghidra_root}/ghidra.zip" "${GHIDRA_RELEASE_URL}"
|
||||
echo "${GHIDRA_RELEASE_SHA256} ${ghidra_root}/ghidra.zip" | sha256sum -c -
|
||||
unzip -q "${ghidra_root}/ghidra.zip" '*/Ghidra/*.jar' '*/Ghidra/application.properties' -d "${ghidra_root}"
|
||||
rm "${ghidra_root}/ghidra.zip"
|
||||
properties="$(find "${ghidra_root}" -path '*/Ghidra/application.properties' -print -quit)"
|
||||
test -n "${properties}"
|
||||
echo "GHIDRA_INSTALL_DIR=$(dirname "$(dirname "${properties}")")" >> "${GITHUB_ENV}"
|
||||
# JAVA_HOME_<major>_X64 comes from the runner image, not the env context.
|
||||
- name: Compile bridge sources with the verified runner JDK
|
||||
shell: bash
|
||||
run: |
|
||||
java_home_variable="JAVA_HOME_${GHIDRA_JAVA_MAJOR}_X64"
|
||||
test -n "${!java_home_variable}"
|
||||
JAVA_HOME="${!java_home_variable}" npm run verify:ghidra:bridge-sources -- --verified-sdk
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install --no-install-recommends -y g++-mingw-w64-x86-64
|
||||
- run: npm run build:windows-native
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cutter-windows-native
|
||||
path: native/windows/build/
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
uses: ./.github/actions/npm-cache
|
||||
- run: npm ci
|
||||
- if: matrix.platform == 'Windows'
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: cutter-windows-native
|
||||
path: native/windows/build/
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
env:
|
||||
EXPECTED_PLATFORM: ${{ matrix.platform }}
|
||||
run: npm run verify:cutter
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: cutter-upstream-${{ matrix.platform }}
|
||||
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
- run: sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y tshark util-linux python3
|
||||
- run: npm ci
|
||||
- run: npm run build:cached
|
||||
- run: npm run test:focused -- tests/boundary/captures/fieldDiscovery.test.ts src/process/LinuxResourceLimits.test.ts tests/boundary/captures/captureProvider.test.ts tests/boundary/captures/captureDescriptorCleanup.test.ts tests/boundary/pcap/pcapProvider.test.ts tests/boundary/pcap/pcapProviderCrossPlatform.test.ts tests/boundary/captures/resourceLimits.test.ts tests/boundary/captures/packetOutput.test.ts tests/boundary/mcp/packetCaptureMcp.test.ts tests/boundary/cli/captureCleanup.test.ts
|
||||
- run: npm run test:focused -- tests/boundary/captures/fieldDiscovery.test.ts src/process/LinuxResourceLimits.test.ts tests/boundary/captures/captureProvider.test.ts tests/boundary/captures/captureDescriptorCleanup.test.ts tests/boundary/captures/resourceLimits.test.ts tests/boundary/captures/packetOutput.test.ts tests/boundary/mcp/packetCaptureMcp.test.ts tests/boundary/cli/captureCleanup.test.ts
|
||||
- run: node scripts/verify-packet-capture.mjs
|
||||
env:
|
||||
REA_TSHARK_COMMAND: /usr/bin/tshark
|
||||
|
||||
@@ -24,19 +24,7 @@ jobs:
|
||||
real-recorded-crash:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: ["ubuntu:24.04", "debian:trixie-slim"]
|
||||
container: ${{ matrix.image }}
|
||||
steps:
|
||||
- name: Install fixture and debugger prerequisites in the disposable container
|
||||
shell: bash
|
||||
run: |
|
||||
apt-get update -qq
|
||||
apt-get install --yes --no-install-recommends \
|
||||
ca-certificates git python3-venv gcc libc6-dev strace gdb
|
||||
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
@@ -48,6 +36,11 @@ jobs:
|
||||
- uses: ./.github/actions/portable-build-cache
|
||||
with:
|
||||
build_cache_artifact: ${{ inputs.build_cache_artifact }}
|
||||
- name: Install GDB on the disposable CI runner
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install --yes --no-install-recommends gdb
|
||||
- name: Acquire exact unchanged upstreams in isolated runner storage
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
".": "6.7.0"
|
||||
".": "6.5.0"
|
||||
}
|
||||
@@ -20,8 +20,6 @@ Give each interpretation and resource a clear owner. Consumers must use that own
|
||||
|
||||
Keep proof of ownership separate from validity, editability, and readiness. Malformed owned data may still be safely removable. Unresolved identity or applicability must remain unknown rather than be treated as absent, foreign, or aligned.
|
||||
|
||||
For lifecycle changes, follow [ownership and completion invariants](docs/tool-design.md#own-the-lifecycle) and select the applicable [lifecycle regressions](docs/testing.md#lifecycle-regressions). Include late handshakes, cancellation during final cleanup, mixed child outcomes, and cleanup retry where those stages exist; active-execution cancellation alone does not cover finalization.
|
||||
|
||||
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.
|
||||
|
||||
When fixing a bug, inspect the producing boundary and affected consumers for duplicated interpretation or unclear ownership. Complete any directly related refactor in the same change and remove superseded code. Passing regression tests alone does not establish that the brittleness is resolved. If related cleanup remains, explain what remains and why.
|
||||
|
||||
@@ -1,93 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
## [6.7.0](https://github.com/morluto/rea/compare/rea-agents-6.6.0...rea-agents-6.7.0) (2026-10-18)
|
||||
|
||||
### Highlights
|
||||
|
||||
- Client configuration edits follow the duplicate-member semantics used by MCP clients.
|
||||
|
||||
### Changes
|
||||
|
||||
- Includes the [6.6.0 changes and migration notes](https://github.com/morluto/rea/releases/tag/rea-agents-6.6.0). That version was tagged but was not published to npm.
|
||||
|
||||
### Fixes
|
||||
|
||||
- **Client configuration:** Setup edits the last repeated JSON/JSONC member, matching the value clients actually read. Setup and uninstall refuse a removal that would reactivate a shadowed duplicate, preserving the original configuration. ([#4957](https://github.com/morluto/rea/pull/4957), [morluto/rea#4952](https://github.com/morluto/rea/issues/4952)). Thanks @kaoru0822-kitauji, @xu91102.
|
||||
|
||||
Full contribution record: [4 commits and 1 merged PR](https://github.com/morluto/rea/blob/rea-agents-6.7.0/docs/releases/6.7.0.contributions.json).
|
||||
|
||||
## [6.6.0](https://github.com/morluto/rea/compare/rea-agents-6.5.0...rea-agents-6.6.0) (2026-10-18)
|
||||
|
||||
### Highlights
|
||||
|
||||
- Add Kuna as a caller-supplied static-analysis provider.
|
||||
- Query selected JavaScript facts and multiple APK locale tables without repeating the underlying analysis.
|
||||
- Extend Ghidra analysis to Windows ARM PE targets and explicit raw m68k images.
|
||||
- Preserve completed Evidence, cancellation reasons and retryable cleanup across provider and CLI finalization.
|
||||
|
||||
### Changes
|
||||
|
||||
- **Kuna analysis:** Use a caller-installed Kuna for procedure listings, pseudocode, assembly, call relationships, exact-address xrefs and cached string searches. Project exports retain source spans and digests; repeated requests reuse completed work. Recorded real-provider coverage uses Kuna 1.833 on Linux; Windows, PE and universal Mach-O are unsupported. See [the provider guide](docs/kuna-provider.md). ([#3832](https://github.com/morluto/rea/pull/3832), [#3854](https://github.com/morluto/rea/pull/3854), [#4071](https://github.com/morluto/rea/pull/4071), [#4095](https://github.com/morluto/rea/pull/4095)). Thanks @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **Retained JavaScript facts:** Query exact application paths, selected properties and filtered module references through `inspect_analysis_view`, with paging and complete row Evidence. These views reuse completed analysis and preserve source selection and unknown coverage. ([#4265](https://github.com/morluto/rea/pull/4265), [morluto/rea#4190](https://github.com/morluto/rea/issues/4190), [#4097](https://github.com/morluto/rea/pull/4097), [morluto/rea#4092](https://github.com/morluto/rea/issues/4092)). Thanks @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **APK locale tables:** Request several resource locales in one decode with repeatable CLI `--locales` or MCP `locales`. Each table reports its status and coverage; existing single-locale fields remain available. ([#4804](https://github.com/morluto/rea/pull/4804), [morluto/rea#4777](https://github.com/morluto/rea/issues/4777)). Thanks @abhay-2108, @N0zoM1z0.
|
||||
- **Windows ARM binaries:** Ghidra admits ARMNT/Thumb-2 and ARM64 PE applications and DLLs on the Windows x64 host lane. Recorded Ghidra 12.1.4 verification uses `WindowsResourceReference` disabled and raised startup budgets; default-analyzer completion, ARM64EC/ARM64X and Windows-on-Arm hosts remain unverified or unsupported. See [the exact scope](docs/windows-ghidra-p0.md#native-authority-and-target-identity). ([#3965](https://github.com/morluto/rea/pull/3965), [morluto/rea#2186](https://github.com/morluto/rea/issues/2186)). Thanks @N0zoM1z0, @WestLabsAI.
|
||||
- **Raw m68k images:** Analyze explicitly selected big-endian m68k raw binaries using Ghidra’s fixed 68000 profile and a caller-supplied aligned entry. Real CLI/MCP verification used Ghidra 12.1.4 on macOS arm64; Linux is unverified and Windows P0 does not admit m68k. See [mapping requirements](docs/raw-binary.md). ([#4018](https://github.com/morluto/rea/pull/4018)). Thanks @icedac.
|
||||
- **JADX deadlines:** Set `REA_JADX_OPERATION_TIMEOUT_MS` to extend APK loading and upstream operation deadlines together. Doctor reports the effective value and setup forwards an explicit selection. ([#4466](https://github.com/morluto/rea/pull/4466), [morluto/rea#3918](https://github.com/morluto/rea/issues/3918)). Thanks @jaychou813, @SandstromPL.
|
||||
- **Electron window options:** Resolve stable local constant `BrowserWindow` options while retaining source provenance. Relevant writes and escapes keep the result unknown. ([#4400](https://github.com/morluto/rea/pull/4400), [morluto/rea#4366](https://github.com/morluto/rea/issues/4366)). Thanks @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **Language editions:** Add the Greek website edition and Malayalam documentation, with Korean typography and translation corrections across the site. ([#3520](https://github.com/morluto/rea/pull/3520), [#4792](https://github.com/morluto/rea/pull/4792), [#3821](https://github.com/morluto/rea/pull/3821), [morluto/rea#3820](https://github.com/morluto/rea/issues/3820), [#3799](https://github.com/morluto/rea/pull/3799), [morluto/rea#3798](https://github.com/morluto/rea/issues/3798), [#4344](https://github.com/morluto/rea/pull/4344), [#3856](https://github.com/morluto/rea/pull/3856), [#4166](https://github.com/morluto/rea/pull/4166)). Thanks @gensokyo-dev, @hi2242, @kalayciburak, @kaoru0822-kitauji, @kraken-503, @kukinghan, @N0zoM1z0, @yeseong0412.
|
||||
|
||||
### Fixes
|
||||
|
||||
- **Cancellation and cleanup:** Keep completed observations, exact cancellation reasons and the original physical failure through finalization. Failed cleanup retains its process or file owner for retry; recovered resources disappear from pending-cleanup reports without replacing the original error. ([#4238](https://github.com/morluto/rea/pull/4238), [morluto/rea#4232](https://github.com/morluto/rea/issues/4232), [#4274](https://github.com/morluto/rea/pull/4274), [morluto/rea#3923](https://github.com/morluto/rea/issues/3923), [3e82366](https://github.com/morluto/rea/commit/3e8236639abffa39deb5d5e939ec8baf6aaf3ca3), [16924e2](https://github.com/morluto/rea/commit/16924e275e939d0543ba01493324959a9e1d731c), [bbfe6ed](https://github.com/morluto/rea/commit/bbfe6edd60290f9bfbec68c8a0bcf605d8bbf5b3), [1f23e97](https://github.com/morluto/rea/commit/1f23e977b50301e91f02a4a17c9f8d48bb7b60f3), [08fbeb8](https://github.com/morluto/rea/commit/08fbeb8bdab27118b6c57039aef7c0fa8b6463bc)). Thanks @coygeek.
|
||||
- **Provider startup:** Join prerequisite probes and in-flight readiness work before shutdown, preserve typed timeout and JVM-memory failures, and retain startup diagnostics through cleanup. Ghidra recognizes keg-only Homebrew JDKs and names the setting responsible for a startup timeout. ([376eeca](https://github.com/morluto/rea/commit/376eeca770820b31f7f8d4c5fcc397315621643e), [ceeff5a](https://github.com/morluto/rea/commit/ceeff5a41788e47e5aee96a4baf191a6ce7fde4b), [3ad1032](https://github.com/morluto/rea/commit/3ad1032b11edea2dcb054e78f951cc43159ae83d), [964decd](https://github.com/morluto/rea/commit/964decd989acfa84c4bfc3295362c4c46877fc20), [3fa972a](https://github.com/morluto/rea/commit/3fa972af7c7cb6cf014ffc426bdf7130dc6f2fd2), [#4557](https://github.com/morluto/rea/pull/4557), [morluto/rea#4556](https://github.com/morluto/rea/issues/4556), [#4590](https://github.com/morluto/rea/pull/4590), [morluto/rea#4241](https://github.com/morluto/rea/issues/4241)). Thanks @DanielCvz1, @J0UH, @Rinkia, @RishTheFish21, @vadlachary2002.
|
||||
- **Client configuration:** Preserve the selected launcher, destination file, caller timeout choices and unresolved configuration evidence. Setup/uninstall recovery stays bound to the exact published file, keeps current verified backups, and transfers failed cleanup ownership for retry. ([d0253c9](https://github.com/morluto/rea/commit/d0253c99d65afbbd12732a2fdaf711640574e17f), [7e4eed9](https://github.com/morluto/rea/commit/7e4eed9dd48485b6a7100300aa98401811c2deb9), [2fb5e20](https://github.com/morluto/rea/commit/2fb5e204a35723f6f843d56ca47b0db94d8fcc44), [8235210](https://github.com/morluto/rea/commit/823521085a28f825e7fee1929d852d420042d1f7), [d818c3d](https://github.com/morluto/rea/commit/d818c3d2639d3115edb8a5269a754101aea6c3bd), [19329e4](https://github.com/morluto/rea/commit/19329e43bb38ca9d64512d801b25abcb188d2512), [dadf909](https://github.com/morluto/rea/commit/dadf909dce2e8b3d055541de69b4118d21276316), [333e0ab](https://github.com/morluto/rea/commit/333e0ab0dfc126a9915907d5079ed6195190e38e), [c15c206](https://github.com/morluto/rea/commit/c15c2062ad815cc9a3222ccfaeb7ef53cacd8b72)). Thanks @Adolanium.
|
||||
- **Configuration formats:** Read signed 64-bit TOML integers without rounding, handle large TOML documents without argument-spread failures, preserve JSONC trivia and Hermes YAML scalar text, and reject NUL bytes in registration environment values. ([#4937](https://github.com/morluto/rea/pull/4937), [morluto/rea#4917](https://github.com/morluto/rea/issues/4917), [c43bc0b](https://github.com/morluto/rea/commit/c43bc0bf66a4e245a0cafa40def0d0207bcbd73c), [4fd28fc](https://github.com/morluto/rea/commit/4fd28fc9e0c4f8358147af38c72ab9e814f52d61), [#3568](https://github.com/morluto/rea/pull/3568), [#4335](https://github.com/morluto/rea/pull/4335)). Thanks @alfredo1491, @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0, @ShuaixinHuang, @xu91102.
|
||||
- **Claude Code configuration:** Setup, doctor and uninstall now accept only the strict JSON format Claude Code reads, including a leading UTF-8 BOM. Comments and trailing commas are refused before backup or writing; clients that support JSONC retain their existing behavior. ([#4944](https://github.com/morluto/rea/pull/4944), [morluto/rea#4940](https://github.com/morluto/rea/issues/4940)). Thanks @kaoru0822-kitauji, @xu91102.
|
||||
- **CLI output and dispatch:** Accept `--flag=value` and spaced global output values, keep array positions in filtered JSON, validate integer tokens before coercion, and exit quietly when the output reader closes. Cancellation remains effective through command finalization; app bundles and static native inspections select the intended workflow. ([#3811](https://github.com/morluto/rea/pull/3811), [#4823](https://github.com/morluto/rea/pull/4823), [2ae4e16](https://github.com/morluto/rea/commit/2ae4e1608f290c95ff7cff28c4d16a79b301d03d), [8d82579](https://github.com/morluto/rea/commit/8d8257928bbe8d43fedffc4db5fca26c8108820f), [#3781](https://github.com/morluto/rea/pull/3781), [279c590](https://github.com/morluto/rea/commit/279c590ef6bb737d4a48ea696a0ae5eb30010b3d), [#3511](https://github.com/morluto/rea/pull/3511), [morluto/rea#3321](https://github.com/morluto/rea/issues/3321), [f31b231](https://github.com/morluto/rea/commit/f31b231a92a61be6bd1800b16be0b3210ae82944)). Thanks @arjunprabhulal, @coygeek, @kaoru0822-kitauji, @ShuaixinHuang, @Sriram-PR, @Tapraj-Pathak.
|
||||
- **Updates:** Route `--update` through the verified updater and bound retained package-manager diagnostics. ([4f7b5fb](https://github.com/morluto/rea/commit/4f7b5fb6023ce2ec449561782d09e3c7e5ac7c7b), [01cdbbd](https://github.com/morluto/rea/commit/01cdbbdc556262c47d04a5b3391dd9c17946d3fc)).
|
||||
- **MCP contracts:** Advertise self-contained tool inputs while preserving tuple, array, Boolean and nested-JSON constraints across schema profiles. Schema-reference handling no longer rewrites literal metadata; catalog identity includes the output-schema profile. ([5e30969](https://github.com/morluto/rea/commit/5e30969cc5f1255d44ec7a1f1ca8dbac0af5e7c4), [10aa74d](https://github.com/morluto/rea/commit/10aa74dfedc3ae776f50d1fa1eb83b64ae82d3d6), [204b9f3](https://github.com/morluto/rea/commit/204b9f3ac140a993c3e458bb0e117de31818ab29), [b3389a5](https://github.com/morluto/rea/commit/b3389a5b0834265fe7a40391be315d810a53a97e), [a2e3016](https://github.com/morluto/rea/commit/a2e30168a046f3b79319eb7fbaf807b802104199), [ba98130](https://github.com/morluto/rea/commit/ba98130049fa40ade66b03611ff70c7ddc011a1d), [c5fb86d](https://github.com/morluto/rea/commit/c5fb86d1948af0a287a581b29b2b1d554743c607)). Thanks @akushonkamen, @HarsH-1877, @kaoru0822-kitauji, @xingzihai.
|
||||
- **Session ordering:** Keep snapshot admission ahead of later calls on the same connection, retain shutdown signals until cleanup succeeds, and preserve inspection authority through investigation publication. ([#3661](https://github.com/morluto/rea/pull/3661), [morluto/rea#3334](https://github.com/morluto/rea/issues/3334), [8873b39](https://github.com/morluto/rea/commit/8873b39770e89eae22b7693bc492d7e423b22bea), [663d07f](https://github.com/morluto/rea/commit/663d07f02cd62c99d81c59391d2c6d745c875335)). Thanks @coygeek, @rudycelekli, @Swatantra-66.
|
||||
- **JavaScript exports and resolution:** Retain CommonJS exports created with `Object.defineProperty` and track export receiver lifetimes. Resolve scoped packages, package `main`, JSON requires and `.mts`/`.cts` imports using the owning loader; overwritten `require` bindings and erased type-only imports no longer create false runtime links. ([#4725](https://github.com/morluto/rea/pull/4725), [morluto/rea#4724](https://github.com/morluto/rea/issues/4724), [#3567](https://github.com/morluto/rea/pull/3567), [morluto/rea#3541](https://github.com/morluto/rea/issues/3541), [#4838](https://github.com/morluto/rea/pull/4838), [morluto/rea#4632](https://github.com/morluto/rea/issues/4632), [#3844](https://github.com/morluto/rea/pull/3844), [morluto/rea#3383](https://github.com/morluto/rea/issues/3383), [#4164](https://github.com/morluto/rea/pull/4164), [morluto/rea#3915](https://github.com/morluto/rea/issues/3915), [#4223](https://github.com/morluto/rea/pull/4223), [#3801](https://github.com/morluto/rea/pull/3801), [morluto/rea#3393](https://github.com/morluto/rea/issues/3393), [#4165](https://github.com/morluto/rea/pull/4165), [morluto/rea#3932](https://github.com/morluto/rea/issues/3932)). Thanks @Abishek0070, @coygeek, @JNTMTMTM, @kaoru0822-kitauji, @prasad2512, @rodricksz4h5, @xu91102.
|
||||
- **JavaScript value flow:** Preserve values captured before later assignments, guarded factory fallthrough and nested destructuring. Track exact property keys and setter writes; direct `eval`, compound assignments and incoming callbacks preserve unresolved effects instead of inventing certainty. ([#4196](https://github.com/morluto/rea/pull/4196), [morluto/rea#3881](https://github.com/morluto/rea/issues/3881), [#4341](https://github.com/morluto/rea/pull/4341), [morluto/rea#3963](https://github.com/morluto/rea/issues/3963), [bfb7ed0](https://github.com/morluto/rea/commit/bfb7ed0bd43edc605e00fc52c6e21e735b285904), [#3480](https://github.com/morluto/rea/pull/3480), [#3831](https://github.com/morluto/rea/pull/3831), [morluto/rea#3312](https://github.com/morluto/rea/issues/3312), [9ac76d3](https://github.com/morluto/rea/commit/9ac76d3d9486856d25395b413d7ac5ffa744cad0), [#4342](https://github.com/morluto/rea/pull/4342), [morluto/rea#4206](https://github.com/morluto/rea/issues/4206), [#4243](https://github.com/morluto/rea/pull/4243), [morluto/rea#3880](https://github.com/morluto/rea/issues/3880)). Thanks @coygeek, @kaoru0822-kitauji, @maxazure, @N0zoM1z0, @ShuaixinHuang.
|
||||
- **JavaScript relationships:** Distinguish `Map` reads from network endpoints, associate response endpoints only with writes that reach the read, and preserve child-process receiver ownership and effective stdio choices. Version comparisons keep relocation and unknown relationships distinct from application changes. ([fbfdb6a](https://github.com/morluto/rea/commit/fbfdb6abe9d663be0be146a15a489e33ccba0f68), [#4759](https://github.com/morluto/rea/pull/4759), [morluto/rea#4606](https://github.com/morluto/rea/issues/4606), [#3819](https://github.com/morluto/rea/pull/3819), [morluto/rea#3362](https://github.com/morluto/rea/issues/3362), [#4336](https://github.com/morluto/rea/pull/4336), [morluto/rea#3355](https://github.com/morluto/rea/issues/3355), [556504e](https://github.com/morluto/rea/commit/556504edcbb0f8cd9eaf81a91b18ff891b8f5457), [4d980d0](https://github.com/morluto/rea/commit/4d980d017622d3175d86aaf3b0dcfbdf4ca3d091)). Thanks @Abdooo2235, @coygeek, @kaoru0822-kitauji, @Xinglan233.
|
||||
- **JavaScript source admission:** Parse JavaScript with its own grammar, refuse FIFO recovery inputs without blocking, and report oversized or resource-skipped files with their actual capacity and coverage state. Malformed runtime events stay excluded rather than becoming policy-filtered facts. ([#3782](https://github.com/morluto/rea/pull/3782), [morluto/rea#3780](https://github.com/morluto/rea/issues/3780), [#3788](https://github.com/morluto/rea/pull/3788), [morluto/rea#3332](https://github.com/morluto/rea/issues/3332), [#4757](https://github.com/morluto/rea/pull/4757), [morluto/rea#4629](https://github.com/morluto/rea/issues/4629), [#3852](https://github.com/morluto/rea/pull/3852), [morluto/rea#3670](https://github.com/morluto/rea/issues/3670), [#4755](https://github.com/morluto/rea/pull/4755), [morluto/rea#4685](https://github.com/morluto/rea/issues/4685)). Thanks @andresaragon, @coygeek, @kaoru0822-kitauji, @sx4im.
|
||||
- **Browser capture:** Bound CDP handshakes and command responses, preserve malformed inventory uncertainty and partial cleanup diagnostics, and report cancellation after content reads and final cleanup. Accessibility comparisons require observed coverage; attached emulation teardown limits remain explicit. ([#3555](https://github.com/morluto/rea/pull/3555), [morluto/rea#3553](https://github.com/morluto/rea/issues/3553), [#3901](https://github.com/morluto/rea/pull/3901), [morluto/rea#3379](https://github.com/morluto/rea/issues/3379), [4cc044b](https://github.com/morluto/rea/commit/4cc044be68f813e96907e6cedcf422d0a3170de3), [#4406](https://github.com/morluto/rea/pull/4406), [morluto/rea#4403](https://github.com/morluto/rea/issues/4403), [#2893](https://github.com/morluto/rea/pull/2893), [0123d59](https://github.com/morluto/rea/commit/0123d5976828bfe621bd51daa4cf39fee48a1349), [2ff0867](https://github.com/morluto/rea/commit/2ff086796ad7b8f60397956750584e170dbe2910)). Thanks @coygeek, @dakjdakd, @kaoru0822-kitauji, @maxazure, @N0zoM1z0, @YunzhouLi-hub.
|
||||
- **Browser page facts:** Preserve URL path bytes when removing credentials, repeated document `Link` headers and complete COOP/COEP structured items. WebMCP discovery reads the actual schema properties and exact receiver path. ([#4731](https://github.com/morluto/rea/pull/4731), [df2fc25](https://github.com/morluto/rea/commit/df2fc251e318a1255309dba232f9f73c700777b6), [c360cfc](https://github.com/morluto/rea/commit/c360cfcd6d7901514b16dd6113eba2e0b0fdf422), [ebd5a82](https://github.com/morluto/rea/commit/ebd5a82c439f6deb3a06062225ce009eb03257cf), [38f92d1](https://github.com/morluto/rea/commit/38f92d108e3148cdf47e4ffbfe3de8a76e795d51)). Thanks @Abdooo2235, @geekwolf, @ShuaixinHuang.
|
||||
- **Electron runtime capture:** Keep native IPC listener and one-shot dispatch behavior, block synchronous shell effects during capture, refuse active scenarios when the inspect fuse is disabled, and preserve fuse/transport cleanup ownership. ([#4389](https://github.com/morluto/rea/pull/4389), [morluto/rea#4390](https://github.com/morluto/rea/issues/4390), [#4605](https://github.com/morluto/rea/pull/4605), [morluto/rea#4593](https://github.com/morluto/rea/issues/4593), [#4562](https://github.com/morluto/rea/pull/4562), [morluto/rea#4393](https://github.com/morluto/rea/issues/4393), [#3605](https://github.com/morluto/rea/pull/3605), [morluto/rea#3453](https://github.com/morluto/rea/issues/3453), [f9de413](https://github.com/morluto/rea/commit/f9de41371f7536e2e22ce6e43c9314fa2f238a30), [e7df00e](https://github.com/morluto/rea/commit/e7df00e80777757b329bbe8aba6d421d8892b9d5)). Thanks @Adolanium, @gensokyo-dev, @gkobayashi0, @HarsH-1877, @kaoru0822-kitauji, @keeponlight, @N0zoM1z0, @Nitin13-git, @xu91102.
|
||||
- **APK resource accuracy:** Retain completed tables and decode facts after interrupted or failed reads. Derive locale limits from resource configuration fields, disclose unselectable qualified tables, distinguish document failures from omitted entries, and bind Evidence to the decoded snapshot. ([34a88d6](https://github.com/morluto/rea/commit/34a88d6c1674710953e2c94bd0a17332cd69ca6f), [f5fcf52](https://github.com/morluto/rea/commit/f5fcf5216ffb3a266b8c00f6d9a0943051084ab5), [6385ef4](https://github.com/morluto/rea/commit/6385ef4355d7a794b3154ee38529cbddee583336), [98886ad](https://github.com/morluto/rea/commit/98886adddfcbd7b4f4236b3a9825f91878c3cb11), [dc2e811](https://github.com/morluto/rea/commit/dc2e8117b60c4481372ed89b077e6c1cf81ee653), [#4771](https://github.com/morluto/rea/pull/4771), [morluto/rea#4768](https://github.com/morluto/rea/issues/4768)). Thanks @abhay-2108, @gensokyo-dev, @Iyanuoluwa007, @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **Apktool guidance:** Retain the observed version and disclose the matching platform/release advisory windows without treating a version string as proof of decoder safety. Missing prerequisites and decode refusals identify the selected APK or launcher. ([d38f099](https://github.com/morluto/rea/commit/d38f099692394ec90c582f9f0a14b036b421b160), [63696d2](https://github.com/morluto/rea/commit/63696d277328f556c971d1fc9f81ae83128d468b), [cc038da](https://github.com/morluto/rea/commit/cc038da218cada68c87700477aba3db4739791ff)). Thanks @GovinduSasanka, @peter-research.
|
||||
- **Android method bodies:** Recover original bytecode bodies when Java source is omitted while preserving genuine native/abstract body absence and primary failures during retryable cleanup. ([63c65a2](https://github.com/morluto/rea/commit/63c65a22430a4bbc0c1807a0298edb867775001f), [742b6f5](https://github.com/morluto/rea/commit/742b6f587f3c4ef1b8212e7376d6f3a305b194dc), [9fa6d2b](https://github.com/morluto/rea/commit/9fa6d2b254cc390665974efb52463386a029e9fc)). Thanks @balkan16, @Chessing234.
|
||||
- **ADB observations and transfers:** Preserve display-scoped focus, distinguish missing declarations from absent focus, retain numeric physical density and mark unknown permission coverage partial. Transfers use consumed snapshot identity and refuse unknown destination existence; uninstall requests explicitly select user zero. ([7086768](https://github.com/morluto/rea/commit/7086768a27242a15daa93486aefbaacc3c891e78), [3d028db](https://github.com/morluto/rea/commit/3d028dbc74a465f6f8df1813a931fbb5362e7dc3), [#4074](https://github.com/morluto/rea/pull/4074), [morluto/rea#3942](https://github.com/morluto/rea/issues/3942), [#4663](https://github.com/morluto/rea/pull/4663), [#4665](https://github.com/morluto/rea/pull/4665), [1342127](https://github.com/morluto/rea/commit/1342127e91d4db8b4113a7a4e85be909bc96e1db), [61e6880](https://github.com/morluto/rea/commit/61e688070f48016b6d178cd04c02fcc2f33e19ad), [be0b2d1](https://github.com/morluto/rea/commit/be0b2d138c46bb951fc3c8ee57ef7b0d57fed312)). Thanks @Copilot, @coygeek, @gongfpp, @Tapraj-Pathak, @yankikucuk.
|
||||
- **Apple metadata:** Preserve exact plist/keyed-archive integers, negative zero, non-finite real identity and dictionary keys. Reject malformed XML before value decoding, retain undecodable dates as unknown and report unsupported OpenStep entries explicitly. ([#4324](https://github.com/morluto/rea/pull/4324), [morluto/rea#4292](https://github.com/morluto/rea/issues/4292), [2cf9c28](https://github.com/morluto/rea/commit/2cf9c28f27261b7e64af2ba7ecb4e23ea7714aee), [#4839](https://github.com/morluto/rea/pull/4839), [morluto/rea#4834](https://github.com/morluto/rea/issues/4834), [f2b7bbb](https://github.com/morluto/rea/commit/f2b7bbb31279a820f4cf32d439570f8e5381d010), [6c98708](https://github.com/morluto/rea/commit/6c98708793c23615de8053b2cd14d9f164b960c5), [78cf610](https://github.com/morluto/rea/commit/78cf6100f33ad2412c0a3d60b83f8a44a43fbbb5), [c7e9e09](https://github.com/morluto/rea/commit/c7e9e096d3e2444e4c251123b8e914e9c0941f4e), [#3793](https://github.com/morluto/rea/pull/3793), [#4105](https://github.com/morluto/rea/pull/4105), [morluto/rea#3892](https://github.com/morluto/rea/issues/3892)). Thanks @coygeek, @kaoru0822-kitauji, @mertkayacs, @pablodiazjorge, @pollychen-lab, @xu91102.
|
||||
- **Apple application structure:** Derive bundle components and launchd domains from their owning directories, retain unavailable components, and select only exact `Assets.car` names as asset catalogs. Interface Builder keeps unresolved classes and counts hierarchy records beyond the returned object page. ([149a0fc](https://github.com/morluto/rea/commit/149a0fc06c3c67ee45624e6da14dfb0754473758), [5d6029e](https://github.com/morluto/rea/commit/5d6029ea62a65ec34fd739ee40223c77c6fdb63b), [c192c58](https://github.com/morluto/rea/commit/c192c58815ddeaf5cf30159e7082c742c0bc36b7), [#4094](https://github.com/morluto/rea/pull/4094), [morluto/rea#3914](https://github.com/morluto/rea/issues/3914), [#4118](https://github.com/morluto/rea/pull/4118), [morluto/rea#3958](https://github.com/morluto/rea/issues/3958), [#4162](https://github.com/morluto/rea/pull/4162), [morluto/rea#3950](https://github.com/morluto/rea/issues/3950)). Thanks @coygeek, @kaoru0822-kitauji.
|
||||
- **Native names and layout:** Keep valid Objective-C records beside malformed neighbors, preserve leading U+FEFF and repeated load-command fields, and select exact arm64e.x1 slices. PE resource ownership and NativeAOT reads stay within declared image/header ranges. ([#3833](https://github.com/morluto/rea/pull/3833), [morluto/rea#3336](https://github.com/morluto/rea/issues/3336), [#4549](https://github.com/morluto/rea/pull/4549), [morluto/rea#4540](https://github.com/morluto/rea/issues/4540), [morluto/rea#4541](https://github.com/morluto/rea/issues/4541), [#4730](https://github.com/morluto/rea/pull/4730), [#4048](https://github.com/morluto/rea/pull/4048), [morluto/rea#4008](https://github.com/morluto/rea/issues/4008), [#3500](https://github.com/morluto/rea/pull/3500), [morluto/rea#3389](https://github.com/morluto/rea/issues/3389), [#4463](https://github.com/morluto/rea/pull/4463), [morluto/rea#4373](https://github.com/morluto/rea/issues/4373), [morluto/rea#4455](https://github.com/morluto/rea/issues/4455), [3fc0075](https://github.com/morluto/rea/commit/3fc007534bb2104d662b43cc712281f9d1d6a7d3), [4a076f3](https://github.com/morluto/rea/commit/4a076f368c62bdfb19415accad342e03a38d1005)). Thanks @coygeek, @Iyanuoluwa007, @jayinvers, @kaoru0822-kitauji, @kevinjosh10, @maxazure, @ShuaixinHuang.
|
||||
- **Native analysis providers:** Keep Ghidra byte matches within examined coverage, retain PE PDB/function-boundary limitations and preserve configured MIPS choices. Attached IDA refuses universal Mach-O rather than silently choosing a slice; request timeout identity and captured output survive adapter handling. ([#4531](https://github.com/morluto/rea/pull/4531), [#2933](https://github.com/morluto/rea/pull/2933), [morluto/rea#2259](https://github.com/morluto/rea/issues/2259), [01a1b3f](https://github.com/morluto/rea/commit/01a1b3fda6a7dacd24a0b10619d41d12153080d4), [50dd9fc](https://github.com/morluto/rea/commit/50dd9fcad1efb47cb404192c30bdf190dcdaca58), [#4765](https://github.com/morluto/rea/pull/4765), [morluto/rea#3871](https://github.com/morluto/rea/issues/3871), [c0cfccb](https://github.com/morluto/rea/commit/c0cfccb45fe43e7eeff18e56c64caa5b121988f9)). Thanks @BeLit-Development-2, @coygeek, @kaoru0822-kitauji, @N0zoM1z0, @ShuaixinHuang.
|
||||
- **Recorded crashes:** Prevent GDB from discovering an executable named by an untrusted core, reject core mapping paths that escape the isolated sysroot, and preserve pwntools worker ownership across launcher exec. Completed decode facts and cancellation reasons remain available through failed final cleanup. ([5bf4fff](https://github.com/morluto/rea/commit/5bf4fffc1b835130ddb16f96db9ce13b639591db), [b33c0df](https://github.com/morluto/rea/commit/b33c0df02e93fabca00a44f2de625b1a63637ee9), [#4435](https://github.com/morluto/rea/pull/4435), [morluto/rea#4011](https://github.com/morluto/rea/issues/4011)). Thanks @coygeek, @N0zoM1z0.
|
||||
- **Cutter and Rizin:** Read Cutter’s active document from core configuration and attribute its host version correctly. Keep interrupted Rizin frames and output whitespace before completion markers, with exact command and cleanup failure attribution. ([#4507](https://github.com/morluto/rea/pull/4507), [morluto/rea#4497](https://github.com/morluto/rea/issues/4497), [#4514](https://github.com/morluto/rea/pull/4514), [morluto/rea#4498](https://github.com/morluto/rea/issues/4498), [#4459](https://github.com/morluto/rea/pull/4459), [morluto/rea#4015](https://github.com/morluto/rea/issues/4015), [d5fc7e6](https://github.com/morluto/rea/commit/d5fc7e6ebf9af050081fc4c6e18b9079cfaa5cdc), [199396f](https://github.com/morluto/rea/commit/199396f61c8f61da326d059606a992304a760147)). Thanks @coygeek, @N0zoM1z0, @Xander-AJ.
|
||||
- **Windows cleanup:** Retain unpublished runtimes after failed removal, handle read-only attributes and sharing conflicts, preserve primary snapshot failures and honor caller environment overrides. ([f78d137](https://github.com/morluto/rea/commit/f78d137b42741a0ed5fb8ac161286f9a50220c4d), [d69acc3](https://github.com/morluto/rea/commit/d69acc3455c33f90a2fc4381db43d38b6af50622), [0679a79](https://github.com/morluto/rea/commit/0679a7972b4f2b02eee6a86a44f50f4c2967d3cb), [5f9ac2c](https://github.com/morluto/rea/commit/5f9ac2c98a6fe11988c41afb737df9b6d5c3a1b3), [1bbf4bd](https://github.com/morluto/rea/commit/1bbf4bd16ca134cdb2187eaf29291cae90d14a57)). Thanks @DeryFerd.
|
||||
- **Managed metadata:** Compare nominal signatures and declaring identities across builds, preserve empty names without display substitutions, verify ABI-prefixed Mach-O exports exactly, and charge cached metadata once. Metadata errors report artifact file offsets; mixed-mode assemblies retain their actual boundary classification. ([#3059](https://github.com/morluto/rea/pull/3059), [#3079](https://github.com/morluto/rea/pull/3079), [#3853](https://github.com/morluto/rea/pull/3853), [morluto/rea#3352](https://github.com/morluto/rea/issues/3352), [#3974](https://github.com/morluto/rea/pull/3974), [morluto/rea#3961](https://github.com/morluto/rea/issues/3961), [#3491](https://github.com/morluto/rea/pull/3491), [morluto/rea#3449](https://github.com/morluto/rea/issues/3449), [#4418](https://github.com/morluto/rea/pull/4418), [morluto/rea#4372](https://github.com/morluto/rea/issues/4372), [#3516](https://github.com/morluto/rea/pull/3516), [morluto/rea#3366](https://github.com/morluto/rea/issues/3366)). Thanks @8rulerstar, @coygeek, @duckhunt113, @Hahaa909, @JayOfTheKeyboard, @kaoru0822-kitauji, @keeponlight, @N0zoM1z0, @tomyrms.
|
||||
- **Archive and filesystem identity:** Reject colliding extraction paths before writing, classify ZIP offsets beyond EOF as malformed, normalize ZIP current-directory prefixes once, and preserve symlink and unreadable-path provenance. A directory named `*.map` is no longer mistaken for a source-map file. ([862a0b2](https://github.com/morluto/rea/commit/862a0b2631785492f8dc20c8acd396646c545fd1), [c209dcb](https://github.com/morluto/rea/commit/c209dcb209118069f123e789949eeba1ef78853e), [6b1c36e](https://github.com/morluto/rea/commit/6b1c36e336eeacbb7159b211e687b4b84f99b9f5), [25c2222](https://github.com/morluto/rea/commit/25c22222abe7a681491bdb4d7316250fdcf32973), [d6e4fe4](https://github.com/morluto/rea/commit/d6e4fe4a4dd8914ec3db50d2a7fc3d0802649262), [#4131](https://github.com/morluto/rea/pull/4131), [morluto/rea#3909](https://github.com/morluto/rea/issues/3909)). Thanks @Adkid-Zephyr, @coygeek, @jackie-cqz, @kaoru0822-kitauji, @maxazure, @XY-code1.
|
||||
- **Evidence and reconstruction:** Authenticate all retained inventory substeps, preserve source-attributed caveats in composed workflows, and require comparable cited Evidence before declaring reconstruction coverage or readiness. Missing Evidence and residual replay uncertainty stay explicit. ([9ac91e0](https://github.com/morluto/rea/commit/9ac91e0c1e13e91cd21341635ad5be89b0e8642d), [c4608a2](https://github.com/morluto/rea/commit/c4608a29620ea3e7bb8259b47357b942fe4e4709), [#4075](https://github.com/morluto/rea/pull/4075), [morluto/rea#3357](https://github.com/morluto/rea/issues/3357), [#3526](https://github.com/morluto/rea/pull/3526), [morluto/rea#3363](https://github.com/morluto/rea/issues/3363), [153017d](https://github.com/morluto/rea/commit/153017d750322188c1a112b2284c1b8065c67320)). Thanks @coygeek, @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0, @rudycelekli.
|
||||
- **Offline data:** Preserve exact UTC packet-capture instants, SQLite column identity and snapshot admission failures, and cooked WASM directive literals. Cleanup cancellation retains completed EVM/WASM observations rather than losing them. ([796faa0](https://github.com/morluto/rea/commit/796faa0e4e6bf745bcdc33acef65af8ccfc3622d), [748ac7f](https://github.com/morluto/rea/commit/748ac7f0df340f0d0569eca2e803a59cd51ffdbd), [bc51d0e](https://github.com/morluto/rea/commit/bc51d0ea5df7dcee1fcc42dfae3ab0c62c9cca5e), [4f87f02](https://github.com/morluto/rea/commit/4f87f02bb19bf77349a683a5bcb2da2d1da427d0), [d694aef](https://github.com/morluto/rea/commit/d694aef227e90164e6654ea9e5ce6a854d099404), [321cacb](https://github.com/morluto/rea/commit/321cacb84a020f447e1110df5c58fa71d99b7bf1)). Thanks @himamaheswarreddy, @mertkayacs, @rollroyces, @viniciusdsandrade.
|
||||
- **Kuna recovery:** Share concurrent single-function requests and cache repeats, validate warm exports once, stream string inventories beyond the former fixed buffer ceiling, and keep unproven processes in their run slots until close confirms release. Failure messages distinguish final buffer refusals from configurable deadlines. ([#4045](https://github.com/morluto/rea/pull/4045), [#4169](https://github.com/morluto/rea/pull/4169), [#4049](https://github.com/morluto/rea/pull/4049), [#4318](https://github.com/morluto/rea/pull/4318), [#4052](https://github.com/morluto/rea/pull/4052), [#4098](https://github.com/morluto/rea/pull/4098), [#4343](https://github.com/morluto/rea/pull/4343)). Thanks @kaoru0822-kitauji.
|
||||
- **Flutter snapshots:** Check symbol-table ranges against loadable segments and retain completed inspection facts when cancellation occurs during snapshot cleanup. ([#3859](https://github.com/morluto/rea/pull/3859), [morluto/rea#3346](https://github.com/morluto/rea/issues/3346), [#4766](https://github.com/morluto/rea/pull/4766), [morluto/rea#4717](https://github.com/morluto/rea/issues/4717), [#4762](https://github.com/morluto/rea/pull/4762), [morluto/rea#4640](https://github.com/morluto/rea/issues/4640)). Thanks @coygeek, @kaoru0822-kitauji.
|
||||
- **Native metadata recovery:** Keep unknown Objective-C category classes, empty protocol names, undecoded Swift aliases and unfinished property types explicit instead of discarding neighboring valid records. Preserve unnamed segment identity and exclude a dylib’s own install name from dependencies. ([#4093](https://github.com/morluto/rea/pull/4093), [morluto/rea#4012](https://github.com/morluto/rea/issues/4012), [#4078](https://github.com/morluto/rea/pull/4078), [morluto/rea#3873](https://github.com/morluto/rea/issues/3873), [#4085](https://github.com/morluto/rea/pull/4085), [morluto/rea#3934](https://github.com/morluto/rea/issues/3934), [#3825](https://github.com/morluto/rea/pull/3825), [morluto/rea#3345](https://github.com/morluto/rea/issues/3345), [#4051](https://github.com/morluto/rea/pull/4051), [morluto/rea#3875](https://github.com/morluto/rea/issues/3875), [#4050](https://github.com/morluto/rea/pull/4050), [morluto/rea#3872](https://github.com/morluto/rea/issues/3872)). Thanks @coygeek, @kaoru0822-kitauji.
|
||||
- **Document selection:** Preserve explicitly selected plist paths and bundle defaults, and only use document fallback after confirming its applicability. Finalization keeps completed selection facts and cancellation outcomes. ([e6c4877](https://github.com/morluto/rea/commit/e6c487799bb64f559e66b69be1863e6ec5187548), [#3774](https://github.com/morluto/rea/pull/3774), [9df559b](https://github.com/morluto/rea/commit/9df559b7e712298a761ff26e9caae8d659b7e54b)). Thanks @kaoru0822-kitauji.
|
||||
- **Capture and comparison accuracy:** Admit schema-valid HAR numeric values while retaining exact-publication limits, preserve empty URL path segments, and keep unrelated process traces and unnamed reference endpoints distinct or unknown. ([#3159](https://github.com/morluto/rea/pull/3159), [morluto/rea#3145](https://github.com/morluto/rea/issues/3145), [#3792](https://github.com/morluto/rea/pull/3792), [morluto/rea#3307](https://github.com/morluto/rea/issues/3307), [#4178](https://github.com/morluto/rea/pull/4178), [morluto/rea#3931](https://github.com/morluto/rea/issues/3931), [#3809](https://github.com/morluto/rea/pull/3809), [morluto/rea#3388](https://github.com/morluto/rea/issues/3388)). Thanks @coygeek, @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0, @pablodiazjorge, @xu91102.
|
||||
- **Evidence publication:** Recheck staged output identity after its final write, classify missing review Evidence and duplicate ledger entries as caller input, and preserve the selected freshness requirement in comparison parameters. ([#4764](https://github.com/morluto/rea/pull/4764), [morluto/rea#4613](https://github.com/morluto/rea/issues/4613), [#4452](https://github.com/morluto/rea/pull/4452), [morluto/rea#4444](https://github.com/morluto/rea/issues/4444), [#4065](https://github.com/morluto/rea/pull/4065), [morluto/rea#4000](https://github.com/morluto/rea/issues/4000)). Thanks @amyanger, @coygeek, @kaoru0822-kitauji, @Rinkia, @Swatantra-66.
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
- **Saved Evidence:** Evidence and analysis snapshots now require explicit nullable `relationship_coverage` in their identity commitments. Artifact inventories require scoped coverage and explicit `integrity_contradictions`; obsolete `coverage_status` and prose-based coverage inference are removed. Regenerate old Evidence/snapshots and inventory observations with this release: saved files are not migrated and omitted facts are not filled with guessed defaults. ([db8128d](https://github.com/morluto/rea/commit/db8128dc0d1c4f731f3d19877fa00d25cf17f657), [0405c9d](https://github.com/morluto/rea/commit/0405c9d361de6d904dfa16cc0b6d8350407f2c9b), [a9588be](https://github.com/morluto/rea/commit/a9588be4ebdd20eeda975cb63ffcdb1cd868b340)).
|
||||
- **Browser capture results:** Consumers must retain resolved capture limits, event families and omission facts. Set desired budgets through the supported capture options; omitted caller inputs still select defaults, but stored observations must report the resolved values. Admitted content reads queue behind bounded concurrency. ([57a23f0](https://github.com/morluto/rea/commit/57a23f0a2da0fdc3835e203718ded8acea5a34e6)).
|
||||
- **Android version codes:** `inspect_adb_package.version_code` is a decimal string rather than a JSON number. Read it as a string, or use `BigInt` for numeric comparison. ([#3485](https://github.com/morluto/rea/pull/3485), [morluto/rea#3368](https://github.com/morluto/rea/issues/3368), [7666a48](https://github.com/morluto/rea/commit/7666a482b69dc7cabdbac3bbaf89a43e32300192)). Thanks @coygeek, @kaoru0822-kitauji.
|
||||
- **Native UI failures:** Failed or cancelled native UI scenarios now return typed errors with the collected report in `partial_observation`. Handle the error path and read that report instead of expecting a successful result containing failed steps. ([d909919](https://github.com/morluto/rea/commit/d9099190ab3a819bd3a9fd62a8714cef398016d5)).
|
||||
- **Provider status:** `binary_session` candidate availability can be unknown during owner finalization. Preserve that state rather than treating it as unavailable; internal consumers must await the asynchronous session status API. ([150e996](https://github.com/morluto/rea/commit/150e996a86f2bec4982ba87f37bf502a8d5e8214)).
|
||||
- **Swift symbol locations:** `swift_symbols` entries may have a null `address` when the provider supplies no location. Handle unknown addresses; optional `evidence.reported_address` retains the original provider value. ([8116dc0](https://github.com/morluto/rea/commit/8116dc06512b4609d8db63cebc9f2ff8cb964151)).
|
||||
- **Linux Hopper admission:** Older builds previously admitted by a fixed allowlist need retained publisher-signed package evidence or an approved update to the current public demo. Update explicit `HOPPER_LAUNCHER_PATH` selections when migrating; the live feed offers only its current release. The official RPM metadata mismatch remains unresolved and is refused. ([#3590](https://github.com/morluto/rea/pull/3590), [morluto/rea#3577](https://github.com/morluto/rea/issues/3577), [70cd4cb](https://github.com/morluto/rea/commit/70cd4cbfb849b61f05d97d2690372a9782831426)). Thanks @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0.
|
||||
|
||||
Full contribution record: [571 commits and 236 merged PRs](https://github.com/morluto/rea/blob/rea-agents-6.6.0/docs/releases/6.6.0.contributions.json).
|
||||
|
||||
## [6.5.0](https://github.com/morluto/rea/compare/rea-agents-6.4.0...rea-agents-6.5.0) (2026-10-13)
|
||||
|
||||
Provider prerequisites and recorded verification scope are listed in [the testing guide](docs/testing.md).
|
||||
|
||||
+1
-24
@@ -21,9 +21,6 @@ For analysis workflows and agent interfaces, follow the
|
||||
[performance priorities](AGENTS.md#performance). Explain the selected output
|
||||
scope, reuse/cache decisions, and relevant before/after measurements when these
|
||||
costs change.
|
||||
Use the [analysis optimization skill](.agents/skills/rea-analysis-optimization/SKILL.md)
|
||||
to locate provider and shared-workflow bottlenecks, preserve Evidence, and
|
||||
compare equivalent real tasks before claiming an improvement.
|
||||
|
||||
When adding or changing an MCP tool, follow the [tool design guide](docs/tool-design.md) and preserve the canonical contracts and generated catalog.
|
||||
|
||||
@@ -228,10 +225,7 @@ manifest. A source checkout does not: `native/windows/build/` is ignored by
|
||||
Git, and neither `npm ci` nor `npm run build:cached` (or `npm run build`)
|
||||
produces `rea-windows-x64.node` or `manifest.json` in that directory.
|
||||
Windows workflows and tests that require native controls need these artifacts;
|
||||
this includes `run-exclusive` commands, which use the native Job Object to keep
|
||||
the artifact lock until every command descendant has exited. Without the
|
||||
artifacts, those controls are unavailable even after a successful runtime
|
||||
build.
|
||||
without them, those controls are unavailable even after a successful runtime build.
|
||||
|
||||
Follow the [Windows native build guide](native/windows/README.md#build) before
|
||||
running those workflows from source. The artifact build requires Linux,
|
||||
@@ -261,23 +255,6 @@ The separate GitHub Pages host uses only the manual
|
||||
**Settings → Pages → Build and deployment → Source** must be set to
|
||||
**GitHub Actions** before deploying there.
|
||||
|
||||
### Translation corrections
|
||||
|
||||
README editions and website editions have separate translation sources:
|
||||
|
||||
- Find the language's `readme` path in the
|
||||
[language inventory](website/locales/languages.json) and edit that file.
|
||||
Locale codes and README suffixes can differ. Use the
|
||||
[English README](README.md) to check commands, requirements, and analysis claims.
|
||||
- Edit `msgstr` values in `website/locales/<language>/messages.po` for website
|
||||
text. Follow the [website translation guide](website/locales/README.md) for
|
||||
the Python environment, catalog validation, and local preview. Preserve source
|
||||
strings, contexts, placeholders, commands, paths, and recorded evidence.
|
||||
|
||||
Before submitting a website translation, run the catalog and website checks in
|
||||
that guide. Translated HTML in `website/_site/` is generated; edit the PO catalog
|
||||
rather than the generated pages.
|
||||
|
||||
## Development feedback and PR verification
|
||||
|
||||
For routine merges, wait for the required checks to pass for the current PR
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
**English** · [简体中文](docs/readme/README_zh.md) · [繁體中文](docs/readme/README_zh-TW.md) · [日本語](docs/readme/README_ja.md) · [한국어](docs/readme/README_ko.md) · [Türkçe](docs/readme/README_tr.md) · [Русский](docs/readme/README_ru.md) · [Tiếng Việt](docs/readme/README_vi.md) · [ไทย](docs/readme/README_th.md) · [Deutsch](docs/readme/README_de.md) · [Español](docs/readme/README_es.md) · [Français](docs/readme/README_fr.md) · [Українська](docs/readme/README_uk.md) · [Polski](docs/readme/README_pl.md) · [Português (Brasil)](docs/readme/README_pt-BR.md) · [العربية](docs/readme/README_ar.md) · [فارسی](docs/readme/README_fa.md) · [Bahasa Indonesia](docs/readme/README_id.md) · [Italiano](docs/readme/README_it.md)
|
||||
· [Ελληνικά](docs/readme/README_el.md) · [മലയാളം](docs/readme/README_ml.md)
|
||||
· [Ελληνικά](docs/readme/README_el.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -132,14 +132,6 @@ For a CLI installed with `npm install --global` or `bun add --global`:
|
||||
rea update
|
||||
```
|
||||
|
||||
`rea --update` is an alias for this verified workflow and accepts the same global
|
||||
output flags. Use `rea update` when combining it with other command controls.
|
||||
|
||||
Updater commands retain at most 4 MiB of stdout and stderr combined. Oversized
|
||||
metadata replies are rejected after the command exits; verbose installs continue
|
||||
with bounded diagnostics. Human progress output respects terminal backpressure
|
||||
and waits for submitted writes to finish.
|
||||
|
||||
Bun global updates require Bun 1.2.17 or later. With an older Bun release,
|
||||
upgrade Bun manually before running `rea update`.
|
||||
|
||||
@@ -213,8 +205,7 @@ or update either provider.
|
||||
|
||||
Native formats and host support vary by provider. See
|
||||
[Hopper and Ghidra setup](docs/installation.md#hopper), the
|
||||
[IDA guide](docs/ida-provider.md) (including an optional native MCP bridge), the
|
||||
[Kuna decompiler guide](docs/kuna-provider.md), and
|
||||
[IDA guide](docs/ida-provider.md) (including an optional native MCP bridge), and
|
||||
[experimental Windows Ghidra support](docs/windows-ghidra-p0.md).
|
||||
Ghidra also supports [16-bit DOS analysis](docs/ghidra-dos.md).
|
||||
For large binaries, raise the provider's startup deadline with
|
||||
@@ -353,7 +344,7 @@ Report vulnerabilities through [SECURITY.md](SECURITY.md).
|
||||
|
||||
## Star history
|
||||
|
||||
🎉 **300,000 GitHub stars — thank you!**
|
||||
🎉 **200,000 GitHub stars — thank you!**
|
||||
|
||||
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ pin inspection sources; they are not included in the npm package.
|
||||
| ghidra-nativeaot | [MIT](https://github.com/Washi1337/ghidra-nativeaot/blob/effeb734fc570c32650f88b159608979dc7b423e/LICENSE.md) | Pinned inspection source; derived parser attribution above. |
|
||||
| JADX | [Apache-2.0](https://github.com/skylot/jadx/blob/v1.5.6/LICENSE) | The audited jadx-headless-mcp source uses JADX 1.5.6 for Android decompilation; the engine JAR is separately supplied. |
|
||||
| jadx-headless-mcp | [Apache-2.0](https://github.com/1013503897/jadx-headless-mcp/blob/5844800a486d2248fa949b74c9896285f5b54de2/LICENSE) | v0.7.1; pinned submodule and user-supplied JAR. |
|
||||
| Kuna | [Apache-2.0](https://github.com/Noelo-Lab/kuna/blob/v1.833/LICENSE), with its [NOTICE](https://github.com/Noelo-Lab/kuna/blob/v1.833/NOTICE) | Bring your own `kuna`; REA verified 1.833 and never downloads, installs or bundles it. REA invokes it as a separate process. |
|
||||
| Apktool | [Apache-2.0](https://github.com/iBotPeaches/Apktool/blob/master/LICENSE.md) | User-supplied Android resource decoder. |
|
||||
| Binwalk | [MIT](https://github.com/ReFirmLabs/binwalk/blob/4fdab3d464d97b68e0af9088df3f9e2e1545b21c/LICENSE) | v3.1.0; pinned submodule and user-supplied firmware engine. |
|
||||
| Unblob | [MIT](https://github.com/onekey-sec/unblob/blob/1fcc7a0a584a70a96c31f5a276c20944d199a089/LICENSE) | 26.6.4; pinned submodule and user-supplied firmware engine. |
|
||||
|
||||
@@ -15,14 +15,11 @@ import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.stream.Collectors;
|
||||
import kotlin.Unit;
|
||||
import kotlin.ResultKt;
|
||||
import kotlin.coroutines.Continuation;
|
||||
import kotlin.coroutines.CoroutineContext;
|
||||
import kotlin.coroutines.EmptyCoroutineContext;
|
||||
import kotlin.coroutines.intrinsics.IntrinsicsKt;
|
||||
import kotlinx.coroutines.BuildersKt;
|
||||
import kotlinx.io.CoreKt;
|
||||
import kotlinx.io.JvmCoreKt;
|
||||
import kotlinx.serialization.json.JsonObject;
|
||||
|
||||
/** REA-owned metadata boundary for the unmodified jadx-headless-mcp 0.7.1 JAR. */
|
||||
class ReaJadxBridge {
|
||||
@@ -31,8 +28,7 @@ class ReaJadxBridge {
|
||||
private JadxSession indexedSession;
|
||||
private Map<String, List<ClassSnapshot>> classes = Map.of();
|
||||
|
||||
private record MethodSnapshot(String name, String rawName, String shortId, List<String> bodyAbsenceMarkers,
|
||||
Map<String, Object> summary) {}
|
||||
private record MethodSnapshot(String name, String shortId, Map<String, Object> summary) {}
|
||||
private record ClassSnapshot(JavaClass node, List<MethodSnapshot> methods, Map<String, Object> summary) {}
|
||||
|
||||
private static final class InputFailure extends IllegalArgumentException {
|
||||
@@ -48,93 +44,15 @@ class ReaJadxBridge {
|
||||
|
||||
private static CallToolResult json(Object value) { return text(JSON.toJson(value), false); }
|
||||
|
||||
/** Translate the typed load outcome before upstream drops its exception identity. */
|
||||
static Object loadResult(Object result) {
|
||||
try { ResultKt.throwOnFailure(result); }
|
||||
catch (Throwable failure) {
|
||||
if (failure instanceof java.util.concurrent.CancellationException
|
||||
|| failure instanceof Error && !(failure instanceof OutOfMemoryError)) return result;
|
||||
if (failure instanceof OutOfMemoryError) {
|
||||
String reason = failure.getMessage();
|
||||
boolean heap = "Java heap space".equals(reason) || "GC overhead limit exceeded".equals(reason);
|
||||
Map<String, Object> reply = new LinkedHashMap<>();
|
||||
reply.put("kind", "jvm-memory-failure");
|
||||
reply.put("memory_area", heap ? "heap" : "unknown");
|
||||
reply.put("exception_type", "java.lang.OutOfMemoryError");
|
||||
if (reason != null) reply.put("message", reason);
|
||||
reply.put("max_heap_bytes", Runtime.getRuntime().maxMemory());
|
||||
return text(JSON.toJson(reply), true);
|
||||
}
|
||||
return text("load failed: " + failure.getMessage(), true);
|
||||
}
|
||||
SessionHolder.LoadResult loaded = (SessionHolder.LoadResult) result;
|
||||
Map<String, Object> reply = new LinkedHashMap<>();
|
||||
reply.put("state", "LOADED");
|
||||
reply.put("apk_path", loaded.getApkPath());
|
||||
reply.put("class_count", loaded.getClassCount());
|
||||
reply.put("raw_class_count", loaded.getRawClassCount());
|
||||
reply.put("resource_count", loaded.getResourceCount());
|
||||
reply.put("load_duration_ms", loaded.getLoadDurationMs());
|
||||
reply.put("decompile_timeout_ms", loaded.getDecompileTimeoutMs());
|
||||
reply.put("threads", loaded.getThreads());
|
||||
reply.put("code_cache_size", loaded.getCodeCacheSize());
|
||||
reply.put("resources", loaded.getResourceMode());
|
||||
if (!loaded.getIncludePackages().isEmpty()) reply.put("include_packages", loaded.getIncludePackages());
|
||||
if (!loaded.getExcludePackages().isEmpty()) reply.put("exclude_packages", loaded.getExcludePackages());
|
||||
return json(reply);
|
||||
}
|
||||
|
||||
private Object load(kotlinx.serialization.json.JsonObject arguments, SessionConfig defaults,
|
||||
Continuation<? super CallToolResult> continuation) {
|
||||
JsonObject args = JsonParser.parseString(arguments.toString()).getAsJsonObject();
|
||||
String path = string(args, "path");
|
||||
SessionConfig options = defaults.withLoadOverrides(
|
||||
optionalString(args, "include_packages"), optionalString(args, "exclude_packages"),
|
||||
args.has("threads") ? integer(args, "threads", 1) : null,
|
||||
args.has("code_cache_size") ? integer(args, "code_cache_size", 64) : null,
|
||||
optionalString(args, "resources"));
|
||||
return loadCall(next -> holder.load(path, options, next), continuation);
|
||||
}
|
||||
|
||||
static Object loadCall(kotlin.jvm.functions.Function1<Continuation<SessionHolder.LoadResult>, Object> load,
|
||||
Continuation<? super CallToolResult> continuation) {
|
||||
var forwarded = new java.util.concurrent.atomic.AtomicBoolean();
|
||||
Continuation<SessionHolder.LoadResult> resumed = new Continuation<>() {
|
||||
public CoroutineContext getContext() { return continuation.getContext(); }
|
||||
public void resumeWith(Object result) {
|
||||
if (!forwarded.compareAndSet(false, true)) throw new IllegalStateException("Load resumed twice");
|
||||
Object translated;
|
||||
try { translated = loadResult(result); }
|
||||
catch (Throwable failure) { translated = ResultKt.createFailure(failure); }
|
||||
// Keep the consumer outside the translation catch, including inline completion.
|
||||
continuation.resumeWith(translated);
|
||||
}
|
||||
};
|
||||
Object result;
|
||||
try { result = load.invoke(resumed); }
|
||||
catch (Throwable failure) {
|
||||
if (forwarded.get()) ResultKt.throwOnFailure(ResultKt.createFailure(failure));
|
||||
result = ResultKt.createFailure(failure);
|
||||
}
|
||||
if (result == IntrinsicsKt.getCOROUTINE_SUSPENDED()) return result;
|
||||
Object translated = loadResult(result);
|
||||
ResultKt.throwOnFailure(translated);
|
||||
return translated;
|
||||
}
|
||||
|
||||
private static String optionalString(JsonObject args, String name) {
|
||||
return args.has(name) ? string(args, name) : null;
|
||||
}
|
||||
|
||||
private static String string(JsonObject args, String name) {
|
||||
JsonElement value = args.get(name);
|
||||
JsonElement value = JsonParser.parseString(args.toString()).getAsJsonObject().get(name);
|
||||
if (value == null || !value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString())
|
||||
throw new IllegalArgumentException(name + " must be a string");
|
||||
return value.getAsString();
|
||||
}
|
||||
|
||||
private static int integer(JsonObject args, String name, int fallback) {
|
||||
JsonElement value = args.get(name);
|
||||
JsonElement value = JsonParser.parseString(args.toString()).getAsJsonObject().get(name);
|
||||
if (value == null) return fallback;
|
||||
if (!value.isJsonPrimitive() || !value.getAsJsonPrimitive().isNumber())
|
||||
throw new IllegalArgumentException(name + " must be a nonnegative integer");
|
||||
@@ -172,13 +90,10 @@ class ReaJadxBridge {
|
||||
if (!shortId.startsWith(rawName + "("))
|
||||
throw new IllegalStateException("JADX method ID has no raw-name prefix: " + shortId);
|
||||
String descriptor = shortId.substring(rawName.length());
|
||||
List<String> bodyAbsenceMarkers = new ArrayList<>();
|
||||
if (method.getAccessFlags().isNative()) bodyAbsenceMarkers.add("native_method");
|
||||
if (method.getAccessFlags().isAbstract()) bodyAbsenceMarkers.add("abstract_method");
|
||||
String signature = name + "(" + method.getArgTypes().stream()
|
||||
.map(Object::toString).collect(Collectors.joining(", "))
|
||||
+ "): " + method.getReturnType().toString();
|
||||
return new MethodSnapshot(name, rawName, shortId, List.copyOf(bodyAbsenceMarkers), Map.of(
|
||||
return new MethodSnapshot(name, shortId, Map.of(
|
||||
"name", name, "signature", signature,
|
||||
"dex_descriptor", descriptor,
|
||||
"is_constructor", method.isConstructor(), "def_pos", 0));
|
||||
@@ -225,52 +140,16 @@ class ReaJadxBridge {
|
||||
|
||||
private JadxSession.SmartCode methodBody(JadxSession current, ClassSnapshot cls,
|
||||
MethodSnapshot selected, JavaMethod method) {
|
||||
// Access flags belong to the parsed member, before code generation rewrites it.
|
||||
// These methods have no Java body; source slicing can include unrelated members.
|
||||
if (!selected.bodyAbsenceMarkers().isEmpty())
|
||||
return new JadxSession.SmartCode("", "java", false, selected.bodyAbsenceMarkers());
|
||||
if (!selected.shortId().equals("<clinit>()V"))
|
||||
return current.getMethodBodySmart(method, current.getMaxSourceBytes(), true);
|
||||
// Java code generation can fold all or part of <clinit> into field declarations.
|
||||
// Its method text cannot establish coverage, even when a static block remains.
|
||||
if (selected.shortId().equals("<clinit>()V"))
|
||||
return exactMethodSmali(current, cls, selected, List.of("static_initializer_disassembly"));
|
||||
String java = current.getMethodSource(method);
|
||||
if (java.startsWith("// ERROR:")) throw new IllegalArgumentException(java);
|
||||
// The upstream placeholder means only that Java code was omitted, including
|
||||
// methods merged into synthetic bridges. Access flags established absence above.
|
||||
if (java.isEmpty() || java.equals(
|
||||
"// method exists but has no decompiled body (native/abstract)"))
|
||||
return exactMethodSmali(current, cls, selected, List.of("java_body_unavailable"));
|
||||
List<String> markers = DecompileFailureKt.detectDecompileFailure(java);
|
||||
if (markers.stream().anyMatch(DecompileFailureKt.getSTRONG_FAILURE_MARKERS()::contains))
|
||||
return exactMethodSmali(current, cls, selected, markers);
|
||||
JadxSession.MethodSmali smali = current.getMethodSmali(cls.node(), method.getName());
|
||||
if (!smali.getFound() || smali.getBlocks().size() != 1)
|
||||
throw new IllegalArgumentException("Static initializer disassembly requires one exact method: " + selected.shortId());
|
||||
return new JadxSession.SmartCode(
|
||||
TextUtilKt.truncateToBytes(java, current.getMaxSourceBytes()), "java", false, markers);
|
||||
}
|
||||
|
||||
private JadxSession.SmartCode exactMethodSmali(JadxSession current, ClassSnapshot cls,
|
||||
MethodSnapshot selected, List<String> markers) {
|
||||
JadxSession.MethodSmali smali = current.getMethodSmali(cls.node(), selected.rawName());
|
||||
String block = selectMethodSmali(smali, selected.shortId());
|
||||
return new JadxSession.SmartCode(
|
||||
TextUtilKt.truncateToBytes(block, current.getMaxSourceBytes()), "smali", true, markers);
|
||||
}
|
||||
|
||||
private static String selectMethodSmali(JadxSession.MethodSmali smali, String shortId) {
|
||||
if (!smali.getFound())
|
||||
throw new IllegalArgumentException("JADX could not disassemble " + shortId
|
||||
+ (smali.getNote() == null ? "" : ": " + smali.getNote()));
|
||||
// Upstream returns every same-name overload, and can return an unterminated
|
||||
// trailing block. Match the full original identity before applying output limits.
|
||||
List<String> matches = smali.getBlocks().stream().filter(block -> {
|
||||
String header = block.lines().findFirst().orElse("").strip();
|
||||
return header.startsWith(".method ") && header.endsWith(" " + shortId);
|
||||
}).toList();
|
||||
if (matches.size() != 1)
|
||||
throw new IllegalArgumentException("Disassembly could not establish one selected method: " + shortId);
|
||||
String block = matches.get(0);
|
||||
if (!block.stripTrailing().endsWith("\n.end method"))
|
||||
throw new IllegalArgumentException("Selected method disassembly is incomplete: " + shortId);
|
||||
return block;
|
||||
TextUtilKt.truncateToBytes(smali.getBlocks().get(0), current.getMaxSourceBytes()),
|
||||
"smali", true, List.of("static_initializer_disassembly"));
|
||||
}
|
||||
|
||||
// The local transport admits 8 MiB frames. Reserve 1 KiB for the fixed
|
||||
@@ -324,8 +203,7 @@ class ReaJadxBridge {
|
||||
return new DirectInvokes(sites, exhaustive[0]);
|
||||
}
|
||||
|
||||
private CallToolResult handle(String name, kotlinx.serialization.json.JsonObject input) {
|
||||
JsonObject args = JsonParser.parseString(input.toString()).getAsJsonObject();
|
||||
private CallToolResult handle(String name, JsonObject args) {
|
||||
if (name.equals("rea_jvm_status")) return json(Map.of(
|
||||
"engine_reported_version", BuildInfo.VERSION,
|
||||
"max_heap_bytes", Runtime.getRuntime().maxMemory(),
|
||||
@@ -335,25 +213,12 @@ class ReaJadxBridge {
|
||||
JadxSession current = session();
|
||||
if (name.equals("list_classes")) {
|
||||
List<String> names = current.getClassFqns();
|
||||
String query = args.has("query") ? string(args, "query") : "";
|
||||
int offset = integer(args, "offset", 0);
|
||||
int limit = integer(args, "limit", 200);
|
||||
int start = Math.min(offset, names.size());
|
||||
int end = start;
|
||||
List<String> items;
|
||||
if (query.isEmpty()) {
|
||||
end = (int) Math.min((long) start + limit, names.size());
|
||||
items = names.subList(start, end);
|
||||
} else {
|
||||
items = new ArrayList<>();
|
||||
while (end < names.size() && items.size() < limit) {
|
||||
String nameInInventory = names.get(end++);
|
||||
if (nameInInventory.contains(query)) items.add(nameInInventory);
|
||||
}
|
||||
}
|
||||
return json(Map.of("total_classes", names.size(), "next_offset", end,
|
||||
"scope", "top_level", "offset", offset, "limit", limit,
|
||||
"items", items));
|
||||
int end = (int) Math.min((long) start + limit, names.size());
|
||||
return json(Map.of("total", names.size(), "offset", offset, "limit", limit,
|
||||
"items", names.subList(start, end)));
|
||||
}
|
||||
ClassSnapshot cls = selected(args);
|
||||
if (name.equals("get_class_summary")) return json(cls.summary());
|
||||
@@ -365,7 +230,6 @@ class ReaJadxBridge {
|
||||
JadxSession.SmartCode code = methodBody(current, cls, overloads.get(index), method);
|
||||
return json(Map.of("class_name", cls.summary().get("full_name"),
|
||||
"method_name", overloads.get(index).name(), "full_name", method.getFullName(),
|
||||
"dex_descriptor", overloads.get(index).summary().get("dex_descriptor"),
|
||||
"overload_index", index, "overload_count", overloads.size(),
|
||||
"mode", code.getKind(), "fell_back", code.getFellBack(),
|
||||
"markers", code.getMarkers(), "body", code.getText()));
|
||||
@@ -377,7 +241,7 @@ class ReaJadxBridge {
|
||||
if (name.equals("get_xrefs_to_class")) uses = cls.node().getUseIn();
|
||||
else {
|
||||
List<MethodSnapshot> overloads = methods(cls, args);
|
||||
if (overloads.size() != 1 && !args.has("overload_index"))
|
||||
if (overloads.size() != 1 && !args.containsKey("overload_index"))
|
||||
throw new InputFailure("overload_index", "Select one of " + overloads.size() + " method overloads");
|
||||
overloadIndex = integer(args, "overload_index", 0);
|
||||
if (overloadIndex >= overloads.size())
|
||||
@@ -423,12 +287,11 @@ class ReaJadxBridge {
|
||||
public static void main(String[] args) throws Exception {
|
||||
PrintStream protocolOut = System.out;
|
||||
System.setOut(System.err);
|
||||
SessionConfig defaults = new SessionConfig(
|
||||
1048576, 0, 90000L, 1, List.of(), List.of(), 64, ResourceMode.FULL);
|
||||
SessionHolder holder = new SessionHolder(defaults);
|
||||
SessionHolder holder = new SessionHolder(new SessionConfig(
|
||||
1048576, 0, 90000L, 1, List.of(), List.of(), 64, ResourceMode.FULL));
|
||||
ServerCapabilities capabilities = new ServerCapabilities(
|
||||
new ServerCapabilities.Tools(null), null, null, null, null, null, null, Map.of());
|
||||
Server server = new Server(new Implementation("rea-jadx-bridge", "4", null, null, null),
|
||||
Server server = new Server(new Implementation("rea-jadx-bridge", "1", null, null, null),
|
||||
new ServerOptions(capabilities), "", ignored -> Unit.INSTANCE);
|
||||
SessionToolsKt.registerSessionTools(server, holder);
|
||||
ManifestToolsKt.registerManifestTools(server, holder);
|
||||
@@ -436,17 +299,13 @@ class ReaJadxBridge {
|
||||
MethodToolsKt.registerMethodTools(server, holder);
|
||||
XrefToolsKt.registerXrefTools(server, holder);
|
||||
ReaJadxBridge bridge = new ReaJadxBridge(holder);
|
||||
Tool loadTool = server.getTools().get("load_apk").getTool();
|
||||
server.removeTool("load_apk");
|
||||
server.addTool(loadTool, (connection, request, continuation) ->
|
||||
bridge.load(request.getArguments(), defaults, continuation));
|
||||
Set<String> consumed = Set.of("load_apk", "get_app_info", "get_android_manifest",
|
||||
"list_classes", "get_class_summary", "get_method_body",
|
||||
"get_xrefs_to_class", "get_xrefs_to_method");
|
||||
for (String name : new ArrayList<>(server.getTools().keySet()))
|
||||
if (!consumed.contains(name)) server.removeTool(name);
|
||||
Tool diagnostics = new Tool("rea_jvm_status",
|
||||
new ToolSchema(null, new kotlinx.serialization.json.JsonObject(Map.of()), List.of(), null),
|
||||
new ToolSchema(null, new JsonObject(Map.of()), List.of(), null),
|
||||
"Observed worker JVM and metadata scope", null, null, null, null, null, null);
|
||||
server.addTool(diagnostics, (connection, request, continuation) -> bridge.handle("rea_jvm_status", request.getArguments()));
|
||||
for (String name : List.of("list_classes", "get_class_summary",
|
||||
@@ -461,16 +320,13 @@ class ReaJadxBridge {
|
||||
};
|
||||
Map<String, kotlinx.serialization.json.JsonElement> properties = new LinkedHashMap<>();
|
||||
for (String field : fields) properties.put(field, tool.getInputSchema().getProperties().get(field));
|
||||
if (name.equals("list_classes")) properties.put("query",
|
||||
new kotlinx.serialization.json.JsonObject(Map.of(
|
||||
"type", kotlinx.serialization.json.JsonElementKt.JsonPrimitive("string"))));
|
||||
String description = switch (name) {
|
||||
case "list_classes" -> "Pages of case-sensitive matching top-level class names; offset and next_offset are inventory positions, limit bounds matching rows. Omitted or empty query inventories all names.";
|
||||
case "list_classes" -> "Indexed pages of all top-level class names, with offset and limit.";
|
||||
case "get_class_summary" -> "Parsed member metadata for one exact class name; no source generation.";
|
||||
case "get_method_body" -> "Source for an exact class and stable same-name overload index; static initializers use smali to preserve folded field initialization.";
|
||||
default -> "Complete static using-node inventory for an exact class or selected method overload; one node may contain multiple invoke instructions, and source lines are unresolved.";
|
||||
};
|
||||
Tool narrowed = new Tool(name, new ToolSchema(null, new kotlinx.serialization.json.JsonObject(properties),
|
||||
Tool narrowed = new Tool(name, new ToolSchema(null, new JsonObject(properties),
|
||||
tool.getInputSchema().getRequired(), null), description, null, null, null, null, null, null);
|
||||
server.addTool(narrowed, (connection, request, continuation) -> {
|
||||
try { return bridge.handle(name, request.getArguments()); }
|
||||
|
||||
+10
-19
@@ -28,9 +28,9 @@ if os.name == "nt":
|
||||
import cutter
|
||||
|
||||
try:
|
||||
from PySide6.QtCore import QCoreApplication, QObject, Signal
|
||||
from PySide6.QtCore import QObject, Signal
|
||||
except ImportError:
|
||||
from PySide2.QtCore import QCoreApplication, QObject, Signal
|
||||
from PySide2.QtCore import QObject, Signal
|
||||
|
||||
|
||||
MAX_FRAME_BYTES = 16 * 1024 * 1024
|
||||
@@ -326,16 +326,15 @@ class _RequestDispatcher(QObject):
|
||||
self._receipt_lock = threading.Lock()
|
||||
self.current_file = self._read_current_file()
|
||||
try:
|
||||
value = QCoreApplication.applicationVersion()
|
||||
self.cutter_version = value if isinstance(value, str) and value else None
|
||||
self.cutter_version = str(cutter.core().getVersionInformation())
|
||||
except Exception:
|
||||
self.cutter_version = None
|
||||
|
||||
@staticmethod
|
||||
def _read_current_file() -> str | None:
|
||||
try:
|
||||
value = cutter.core().getConfig("file.path")
|
||||
return value if isinstance(value, str) and value else None
|
||||
value = cutter.core().currentlyOpenFile()
|
||||
return str(value) if value else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@@ -783,22 +782,14 @@ def _within_response_limit(value: Any) -> bool:
|
||||
current = pending.pop()
|
||||
if isinstance(current, str):
|
||||
size += 2
|
||||
if len(current) > MAX_FRAME_BYTES - size:
|
||||
return False
|
||||
if current.isascii():
|
||||
size += len(current)
|
||||
size += current.count('"') + current.count("\\")
|
||||
size += sum(5 for character in current if ord(character) < 0x20)
|
||||
else:
|
||||
# Count UTF-8 bytes without allocating a copy of the whole output.
|
||||
try:
|
||||
size += sum(
|
||||
len(current[start:start + 65536].encode("utf-8"))
|
||||
for start in range(0, len(current), 65536)
|
||||
)
|
||||
except UnicodeEncodeError:
|
||||
# Unencodable output also needs the signed omission fallback.
|
||||
return False
|
||||
size += current.count('"') + current.count("\\")
|
||||
size += sum(5 for character in current if ord(character) < 0x20)
|
||||
size += 4 * len(current)
|
||||
size += current.count('"') + current.count("\\")
|
||||
size += sum(5 for character in current if ord(character) < 0x20)
|
||||
elif isinstance(current, dict):
|
||||
identity = id(current)
|
||||
if identity in seen:
|
||||
|
||||
@@ -140,7 +140,6 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
"params"
|
||||
);
|
||||
private static final String[] CAPABILITIES = {
|
||||
"read_binary_inventory_summary",
|
||||
"annotate_native_function",
|
||||
"set_address_name",
|
||||
"set_addresses_names",
|
||||
@@ -428,7 +427,6 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
);
|
||||
}
|
||||
return switch (request.method) {
|
||||
case "read_binary_inventory_summary" -> binaryInventorySummary(request.params);
|
||||
case "inspect_native_load_image" -> inspectNativeLoadImage(request.params);
|
||||
case "read_bytes" -> readMemoryBytes(request.params);
|
||||
case "search_bytes" -> searchMemoryBytes(request.params, descriptor);
|
||||
@@ -936,7 +934,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
String value = decompiledText(decompile(function));
|
||||
JsonObject result = functionObservation(
|
||||
value == null ? JsonNull.INSTANCE : GSON.toJsonTree(value),
|
||||
functionBoundaryLimitations(
|
||||
noReturnCallLimitations(
|
||||
function,
|
||||
currentProgram.getListing().getInstructions(function.getBody(), true)
|
||||
)
|
||||
@@ -1029,7 +1027,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
InstructionScan scan = scanInstructions(function, Integer.MAX_VALUE);
|
||||
return functionObservation(
|
||||
GSON.toJsonTree(renderAssembly(scan.instructions)),
|
||||
functionBoundaryLimitations(function, scan.instructions)
|
||||
noReturnCallLimitations(function, scan.instructions)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1048,7 +1046,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
limitations.add(
|
||||
"The fast path does not invoke the decompiler or scan whole-program names and strings."
|
||||
);
|
||||
List<String> boundaryLimitations = functionBoundaryLimitations(function, scan.instructions);
|
||||
List<String> boundaryLimitations = noReturnCallLimitations(function, scan.instructions);
|
||||
for (String limitation : boundaryLimitations) limitations.add(limitation);
|
||||
JsonObject result = new JsonObject();
|
||||
result.add("procedure", procedureIdentity(function));
|
||||
@@ -1071,7 +1069,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
result.add(canonicalAddress(item.getEntryPoint()));
|
||||
}
|
||||
if (callers) {
|
||||
JsonObject observation = functionObservation(result, functionBoundaryLimitations(function,
|
||||
JsonObject observation = functionObservation(result, noReturnCallLimitations(function,
|
||||
currentProgram.getListing().getInstructions(function.getBody(), true)
|
||||
));
|
||||
observation.add("relationship_coverage", callRelationshipCoverage(null,
|
||||
@@ -1101,7 +1099,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
result.add("classification", functionClassification(function));
|
||||
return functionObservation(
|
||||
result,
|
||||
functionBoundaryLimitations(
|
||||
noReturnCallLimitations(
|
||||
function,
|
||||
currentProgram.getListing().getInstructions(function.getBody(), true)
|
||||
)
|
||||
@@ -1133,22 +1131,12 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
result.addProperty("direction", direction);
|
||||
result.add("references", edges);
|
||||
result.addProperty("reference_kinds_available", true);
|
||||
List<String> limitations;
|
||||
JsonArray unresolvedCalls = new JsonArray();
|
||||
if (direction.equals("outgoing")) {
|
||||
CallBoundaryObservation calls = callBoundaryObservation(
|
||||
JsonArray unresolvedCalls = direction.equals("outgoing")
|
||||
? callBoundaryObservation(
|
||||
function, currentProgram.getListing().getInstructions(function.getBody(), true), null, true, references
|
||||
);
|
||||
unresolvedCalls = calls.unresolvedCalls();
|
||||
limitations = calls.limitations();
|
||||
} else {
|
||||
limitations = functionBoundaryLimitations(
|
||||
function,
|
||||
currentProgram.getListing().getInstructions(function.getBody(), true)
|
||||
);
|
||||
}
|
||||
).unresolvedCalls() : new JsonArray();
|
||||
result.add("unresolved_calls", unresolvedCalls);
|
||||
return functionObservation(result, limitations);
|
||||
return result;
|
||||
}
|
||||
|
||||
private JsonObject inspectNativeDataType(JsonObject params) throws Exception {
|
||||
@@ -1349,7 +1337,12 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
result.add("references", references);
|
||||
if (includeIncoming) {
|
||||
TreeMap<String, Reference> incoming = new TreeMap<>();
|
||||
visitObservedReferencesTo(address, reference -> addReference(incoming, reference));
|
||||
ReferenceIterator incomingIterator = currentProgram.getReferenceManager().getReferencesTo(address);
|
||||
while (incomingIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference reference = incomingIterator.next();
|
||||
if (!reference.isEntryPointReference()) addReference(incoming, reference);
|
||||
}
|
||||
List<Reference> orderedIncoming = new ArrayList<>(incoming.values());
|
||||
orderedIncoming.sort(REFERENCE_ORDER);
|
||||
JsonArray incomingReferences = new JsonArray();
|
||||
@@ -1401,8 +1394,16 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
requireKeys(params, Set.of("document", "address"));
|
||||
requireDocument(params);
|
||||
Address address = requireAddress(params, "address");
|
||||
ReferenceIterator references = currentProgram.getReferenceManager().getReferencesTo(address);
|
||||
Set<Address> sources = new HashSet<>();
|
||||
visitObservedReferencesTo(address, reference -> sources.add(reference.getFromAddress()));
|
||||
while (references.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference reference = references.next();
|
||||
if (reference.isEntryPointReference()) {
|
||||
continue;
|
||||
}
|
||||
sources.add(reference.getFromAddress());
|
||||
}
|
||||
List<Address> ordered = new ArrayList<>(sources);
|
||||
ordered.sort(Address::compareTo);
|
||||
JsonArray result = new JsonArray();
|
||||
@@ -1976,18 +1977,6 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
return result;
|
||||
}
|
||||
|
||||
private JsonObject binaryInventorySummary(JsonObject params) throws Exception {
|
||||
requireKeys(params, Set.of());
|
||||
JsonObject result = new JsonObject();
|
||||
result.addProperty("document", currentProgram.getName());
|
||||
result.add("segments", segments());
|
||||
// Count the owning inventories, preserving their exact discovery rules
|
||||
// without serializing function identities or string values for counts.
|
||||
result.addProperty("procedure_count", procedures().size());
|
||||
result.addProperty("string_count", strings().size());
|
||||
return result;
|
||||
}
|
||||
|
||||
private JsonArray listNames(JsonObject params) throws Exception {
|
||||
requireKeys(params, Set.of("document", "address"));
|
||||
requireDocument(params);
|
||||
@@ -2014,10 +2003,6 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
private JsonArray listSegments(JsonObject params) {
|
||||
requireKeys(params, Set.of("document"));
|
||||
requireDocument(params);
|
||||
return segments();
|
||||
}
|
||||
|
||||
private JsonArray segments() {
|
||||
JsonArray result = new JsonArray();
|
||||
String imageBase = canonicalAddress(currentProgram.getImageBase());
|
||||
MemoryBlock[] blocks = currentProgram.getMemory().getBlocks();
|
||||
@@ -3446,27 +3431,51 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
return omitted[0];
|
||||
}
|
||||
|
||||
private List<String> functionBoundaryLimitations(
|
||||
private List<String> noReturnCallLimitations(
|
||||
Function function, Iterable<Instruction> instructions)
|
||||
throws Exception {
|
||||
FunctionBoundaryLimitations boundary = new FunctionBoundaryLimitations(function);
|
||||
for (Instruction instruction : instructions) boundary.observe(instruction);
|
||||
return boundary.values();
|
||||
List<String> limitations = new ArrayList<>();
|
||||
Instruction beforePrevious = null;
|
||||
Instruction previous = null;
|
||||
for (Instruction instruction : instructions) {
|
||||
monitor.checkCancelled();
|
||||
String limitation = terminalCallLimitation(instruction);
|
||||
if (limitation != null) limitations.add(limitation);
|
||||
if (beforePrevious != null && previous != null) {
|
||||
String seh = borlandSehHandlerLimitation(
|
||||
function, beforePrevious, previous, instruction);
|
||||
if (seh != null) limitations.add(seh);
|
||||
}
|
||||
beforePrevious = previous;
|
||||
previous = instruction;
|
||||
}
|
||||
return limitations;
|
||||
}
|
||||
|
||||
private CallBoundaryObservation callBoundaryObservation(
|
||||
Function function, Iterable<Instruction> instructions, Set<Function> returnedCallees,
|
||||
boolean includeUnresolvedSites, List<Reference> observedReferences)
|
||||
throws Exception {
|
||||
FunctionBoundaryLimitations boundary = new FunctionBoundaryLimitations(function);
|
||||
List<String> limitations = new ArrayList<>();
|
||||
CallBoundaryReferences calls = new CallBoundaryReferences(returnedCallees, includeUnresolvedSites);
|
||||
Instruction beforePrevious = null;
|
||||
Instruction previous = null;
|
||||
if (observedReferences == null) visitReferences(function, "outgoing", calls::observe);
|
||||
else for (Reference reference : observedReferences) {
|
||||
monitor.checkCancelled();
|
||||
calls.observe(reference);
|
||||
}
|
||||
for (Instruction instruction : instructions) {
|
||||
boundary.observe(instruction);
|
||||
monitor.checkCancelled();
|
||||
String limitation = terminalCallLimitation(instruction);
|
||||
if (limitation != null) limitations.add(limitation);
|
||||
if (beforePrevious != null && previous != null) {
|
||||
String seh = borlandSehHandlerLimitation(
|
||||
function, beforePrevious, previous, instruction);
|
||||
if (seh != null) limitations.add(seh);
|
||||
}
|
||||
beforePrevious = previous;
|
||||
previous = instruction;
|
||||
if (!instruction.getFlowType().isCall()) continue;
|
||||
boolean destination = false;
|
||||
for (Reference reference : instruction.getReferencesFrom()) {
|
||||
@@ -3480,38 +3489,10 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
"Instruction decoder identifies a call but ReferenceManager supplies no call destination");
|
||||
}
|
||||
}
|
||||
return new CallBoundaryObservation(boundary.values(),
|
||||
return new CallBoundaryObservation(List.copyOf(limitations),
|
||||
returnedCallees == null ? null : calls.unrepresented, calls.unresolvedCalls());
|
||||
}
|
||||
|
||||
private final class FunctionBoundaryLimitations {
|
||||
private final Function function;
|
||||
private final List<String> limitations = new ArrayList<>();
|
||||
private Instruction beforePrevious;
|
||||
private Instruction previous;
|
||||
|
||||
private FunctionBoundaryLimitations(Function function) {
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
private void observe(Instruction instruction) throws Exception {
|
||||
monitor.checkCancelled();
|
||||
String limitation = terminalCallLimitation(instruction);
|
||||
if (limitation != null) limitations.add(limitation);
|
||||
if (beforePrevious != null && previous != null) {
|
||||
String seh = borlandSehHandlerLimitation(
|
||||
function, beforePrevious, previous, instruction);
|
||||
if (seh != null) limitations.add(seh);
|
||||
}
|
||||
beforePrevious = previous;
|
||||
previous = instruction;
|
||||
}
|
||||
|
||||
private List<String> values() {
|
||||
return List.copyOf(limitations);
|
||||
}
|
||||
}
|
||||
|
||||
private String borlandSehHandlerLimitation(
|
||||
Function function, Instruction handlerPush, Instruction framePush,
|
||||
Instruction frameLink) {
|
||||
@@ -3693,36 +3674,24 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
monitor.checkCancelled();
|
||||
Address address = addresses.next();
|
||||
if (outgoing) {
|
||||
visitObservedReferencesFrom(address, visitor);
|
||||
for (Reference reference : currentProgram.getReferenceManager()
|
||||
.getReferencesFrom(address)) {
|
||||
monitor.checkCancelled();
|
||||
if (!reference.isEntryPointReference()) visitor.accept(reference);
|
||||
}
|
||||
}
|
||||
else {
|
||||
visitObservedReferencesTo(address, visitor);
|
||||
ReferenceIterator iterator = currentProgram.getReferenceManager()
|
||||
.getReferencesTo(address);
|
||||
while (iterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
Reference reference = iterator.next();
|
||||
if (!reference.isEntryPointReference()) visitor.accept(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void visitObservedReferencesFrom(Address address, ReferenceVisitor visitor)
|
||||
throws Exception {
|
||||
for (Reference reference : currentProgram.getReferenceManager().getReferencesFrom(address)) {
|
||||
monitor.checkCancelled();
|
||||
visitObservedReference(reference, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitObservedReferencesTo(Address address, ReferenceVisitor visitor)
|
||||
throws Exception {
|
||||
ReferenceIterator references = currentProgram.getReferenceManager().getReferencesTo(address);
|
||||
while (references.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
visitObservedReference(references.next(), visitor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void visitObservedReference(Reference reference, ReferenceVisitor visitor)
|
||||
throws Exception {
|
||||
if (!reference.isEntryPointReference()) visitor.accept(reference);
|
||||
}
|
||||
|
||||
private static void addReference(TreeMap<String, Reference> observed, Reference reference) {
|
||||
String key = canonicalAddress(reference.getFromAddress()) + "\u0000" +
|
||||
canonicalAddress(reference.getToAddress()) + "\u0000" +
|
||||
|
||||
@@ -1057,10 +1057,6 @@ def _serve_connection(connection):
|
||||
):
|
||||
raise PermissionError("Invalid bridge capability")
|
||||
authenticated = True
|
||||
# The connection grace period only bounds unauthenticated idle
|
||||
# clients. Native analysis and a connected owner's idle time
|
||||
# remain unbounded after capability validation.
|
||||
connection.settimeout(None)
|
||||
_write_message(file, {"id": request_id, "event": {
|
||||
"type": "progress",
|
||||
"phase": "hopper_bridge",
|
||||
@@ -1152,17 +1148,13 @@ def _run():
|
||||
server.bind(REA_SOCKET)
|
||||
os.chmod(REA_SOCKET, 0o600)
|
||||
server.listen(1)
|
||||
# A bridge can start after its caller's startup/cleanup deadline. Bound
|
||||
# the first accept as well as reconnects so an orphan cannot pin Hopper's
|
||||
# dedicated Python thread and prevent later documents from starting REA.
|
||||
server.settimeout(REA_RECONNECT_TIMEOUT_SECONDS)
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
connection, _ = server.accept()
|
||||
except socket.timeout:
|
||||
break
|
||||
connection.settimeout(REA_RECONNECT_TIMEOUT_SECONDS)
|
||||
connection.settimeout(None)
|
||||
if _serve_connection(connection):
|
||||
break
|
||||
# Match REA's cleanup handshake budget without pinning Hopper's
|
||||
|
||||
@@ -555,38 +555,6 @@ def _failed_launch_description(process):
|
||||
return None
|
||||
|
||||
|
||||
def _retire_failed_launch(process, config, listener, stdout, stderr):
|
||||
"""Reconcile an SBProcess returned alongside a failed Launch error."""
|
||||
if not process.IsValid():
|
||||
stdout.close()
|
||||
stderr.close()
|
||||
return False
|
||||
|
||||
pid = process.GetProcessID()
|
||||
if pid > 0:
|
||||
# Even an already-exited process needs its PID published so the host
|
||||
# can distinguish a completed launch failure from an unknown target.
|
||||
with open(config["pid_path"], "w") as handle:
|
||||
handle.write(str(pid))
|
||||
|
||||
if process.GetState() != lldb.eStateExited:
|
||||
stdout.mark_launched()
|
||||
stderr.mark_launched()
|
||||
if pid > 0:
|
||||
# Hold a surviving target until the host has captured its start
|
||||
# identity. If that proof is unavailable, Kill still addresses
|
||||
# this exact SBProcess created by the current launch request.
|
||||
_wait_for_identity_ack(config)
|
||||
process.Kill()
|
||||
_wait_for_exit(listener, process, 5)
|
||||
|
||||
exit_observed = process.GetState() == lldb.eStateExited
|
||||
expected_exit = exit_observed
|
||||
stdout.close(expected_exit=expected_exit)
|
||||
stderr.close(expected_exit=expected_exit)
|
||||
return exit_observed
|
||||
|
||||
|
||||
def trace(debugger, config):
|
||||
global _TRACE_CONTEXT
|
||||
debugger.SetAsync(True)
|
||||
@@ -662,9 +630,8 @@ def trace(debugger, config):
|
||||
)
|
||||
process = target.Launch(_launch_info(target, config, listener), error)
|
||||
if not error.Success() or not process.IsValid():
|
||||
exit_observed = _retire_failed_launch(
|
||||
process, config, listener, stdout, stderr
|
||||
)
|
||||
stdout.close()
|
||||
stderr.close()
|
||||
return {
|
||||
"status": "launch-error",
|
||||
"error": error.GetCString(),
|
||||
@@ -673,26 +640,15 @@ def trace(debugger, config):
|
||||
if process.IsValid()
|
||||
else {}
|
||||
),
|
||||
**(
|
||||
{"target_process_exit_observed": True}
|
||||
if exit_observed
|
||||
else {}
|
||||
),
|
||||
}
|
||||
launch_failure = _failed_launch_description(process)
|
||||
if launch_failure is not None:
|
||||
exit_observed = _retire_failed_launch(
|
||||
process, config, listener, stdout, stderr
|
||||
)
|
||||
stdout.close(expected_exit=True)
|
||||
stderr.close(expected_exit=True)
|
||||
return {
|
||||
"status": "launch-error",
|
||||
"error": launch_failure,
|
||||
"target_process_created": True,
|
||||
**(
|
||||
{"target_process_exit_observed": True}
|
||||
if exit_observed
|
||||
else {}
|
||||
),
|
||||
}
|
||||
stdout.mark_launched()
|
||||
stderr.mark_launched()
|
||||
|
||||
@@ -15,8 +15,6 @@ fake_lldb = sys.modules.setdefault("lldb", types.ModuleType("lldb"))
|
||||
fake_lldb.LLDB_INVALID_ADDRESS = -1
|
||||
fake_lldb.eLaunchFlagDebug = 2
|
||||
fake_lldb.eLaunchFlagStopAtEntry = 4
|
||||
fake_lldb.eStateExited = 10
|
||||
fake_lldb.SBEvent = lambda: object()
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"rea_lldb_tracer", os.path.join(os.path.dirname(__file__), "rea_lldb_tracer.py")
|
||||
)
|
||||
@@ -25,136 +23,6 @@ spec.loader.exec_module(tracer)
|
||||
|
||||
|
||||
class NativeTraceBudgetTests(unittest.TestCase):
|
||||
def test_failed_launch_does_not_infer_exit_from_a_failed_kill(self):
|
||||
class Process:
|
||||
def IsValid(self):
|
||||
return True
|
||||
|
||||
def GetProcessID(self):
|
||||
return 12345
|
||||
|
||||
def GetState(self):
|
||||
return 6
|
||||
|
||||
def Kill(self):
|
||||
return None
|
||||
|
||||
class Sink:
|
||||
close_exit = None
|
||||
|
||||
def mark_launched(self):
|
||||
pass
|
||||
|
||||
def close(self, expected_exit=False):
|
||||
self.close_exit = expected_exit
|
||||
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
stdout, stderr = Sink(), Sink()
|
||||
with patch.object(tracer, "_wait_for_identity_ack", return_value="unavailable"), patch.object(
|
||||
tracer, "_wait_for_exit", return_value=None
|
||||
):
|
||||
exited = tracer._retire_failed_launch(
|
||||
Process(), {"pid_path": os.path.join(directory, "pid")}, object(), stdout, stderr
|
||||
)
|
||||
self.assertFalse(exited)
|
||||
self.assertFalse(stdout.close_exit)
|
||||
self.assertFalse(stderr.close_exit)
|
||||
|
||||
def test_failed_launch_publishes_pid_and_retires_live_process(self):
|
||||
class Process:
|
||||
state = 6
|
||||
killed = False
|
||||
|
||||
def IsValid(self):
|
||||
return True
|
||||
|
||||
def GetProcessID(self):
|
||||
return 12345
|
||||
|
||||
def GetState(self):
|
||||
return self.state
|
||||
|
||||
def Kill(self):
|
||||
self.killed = True
|
||||
self.state = tracer.lldb.eStateExited
|
||||
|
||||
class Sink:
|
||||
launched = False
|
||||
close_exit = None
|
||||
|
||||
def mark_launched(self):
|
||||
self.launched = True
|
||||
|
||||
def close(self, expected_exit=False):
|
||||
self.close_exit = expected_exit
|
||||
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
pid_path = os.path.join(directory, "pid")
|
||||
process = Process()
|
||||
stdout, stderr = Sink(), Sink()
|
||||
|
||||
def acknowledge(config):
|
||||
with open(config["pid_path"], "r") as pid_file:
|
||||
self.assertEqual(pid_file.read(), "12345")
|
||||
return "readable"
|
||||
|
||||
with patch.object(tracer, "_wait_for_identity_ack", acknowledge):
|
||||
exited = tracer._retire_failed_launch(
|
||||
process,
|
||||
{"pid_path": pid_path},
|
||||
object(),
|
||||
stdout,
|
||||
stderr,
|
||||
)
|
||||
|
||||
self.assertTrue(exited)
|
||||
self.assertTrue(process.killed)
|
||||
self.assertTrue(stdout.launched)
|
||||
self.assertTrue(stderr.launched)
|
||||
self.assertTrue(stdout.close_exit)
|
||||
self.assertTrue(stderr.close_exit)
|
||||
|
||||
def test_failed_launch_records_when_valid_process_is_already_exited(self):
|
||||
class Process:
|
||||
def IsValid(self):
|
||||
return True
|
||||
|
||||
def GetProcessID(self):
|
||||
return 12345
|
||||
|
||||
def GetState(self):
|
||||
return tracer.lldb.eStateExited
|
||||
|
||||
def Kill(self):
|
||||
raise AssertionError("an exited process must not be killed")
|
||||
|
||||
class Sink:
|
||||
close_exit = None
|
||||
|
||||
def mark_launched(self):
|
||||
raise AssertionError("an exited process has no output to drain")
|
||||
|
||||
def close(self, expected_exit=False):
|
||||
self.close_exit = expected_exit
|
||||
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
pid_path = os.path.join(directory, "pid")
|
||||
stdout, stderr = Sink(), Sink()
|
||||
with patch.object(
|
||||
tracer,
|
||||
"_wait_for_identity_ack",
|
||||
side_effect=AssertionError("exit is already observed"),
|
||||
):
|
||||
exited = tracer._retire_failed_launch(
|
||||
Process(), {"pid_path": pid_path}, object(), stdout, stderr
|
||||
)
|
||||
with open(pid_path, "r") as pid_file:
|
||||
self.assertEqual(pid_file.read(), "12345")
|
||||
|
||||
self.assertTrue(exited)
|
||||
self.assertTrue(stdout.close_exit)
|
||||
self.assertTrue(stderr.close_exit)
|
||||
|
||||
def test_pre_target_integrity_failure_reports_no_process_created(self):
|
||||
original_debugger = getattr(tracer.lldb, "SBDebugger", None)
|
||||
|
||||
|
||||
@@ -20,9 +20,8 @@ def inspect(request):
|
||||
root = Path(os.environ["REA_CORE_CONTEXT_REQUEST"]).parent
|
||||
empty = root / "no-libraries"
|
||||
empty.mkdir(mode=0o700)
|
||||
for command in ["set auto-load off", "set debuginfod enabled off", "set auto-solib-add off", "set history save off", "set pagination off", "set target-file-system-kind unix",
|
||||
"set sysroot ./no-libraries", "set solib-search-path ./no-libraries",
|
||||
"set debug-file-directory ./no-libraries"]:
|
||||
for command in ["set auto-load off", "set debuginfod enabled off", "set auto-solib-add off", "set history save off", "set pagination off",
|
||||
"set sysroot ./no-libraries", "set solib-search-path ./no-libraries"]:
|
||||
gdb.execute(command, to_string=True)
|
||||
entry = request["gdbinit"]
|
||||
try:
|
||||
@@ -39,19 +38,7 @@ def inspect(request):
|
||||
# relative filename in the owned cwd so no selected path becomes GDB syntax.
|
||||
if Path(request["snapshot_path"]) != root.parent / "object.snapshot":
|
||||
raise ContextFailure("decoder", "Core context request did not select the shared owned snapshot.")
|
||||
# GDB 16 searches AT_EXECFN/NT_FILE outside sysroot when no executable BFD
|
||||
# is selected. Occupy that slot with the already running, owned debugger;
|
||||
# exec-file loads no symbols and never runs it. Clear it before any query.
|
||||
# /proc/self/exe identifies this process, not the core's historical PID.
|
||||
architecture = {"x86_64-little-endian": "i386:x86-64", "aarch64-little-endian": "aarch64"}.get(request["architecture"])
|
||||
if architecture is None:
|
||||
raise ContextFailure("unsupported", "Unsupported recorded core architecture.")
|
||||
gdb.execute("exec-file /proc/self/exe", to_string=True)
|
||||
# The placeholder must not select the core's architecture. Reuse the
|
||||
# decoder's validated profile, including for cross-architecture GDB builds.
|
||||
gdb.execute("set architecture " + architecture, to_string=True)
|
||||
gdb.execute("core-file ../object.snapshot", to_string=True)
|
||||
gdb.execute("file", to_string=True)
|
||||
inferior = gdb.selected_inferior()
|
||||
if inferior.connection is None or inferior.connection.type != "core" or gdb.current_progspace().filename is not None:
|
||||
raise ContextFailure("decoder", "Requested core-only boundary was not established; no mapping query performed.")
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
"""Producer regressions with controlled GDB state, not native debugger qualification."""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import runpy
|
||||
import sys
|
||||
import tempfile
|
||||
import types
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
BRIDGE = Path(__file__).with_name("core_context.py")
|
||||
|
||||
|
||||
class CoreContextTests(unittest.TestCase):
|
||||
def inspect(self, failure=None, connection="core", symbols=None, architecture="x86_64-little-endian"):
|
||||
commands, reads, queries = [], [], []
|
||||
state = {"executable": None, "symbols": None, "connection": None}
|
||||
gdb = types.ModuleType("gdb")
|
||||
gdb.VERSION = "16.3"
|
||||
gdb.selected_inferior = lambda: types.SimpleNamespace(
|
||||
connection=state["connection"], pid=123)
|
||||
gdb.current_progspace = lambda: types.SimpleNamespace(filename=state["symbols"])
|
||||
|
||||
def execute(command, to_string):
|
||||
self.assertTrue(to_string)
|
||||
commands.append(command)
|
||||
if command == failure:
|
||||
raise RuntimeError("controlled command failure")
|
||||
if command == "exec-file /proc/self/exe":
|
||||
state["executable"] = "/proc/self/exe"
|
||||
elif command == "core-file ../object.snapshot":
|
||||
if state["executable"] is None:
|
||||
reads.append("recorded-executable")
|
||||
state["executable"] = state["symbols"] = "recorded-executable"
|
||||
state["connection"] = types.SimpleNamespace(type=connection)
|
||||
elif command == "file":
|
||||
state["executable"] = None
|
||||
state["symbols"] = symbols
|
||||
|
||||
gdb.execute = execute
|
||||
pwndbg = types.ModuleType("pwndbg")
|
||||
pwndbg.aglib = types.ModuleType("pwndbg.aglib")
|
||||
pwndbg.aglib.vmmap = types.ModuleType("pwndbg.aglib.vmmap")
|
||||
pwndbg.lib = types.ModuleType("pwndbg.lib")
|
||||
pwndbg.lib.version = types.ModuleType("pwndbg.lib.version")
|
||||
pwndbg.lib.version.__version__ = "2026.09.15"
|
||||
|
||||
def maps():
|
||||
self.assertIsNone(state["executable"], "Helper executable must be discarded before mapping queries")
|
||||
queries.append("maps")
|
||||
return [types.SimpleNamespace(start=4096, end=8192, offset=0, flags=5, objfile="recorded-executable")]
|
||||
|
||||
pwndbg.aglib.vmmap.get = maps
|
||||
modules = {module.__name__: module for module in [
|
||||
gdb, pwndbg, pwndbg.aglib, pwndbg.aglib.vmmap, pwndbg.lib, pwndbg.lib.version]}
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
stage = root / "debugger"
|
||||
stage.mkdir()
|
||||
plugin = root / "gdbinit.py"
|
||||
plugin.write_text("")
|
||||
request = stage / "request.json"
|
||||
reply = stage / "reply.json"
|
||||
request.write_text(json.dumps({"gdbinit": str(plugin), "architecture": architecture, "snapshot_path": str(root / "object.snapshot"), "reply_path": str(reply)}))
|
||||
with patch.dict(sys.modules, modules), patch.dict(os.environ, REA_CORE_CONTEXT_REQUEST=str(request)):
|
||||
runpy.run_path(str(BRIDGE))
|
||||
result = json.loads(reply.read_text())
|
||||
return result, commands, reads, queries
|
||||
|
||||
def test_core_load_never_opens_recorded_executable_and_queries_only_after_discard(self):
|
||||
result, commands, reads, queries = self.inspect()
|
||||
self.assertTrue(result["ok"], result)
|
||||
self.assertEqual(reads, [])
|
||||
self.assertEqual(queries, ["maps"])
|
||||
self.assertEqual(commands[-4:], ["exec-file /proc/self/exe", "set architecture i386:x86-64", "core-file ../object.snapshot", "file"])
|
||||
self.assertLess(commands.index("set debug-file-directory ./no-libraries"), commands.index("core-file ../object.snapshot"))
|
||||
self.assertIsNone(result["value"]["executable"])
|
||||
self.assertEqual(result["value"]["maps"][0]["current_file_identity"], "unknown")
|
||||
|
||||
def test_failed_guard_core_load_or_discard_never_queries_mappings(self):
|
||||
for command in ["exec-file /proc/self/exe", "set architecture i386:x86-64", "core-file ../object.snapshot", "file"]:
|
||||
with self.subTest(command=command):
|
||||
result, commands, reads, queries = self.inspect(failure=command)
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertEqual(reads, [])
|
||||
self.assertEqual(queries, [])
|
||||
if command in ["exec-file /proc/self/exe", "set architecture i386:x86-64"]:
|
||||
self.assertNotIn("core-file ../object.snapshot", commands)
|
||||
|
||||
def test_cross_architecture_uses_the_validated_decoder_profile(self):
|
||||
result, commands, reads, queries = self.inspect(architecture="aarch64-little-endian")
|
||||
self.assertTrue(result["ok"], result)
|
||||
self.assertEqual(reads, [])
|
||||
self.assertEqual(queries, ["maps"])
|
||||
self.assertLess(commands.index("set architecture aarch64"), commands.index("core-file ../object.snapshot"))
|
||||
|
||||
def test_unknown_architecture_refuses_before_loading_core(self):
|
||||
result, commands, reads, queries = self.inspect(architecture="unknown")
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertEqual(result["reason"], "unsupported")
|
||||
self.assertNotIn("core-file ../object.snapshot", commands)
|
||||
self.assertEqual(reads, [])
|
||||
self.assertEqual(queries, [])
|
||||
|
||||
def test_wrong_connection_or_remaining_symbols_never_queries_mappings(self):
|
||||
for options in [{"connection": "native"}, {"symbols": "unexpected-symbols"}]:
|
||||
with self.subTest(options=options):
|
||||
result, _, reads, queries = self.inspect(**options)
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertEqual(reads, [])
|
||||
self.assertEqual(queries, [])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -60,7 +60,6 @@ export default defineConfig({
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "IDA", link: "/ida-provider" },
|
||||
{ text: "Kuna", link: "/kuna-provider" },
|
||||
{ text: "Ghidra on Windows", link: "/windows-ghidra-p0" },
|
||||
{ text: "Ghidra DOS analysis", link: "/ghidra-dos" },
|
||||
{ text: "Ghidra raw binary", link: "/raw-binary" },
|
||||
|
||||
@@ -98,37 +98,16 @@ existing analysis families directly, for example
|
||||
| `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`); checks for existing targets and refuses them without explicit overwrite (the check is not atomic); compares digests when device `sha256sum` is available |
|
||||
| `install_adb_package` | **mutates device** | Local APK via `adb install [-r]`; preserves its Success/Failure verdict, records `replace_requested`, and leaves actual replacement `null` because prior package state is not observed |
|
||||
| `uninstall_adb_package` | **mutates device** | Requests package removal for user 0 via `adb shell pm uninstall --user 0`, without data retention |
|
||||
| `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 |
|
||||
|
||||
For `inspect_adb_window`, `focus_contexts` retains each display header, its exact
|
||||
display ID when recognized, and every focus declaration with its original line.
|
||||
Declarations without a display header are explicitly `unscoped`. A missing
|
||||
declaration differs from a declaration whose `value` is JSON `null`.
|
||||
`source_section` identifies the selected dumpsys section; `observed_lines`
|
||||
preserves its focus declarations and display headers in source order.
|
||||
|
||||
`focus_summary` is `single_context` only for one context with no repeated focus
|
||||
field. The singular `focused_window` and `focused_app` summarize that context;
|
||||
they do not establish device-wide focus. Multiple contexts or repeated fields
|
||||
produce `ambiguous` with null singular fields and all declarations retained.
|
||||
When no focus field was declared, the status is `unavailable`. REA reads the
|
||||
displays section only when the windows section declares neither focus field.
|
||||
|
||||
For `install_adb_package`, `replace_requested` records whether `-r` was sent.
|
||||
The `replaced` result is `null`: the successful install response does not say
|
||||
whether the package was installed fresh or replaced, and REA does not query the
|
||||
device first. The install verdict and host APK digest remain available.
|
||||
|
||||
Push and install consume a private snapshot of the selected local input. The
|
||||
reported size and SHA-256 identify those consumed bytes; `local_path` and
|
||||
`apk_path` retain the original input path, whose contents may change later.
|
||||
Snapshot creation needs temporary disk space proportional to the input size.
|
||||
Failed snapshot cleanup remains owned and is retried before later operations
|
||||
and during shutdown.
|
||||
|
||||
## Interpret the result
|
||||
|
||||
- **Directory names retain whitespace and newlines.** Symlink targets do too,
|
||||
@@ -167,10 +146,8 @@ and during shutdown.
|
||||
- **Mutations are explicit.** `push_adb_file`, `install_adb_package`, and
|
||||
`uninstall_adb_package` declare `mutatesTarget` and never run implicitly:
|
||||
pushes check for existing device files before transfer and refuse them
|
||||
unless `overwrite` is set. A failed or unexpected existence probe stops
|
||||
transfer even with `overwrite`; only a clean `test -e` exit of 1 with no
|
||||
output is interpreted as absence. The check is not atomic, so a different
|
||||
process can create the path before `adb push` writes it. When available, the device's
|
||||
unless `overwrite` is set. The check is not atomic, so a different process
|
||||
can create the path before `adb push` writes it. When available, the device's
|
||||
`sha256sum` verifies the transfer; installs preserve the
|
||||
device's `Failure [...]` reason verbatim.
|
||||
- **Producer identity stays attached.** Every result embeds the producing
|
||||
@@ -183,19 +160,14 @@ and during shutdown.
|
||||
The app/activity lifecycle tools use `am start -W` and `am force-stop`.
|
||||
- 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. Output capture overflow reports `resource_constraint`;
|
||||
deadline expiration, including the client-version probe, reports
|
||||
`provider_timeout`. Command cancellation preserves the caller's exact reason;
|
||||
a later abort does not replace an already completed command failure.
|
||||
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.
|
||||
- Screen capture checks cancellation before publishing its exclusive output.
|
||||
If cancellation arrives after publication, the error retains the committed
|
||||
file's path, digest and dimensions; the file remains available as evidence.
|
||||
- Bugreports collect into isolated staging and publish with exclusive creation;
|
||||
filename collisions select the next numeric suffix. If publication fails, the
|
||||
completed archive remains in staging. The error's partial observation gives
|
||||
|
||||
+13
-56
@@ -103,10 +103,9 @@ 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 filtered class-page bridge (protocol 2) is verified on Linux x86-64 with
|
||||
Temurin 21, public Appium ApiDemos 6.0.18 and NewPipe 0.29.1 APKs. Earlier
|
||||
metadata-bridge records covered macOS arm64/OpenJDK 21 and Windows x64/JDK 21;
|
||||
this protocol revision has not been rerun on those hosts or Linux/JDK 25.
|
||||
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 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.
|
||||
@@ -147,20 +146,10 @@ queries accept the same `overload_index`; the bridge resolves the selected
|
||||
method node and the result reports its index and displayed signature. These
|
||||
indices are tied to the current artifact and engine, not stable across builds.
|
||||
|
||||
Smali fallbacks select one complete block using the original method name and DEX
|
||||
descriptor, before applying the source byte limit. This preserves the selected
|
||||
overload even when Java code generation renames a method. If the selected Java
|
||||
body was omitted, including a method merged into a synthetic bridge, REA returns
|
||||
its original smali with the `java_body_unavailable` marker. The marker describes
|
||||
missing Java; it does not infer why the method was omitted or name a replacement.
|
||||
Unresolved or duplicate disassembly identities fail instead of attributing another
|
||||
method's instructions to the selection.
|
||||
|
||||
Native and abstract methods are identified from access flags
|
||||
captured before code generation. They report `body_status: "not_available"`, an
|
||||
empty source, and the `native_method` or `abstract_method` marker; their declarations
|
||||
are not passed through the engine's source slicer. Other missing decompiled bodies
|
||||
do not establish either access flag.
|
||||
The engine's smali fallback also joins same-name overloads; REA rejects that
|
||||
fallback for an overloaded method instead of attributing all bodies to one
|
||||
selected overload. Native/abstract methods with no decompiled body report
|
||||
`body_status: "not_available"` without inferring which implementation flag caused it.
|
||||
|
||||
Static initializers (`<clinit>`) return smali with the
|
||||
`static_initializer_disassembly` marker. Java decompilation can move their
|
||||
@@ -174,10 +163,7 @@ the same source byte limit and explicit truncation reporting.
|
||||
permissions and class/resource counts. Summary fields are extracted by the
|
||||
upstream engine and should be checked against the retained XML when needed.
|
||||
Signature verification is explicitly `not_performed`.
|
||||
- Class search filters the engine's cached top-level names before transferring
|
||||
pages, then follows contiguous inventory positions without rescanning earlier
|
||||
rows. It checks selection, scope, examined ranges and counts before reporting
|
||||
complete coverage. Complete producer replies stay in Evidence; an empty `query`
|
||||
- Class search consumes all pages and checks their counts. An empty `query`
|
||||
inventories all class-name rows; class names are decompiler representations.
|
||||
Repeated names remain repeated in `matches` so the inventory row count and
|
||||
producer evidence stay visible. `duplicate_names` identifies matching names
|
||||
@@ -247,12 +233,8 @@ 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. File and slice occurrences supply component
|
||||
endpoints; directory trees and symlinks retain their identities in the source
|
||||
inventory without being classified as code files. It does not decode DEX or
|
||||
claim observed runtime calls. DEX/JVM runtime hints summarize the classified
|
||||
bytecode component lists. Framework hints match complete native library names,
|
||||
such as
|
||||
and path-based bridge hypotheses. It does not decode DEX or claim observed
|
||||
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.
|
||||
@@ -317,34 +299,9 @@ settings. Evidence reports the worker's observed `Runtime.maxMemory()` rounded
|
||||
down to MiB and retains exact bytes, Java version and visible processors in its
|
||||
raw runtime response. The observed allocatable heap can differ from configured
|
||||
`-Xmx`, especially with Serial GC. Heap is not a total RSS cap: the JVM also
|
||||
uses native memory. A typed JVM memory allocation failure during APK loading
|
||||
reports `resource_constraint` with the observed maximum heap in bytes. Known
|
||||
heap failures name `REA_JADX_HEAP_MIB` in remediation; other memory regions
|
||||
remain unknown. A healthy doctor configuration check does not establish that
|
||||
any particular APK fits. Failures before the bridge can report a typed result
|
||||
and upstream errors from other operations retain their existing diagnostics;
|
||||
error text alone does not establish memory exhaustion.
|
||||
|
||||
Independent REA instances have independent queues. Whole
|
||||
operations have a **120-second** execution deadline by default, starting after
|
||||
they reach the queue's front. For a known slow cold load, such as a large
|
||||
multidex APK, select another finite deadline:
|
||||
|
||||
```sh
|
||||
export REA_JADX_OPERATION_TIMEOUT_MS=600000
|
||||
```
|
||||
|
||||
The value must be a decimal millisecond count from 1 to 2147483647; anything
|
||||
else is refused before Java starts. The same deadline bounds each upstream
|
||||
call, a timeout reports the selected value, and a passing JADX configuration
|
||||
check in `rea doctor` reports the effective `operation_timeout_ms`. Explicit
|
||||
cancellation still ends the operation immediately, and partial observations
|
||||
and owned-process cleanup are unchanged. Raising the deadline does not extend
|
||||
the bridge's 30-second startup handshake or the upstream **90-second**
|
||||
decompilation limit. MCP clients enforce their own tool-call timeouts, and
|
||||
setup's derived [client tool timeout](client-configuration.md) does not include
|
||||
this setting, so also raise the client timeout when selecting a longer
|
||||
deadline.
|
||||
uses native memory. Independent REA instances have independent queues. Whole
|
||||
operations have a **120-second** execution deadline after reaching the queue's
|
||||
front; upstream decompilation is limited to **90 seconds**.
|
||||
|
||||
Decoded manifest and method text have a **1 MiB** upstream byte budget and report
|
||||
truncation. Class-name pages use indexed slices of up to 4,096 names without changing the
|
||||
|
||||
@@ -24,30 +24,6 @@ missing launcher reports `capability_unavailable` with the
|
||||
`binary_session` uses the same host probe for tool availability; it does not
|
||||
validate a particular APK or guarantee that the selected input can be decoded.
|
||||
|
||||
Client inspection and decode results disclose the following reported-version
|
||||
advisory windows without refusing otherwise compatible launchers:
|
||||
|
||||
| Advisory | Reported version window | Host scope |
|
||||
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ---------- |
|
||||
| [CVE-2024-21633](https://github.com/iBotPeaches/Apktool/security/advisories/GHSA-2hqv-2xv4-5h5w) | Before 2.9.2 | All |
|
||||
| [GHSA-vgwr-4w3p-xmjv](https://github.com/iBotPeaches/Apktool/security/advisories/GHSA-vgwr-4w3p-xmjv) | Before 2.9.3 | Windows |
|
||||
| [CVE-2026-39973](https://github.com/iBotPeaches/Apktool/security/advisories/GHSA-m8mh-x359-vm8m) | 3.0.0 release line through versions before 3.0.2 | All |
|
||||
|
||||
The 2026 advisory names 3.0.1 and its 3.0.2 fix. Inclusion of 3.0.0 is
|
||||
source-derived: [tagged 3.0.0](https://github.com/iBotPeaches/Apktool/blob/f770b39e425af4fa6ac4ca1e9ea6c4824339c6d3/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResTypeSpec.java)
|
||||
passes type names through unchanged; the [3.0.2 patch](https://github.com/iBotPeaches/Apktool/commit/65dd8480dfcb63068562ffaa527f71bb0a9f772c)
|
||||
validates those names at their owner before they reach the output-path producer.
|
||||
Prereleases before the fixed release are conservatively disclosed; the exact
|
||||
`-dirty` downstream marker is compared as a release while preserving its spelling.
|
||||
This is version guidance, not verification of a particular prerelease or decoder.
|
||||
|
||||
A launcher version does not prove the decoder's contents, execution platform,
|
||||
downstream backports, or overall safety. Windows applicability uses the selected
|
||||
local host; an opaque wrapper may run another engine. A missing warning means
|
||||
only that none of these version/host windows matched. Verify the selected
|
||||
decoder's patches before decoding untrusted APKs; the compatibility floor above
|
||||
is not a security recommendation. REA does not fetch advisories at runtime.
|
||||
|
||||
On Windows, a `.bat` or `.cmd` launcher (such as Chocolatey's `apktool.bat`)
|
||||
runs through an explicit `cmd.exe /d /s /c` call. That call has no AutoRun,
|
||||
no delayed expansion, and quotes every argument. A launcher path that
|
||||
@@ -62,15 +38,13 @@ reports `capability_unavailable`.
|
||||
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 --locales de --locales pt-BR
|
||||
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
|
||||
primary `locale` (project `res/values-<locale>/strings.xml` instead of the default
|
||||
table), `locales` (repeatable array of additional localized string tables to project
|
||||
from the same single decode pass), and `include_strings` (default true). Regional locales such as `pt-BR`
|
||||
`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.
|
||||
|
||||
@@ -78,8 +52,6 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
|
||||
|
||||
- **An owned APK snapshot is digested and decoded.** `target.sha256` and
|
||||
`target.bytes` bind the observation to the exact APK that was decoded.
|
||||
The Evidence subject carries the same snapshot digest and caller-selected
|
||||
path, including when the original file changes during decoding.
|
||||
- **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.
|
||||
@@ -87,28 +59,9 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
|
||||
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 examined count.
|
||||
Malformed XML and a wrong document root are whole-document projection
|
||||
failures: the result is partial, the failure reason is disclosed, and entry
|
||||
counts remain unknown. They are not counted as one unsupported string.
|
||||
The default table is bounded to 2000 entries with partial coverage when more
|
||||
exist. `locales` lists observed regular `strings.xml` tables whose exact
|
||||
`values-<locale>` directory is selectable by the request's locale grammar.
|
||||
Locale suffixes allow up to 23 ASCII characters, derived from Apktool's
|
||||
language, script, region, and variant fields; for example,
|
||||
`b+sr+Latn+RS+REVISED` selects that exact table.
|
||||
Other table directories, including combined qualifiers such as
|
||||
`values-en-rUS-v21` and `values-mcc310-fr`, are named in limitations with
|
||||
their source spelling. They are not advertised as selectable locales;
|
||||
REA does not infer Android's runtime resource matching. Non-regular
|
||||
strings-table paths are disclosed with partial coverage. Discovery uses
|
||||
the same bounded traversal as the file count; filesystem failures remain
|
||||
failures rather than being interpreted as missing tables.
|
||||
When multiple tables are requested with `locales`, `string_tables` records
|
||||
each projected table with its locale, status (`present`, `missing`,
|
||||
`oversized`, `malformed`, or `skipped`), entry counts, and coverage,
|
||||
bounded at an aggregate budget of 10,000 strings and 32 MiB XML. When `locales`
|
||||
is omitted, legacy single-table payloads are preserved without adding `string_tables`.
|
||||
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.
|
||||
@@ -128,11 +81,9 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
|
||||
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.
|
||||
- An ordinary nonzero decode exit surfaces as `unsupported_target` naming
|
||||
the caller-selected APK, with Apktool's diagnostic and captured output.
|
||||
Launcher startup, ownership preparation, signal termination and incomplete
|
||||
output collection remain provider failures; they do not establish that the
|
||||
selected APK is unsupported.
|
||||
- Apktool's own decode failures (`AndrolibException`, directory traversal
|
||||
refusals) surface as `unsupported_target` with apktool's reason preserved
|
||||
verbatim.
|
||||
|
||||
## Real verification
|
||||
|
||||
|
||||
@@ -60,15 +60,6 @@ states that absence is unknown. Component arrays remain complete when candidate
|
||||
hypotheses are omitted; component arrays still include every component from
|
||||
the supplied inventory pages, and overall coverage is `partial` in that case.
|
||||
|
||||
Inventoried files whose bytes were not read, such as encrypted archive members,
|
||||
are listed in `unavailable_components` with their original path, format,
|
||||
encryption flag, limitations, and null content identity. The same application-root
|
||||
and AppleDouble attribution rules apply. These files make overall coverage
|
||||
`partial`; component absence is unknown even when `inventory_complete` is true.
|
||||
Directories have no file bytes and symlinks remain in `symlinks`, so neither is
|
||||
an unavailable file component. The additive field participates in `projection_id`,
|
||||
including when empty, so Apple projection identifiers change.
|
||||
|
||||
## Application roots
|
||||
|
||||
| Inventory root | Application root |
|
||||
@@ -77,15 +68,6 @@ including when empty, so Apple projection identifiers change.
|
||||
| `.app` directory | `.`, the inventoried bundle itself |
|
||||
| Directory, ZIP, or DMG containing apps | Each outermost `<Name>.app` followed by `Contents/` |
|
||||
|
||||
File and slice occurrences supply component endpoints. Directory tree identities
|
||||
remain in source inventory and bundle anatomy, and links remain in `symlinks`.
|
||||
|
||||
Root and layout discovery use known directories and ancestors implied by deeper
|
||||
inventory paths. A leaf file or symlink named `*.app`, `Contents`, or `Versions`
|
||||
does not establish that directory. Directory and authenticated-file identity are
|
||||
selected before applying anatomy case preferences, so a file cannot shadow a
|
||||
folded directory name or a directory shadow a metadata/signature file.
|
||||
|
||||
ZIP archives made with `ditto -c -k --keepParent` report `<Name>.app`. A DMG
|
||||
reports `<image>.dmg/<Volume>/<Name>.app`; DMG child inventory needs the native
|
||||
macOS mounting adapter. When a DMG has only its root identity, the projection is
|
||||
|
||||
@@ -26,7 +26,6 @@ graph TD
|
||||
end
|
||||
|
||||
subgraph "Provider Layers"
|
||||
PROVIDER_OWNERS["src/providers/<br/>shared deferred client and inspection owners<br/>exact cleanup retry and attributed failures"]
|
||||
PWNTOOLS["src/native/pwntools/ + src/native/pwndbg/<br/>BYO offline ELF/core adapters<br/>owned snapshots/Python and optional core-only GDB<br/>unchanged upstream parsers, ABI structures and mapping API"]
|
||||
WASM["src/wasm/<br/>caller-supplied WABT; immutable artifact inspection<br/>owned process supervision and retryable workspace cleanup"]
|
||||
EVM["src/evm/<br/>unchanged EVMole/WASM in bounded owned worker<br/>explicit carrier parsing and inferred interface adapter"]
|
||||
@@ -139,11 +138,6 @@ graph TD
|
||||
GHIDRA --> GHIDRA_BRIDGE
|
||||
HOPPER --> PROCESS
|
||||
GHIDRA --> PROCESS
|
||||
GHIDRA --> PROVIDER_OWNERS
|
||||
APP --> PROVIDER_OWNERS
|
||||
PROVIDER_OWNERS --> PROCESS
|
||||
PROVIDER_OWNERS --> AUX
|
||||
PROVIDER_OWNERS --> DOMAIN
|
||||
GHIDRA --> WINDOWS
|
||||
PROCESS --> WINDOWS
|
||||
WINDOWS --> WINDOWS_NATIVE
|
||||
|
||||
@@ -147,24 +147,6 @@ 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.
|
||||
|
||||
## Ghidra process failures
|
||||
|
||||
When output from the failing Ghidra startup or operation reports
|
||||
`java.lang.OutOfMemoryError`, REA returns `resource_constraint`. Java heap or GC
|
||||
overhead exhaustion includes heap-specific recovery advice. Metaspace and array
|
||||
size failures do not recommend increasing the heap; native-thread exhaustion is
|
||||
reported as a capacity constraint with unknown limits.
|
||||
|
||||
`configured_jvm_max_heap` records the explicit `-Xmx` value selected by REA's
|
||||
launch builder. It is a configuration fact, not measured memory use or proof of
|
||||
the effective JVM limit; JVM environment options may affect that limit.
|
||||
When a Windows script wrapper selects the JVM, this value remains unknown.
|
||||
Historical stdout and stderr remain available, but classification uses only the
|
||||
failing operation's `failure_output`. Output draining waits at most one second,
|
||||
subject to earlier cancellation or the startup deadline. `output_incomplete`
|
||||
marks a snapshot taken before stream closure; cleanup ownership remains with
|
||||
the session until release succeeds.
|
||||
|
||||
## Portable PE resources
|
||||
|
||||
`inspect_pe_resources` / `inspect-pe-resources` inspects an explicit PE32 or
|
||||
|
||||
+11
-32
@@ -66,25 +66,14 @@ Electron `file://` pages use a separate provider and target boundary; see [elect
|
||||
|
||||
## Provider authorities
|
||||
|
||||
CDP page capture and V8 Inspector observation attach to an already-running
|
||||
target without launching it, driving actions, or evaluating target code.
|
||||
Playwright scenarios drive actions and capture step snapshots in either a
|
||||
provider-owned browser or a caller-selected external browser. Separate providers
|
||||
preserve these authority and lifecycle differences. They share one exclusion
|
||||
vocabulary (`BrowserExclusionReason`): every denial reason maps onto it, even
|
||||
where a wire schema keeps a narrower historical bucket.
|
||||
|
||||
CDP attachment is not a guarantee that the browser preserves all state.
|
||||
Chromium can clear another client's `navigator.platform` emulation when REA's
|
||||
page session disconnects, even if that session sent no emulation commands.
|
||||
This affects page inspection, bundle capture, session observation, screenshots,
|
||||
WebMCP discovery, and Electron page inspection; target listing alone does not
|
||||
attach a page session. REA cannot read the other client's complete
|
||||
user-agent/client-hint configuration and does not replay guessed settings.
|
||||
Use a disposable browser when preserving externally configured emulation is
|
||||
required, or have the owning client reapply its complete configuration afterward.
|
||||
See [the reproduction and Chromium ownership limitation](https://github.com/morluto/rea/issues/4089).
|
||||
|
||||
CDP page capture, V8 Inspector observation, and Playwright scenarios stay
|
||||
separate providers because their authorities differ: CDP and V8 attach to an
|
||||
already-running target and never launch, drive, evaluate, or mutate it, while
|
||||
Playwright providers own and drive the runtime (launch browsers, run actions,
|
||||
capture step snapshots). Merging them would mix attach-only and owned-process
|
||||
lifecycles in one contract. What they share instead is one exclusion
|
||||
vocabulary (`BrowserExclusionReason`): every denial reason in every stack maps
|
||||
onto it, even where a wire schema keeps a narrower historical bucket.
|
||||
Existing static application Evidence and passive web/Electron captures can be
|
||||
combined later through
|
||||
[JavaScript static/runtime reconciliation](javascript-runtime-reconciliation.md).
|
||||
@@ -285,14 +274,6 @@ REA establishes a main-frame origin boundary before enabling Runtime, Debugger,
|
||||
|
||||
## Data minimization
|
||||
|
||||
The Link projection parses repeated CDP header field lines independently and
|
||||
retains their declarations in order, including derived untrusted agent hints.
|
||||
Commas inside URI targets or quoted parameters remain part of those values.
|
||||
COOP and COEP projections retain the exact declared token after validating the
|
||||
complete Structured Field Item, including parameters such as `report-to`.
|
||||
These are declarations, not an assessment of the document's effective policy;
|
||||
absent, malformed or non-token items project as `null`.
|
||||
|
||||
REA retains local observation data and removes only URL userinfo credentials, explicitly declared scenario secrets, and values from structured credential/storage fields:
|
||||
|
||||
- URL observations preserve the complete local URL, including query values, fragments, duplicate parameters, and their order. Only username/password userinfo is removed; malformed original URL strings remain available with `origin: null`.
|
||||
@@ -328,7 +309,7 @@ REA retains local observation data and removes only URL userinfo credentials, ex
|
||||
an omitted type leaves equality unknown rather than proving a modification.
|
||||
- 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 fingerprints hash all decoded response bytes, including bodies above 64 KiB, subject to the [64 MiB per-message CDP limit](#request-boundary). Missing or undecodable cache bodies and partial IndexedDB remote objects make fingerprint coverage incomplete, so identical observations remain `unknown`.
|
||||
- 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`.
|
||||
- Unavailable or malformed storage inventories mark `storage_keys` unavailable, even without fingerprints. Comparisons suppress inferred key additions and removals while preserving modifications proven by complete fingerprints on both sides. Previously exported captures are not retroactively corrected; recapture them to obtain these coverage markers.
|
||||
- Script metadata is included only when CDP supplies a URL on an allowed origin. Stable keys exclude transient CDP script IDs, and exact transient raw URLs are used only during script/resource reconciliation. URL-less scripts are excluded because their origin cannot be established. When CDP supplies an execution-context association, the accepted script retains its authorized frame ID for later attribution. Script metadata admission bounds retained identity and source-map strings to 8 MiB and 50,000 records. When a source-map URL cannot fit, the script identity remains and source-map coverage reports `resource_budget_exhausted`; rejected script observations are counted without retaining their IDs. Source content is omitted unless explicitly requested and is returned inline as a self-verifying artifact with its SHA-256 digest.
|
||||
|
||||
@@ -362,10 +343,8 @@ an invalid supplied size remains unknown with incomplete resource coverage while
|
||||
the resource's other facts are retained. Zero and nonnegative fractional sizes
|
||||
are preserved.
|
||||
|
||||
CDP discovery has a 10-second deadline. Each WebSocket handshake and command
|
||||
response has its own 20-second deadline, separate from the caller-selected
|
||||
observation window. A stalled handshake or command reports `provider_timeout`;
|
||||
caller cancellation still reports cancellation. WebSocket messages remain subject
|
||||
CDP discovery, connection, and commands wait for the peer or caller cancellation;
|
||||
a stalled peer can leave an operation waiting. WebSocket messages remain subject
|
||||
to the [64 MiB limit](#request-boundary). REA does not impose a message-count or
|
||||
pending-command quota. On cancellation, it closes only its own WebSocket,
|
||||
waiting up to one second before terminating it. Malformed unsolicited events
|
||||
|
||||
@@ -144,36 +144,6 @@ distinction: it closes and deletes provider-owned profiles, but only disconnects
|
||||
from an external CDP browser. Real-browser verification checks both outcomes and
|
||||
confirms that an attached external browser remains alive.
|
||||
|
||||
That cleanup requires REA to remain running. Abrupt termination, including
|
||||
Windows process-tree termination or POSIX `SIGKILL`, can leave the launch
|
||||
profile and Playwright artifacts behind. A profile can retain cookies, history,
|
||||
cache and origin storage. Later REA runs currently do not reclaim these paths.
|
||||
Playwright 1.58.2 can also leave an artifacts directory when launch preparation
|
||||
fails before a browser process exists, such as for a missing executable.
|
||||
POSIX wrappers can request awaited cancellation with `SIGINT` or `SIGTERM`;
|
||||
Windows process termination is not an equivalent graceful-cancellation channel.
|
||||
Do not identify owned artifacts by directory prefix or creation time alone.
|
||||
See [#4659](https://github.com/morluto/rea/issues/4659) for the remaining recovery
|
||||
and wrapper-cancellation work.
|
||||
|
||||
Keeping that browser alive does not guarantee its emulation state survives.
|
||||
Chromium can clear caller-owned `navigator.platform` emulation when a page CDP
|
||||
session disconnects, including sessions that sent no emulation commands. REA
|
||||
cannot snapshot the other client's complete user-agent/client-hint settings and
|
||||
does not replay a partial reconstruction. Use launch mode to keep this effect
|
||||
inside a provider-owned browser, or have the external owning client reapply its
|
||||
complete configuration after capture. Connected captures report this limitation;
|
||||
see [issue #4089](https://github.com/morluto/rea/issues/4089).
|
||||
|
||||
`environment.locale` sets Intl formatting in both modes. Launch also sets
|
||||
`navigator.language`, `navigator.languages`, and the request `Accept-Language`.
|
||||
Connect preserves the caller's page and request languages; every attached
|
||||
capture identifies this locale limitation, including retained partial
|
||||
observations. Use launch mode when the application must select the requested
|
||||
language through navigator values or request headers. Artifact completeness
|
||||
covers the selected observations, not equivalence of launch and connect
|
||||
language environments.
|
||||
|
||||
HTTP(S) URLs may include ordinary query values and fragments directly. Use
|
||||
ordered structured query entries when a value needs to reference a declared
|
||||
environment-backed secret. Form, storage, and cookie values are either literal
|
||||
|
||||
+3
-17
@@ -95,9 +95,8 @@ dependency edges, and the section's file range. A missing `.dep-v0` section is
|
||||
null metadata, not proof that the binary has no dependencies. See
|
||||
[Rust binaries](rust-binaries.md).
|
||||
|
||||
Configure [Hopper or Ghidra](installation.md#hopper), the
|
||||
[IDA adapter](ida-provider.md), or [Kuna](kuna-provider.md) before analyzing a
|
||||
native target. Substitute
|
||||
Configure [Hopper or Ghidra](installation.md#hopper), or the
|
||||
[IDA adapter](ida-provider.md), before analyzing a native target. Substitute
|
||||
your target, search text and function name or address in these examples:
|
||||
|
||||
```bash
|
||||
@@ -168,12 +167,6 @@ be verified. See [MCP contracts](mcp-contracts.md) for session lifecycle and
|
||||
[Ghidra first-query deadlines](mcp-contracts.md#ghidra-first-query-deadlines-and-recovery)
|
||||
for import, client timeouts and recovery.
|
||||
|
||||
If one-shot analysis fails and closing its session also fails, the original
|
||||
error details remain inline and `details.cleanup_error` describes the later
|
||||
close failure. Each diagnostic retains its own reported resources; the later
|
||||
failure does not establish whether an earlier resource was released. Captured
|
||||
output and partial observations remain in the original details.
|
||||
|
||||
## Save and reuse analysis snapshots
|
||||
|
||||
A snapshot retains successful analysis results for later queries. REA reuses
|
||||
@@ -321,9 +314,7 @@ diagnostics appear inside the report when `--full-output` is selected. Log
|
||||
truncation alone does not change the diagnostic health or exit status.
|
||||
|
||||
The default terminal format is TOON. Use `--json` when saving results for a
|
||||
JSON consumer. Valued output flags (`--format`, `--filter-output`,
|
||||
`--token-limit`, `--token-offset`) accept `--flag value` or `--flag=value`; a
|
||||
missing value fails with `MISSING_OUTPUT_VALUE` before the command runs. `--json` is indented on a terminal and compact when piped or
|
||||
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.
|
||||
@@ -361,11 +352,6 @@ command, objdump, Rizin and GDB. In these paths, a returned structured
|
||||
signal-derived status. This describes the current source routing; it is not a
|
||||
claim that every command or provider runtime has been independently exercised.
|
||||
|
||||
When the reader of piped output closes early, as `rea ... | head` does, the
|
||||
CLI stops writing, prints no error and exits `141` (`128 + 13`, the status of a
|
||||
SIGPIPE-terminated writer). The operation itself may have completed; only its
|
||||
output was declined.
|
||||
|
||||
`inspect-artifact` also returns a structured cancelled result, but its direct
|
||||
analysis cancellation path does not set a signal-derived exit status, so it
|
||||
exits `1`. Setup has its own contract: cancellation exits `0`. Treat the
|
||||
|
||||
@@ -52,16 +52,10 @@ in the file the installed app reads:
|
||||
`%APPDATA%` file it still reads; with neither file, setup creates the
|
||||
private copy.
|
||||
- If `%LOCALAPPDATA%\Packages` holds a `Claude_<publisher ID>` package from
|
||||
another publisher, an `AnthropicPBC.Claude_<publisher ID>` package, or cannot
|
||||
be read, REA cannot establish which file Claude
|
||||
another publisher, or cannot be read, REA cannot establish which file Claude
|
||||
Desktop reads. Setup, doctor and uninstall report that instead of falling
|
||||
back to `%APPDATA%`. Doctor then reports `claude_desktop` as invalid, and
|
||||
uninstall stops before removing anything for any client.
|
||||
The reported `AnthropicPBC.Claude_fnn82j28hfe8t` build can use the `Claude-3p`
|
||||
deployment directory. REA recognizes that package as an unresolved location;
|
||||
it does not assume that it reads the legacy AppData file or automatically
|
||||
register in `Claude-3p`. See [#4432](https://github.com/morluto/rea/issues/4432)
|
||||
for the reported build and manual registration evidence.
|
||||
|
||||
Quit Claude Desktop fully before approving setup; closing its window is not
|
||||
enough. A running Claude Desktop can rewrite its configuration from memory and
|
||||
@@ -146,38 +140,8 @@ profiles](mcp-contracts.md#output-schemas).
|
||||
Setup registers `rea` in `~/.kimi-code/mcp.json`, or
|
||||
`$KIMI_CODE_HOME/mcp.json` when set, while preserving unrelated settings and
|
||||
creating a `.rea.backup` before updating an existing file. Kimi Code infers
|
||||
stdio from the `command` entry, so setup does not add a `type` field. New
|
||||
registrations include `startupTimeoutMs = 30000` and a `toolTimeoutMs` derived
|
||||
from REA's known provider allowance plus 120 seconds of operation
|
||||
headroom. The default is 450000 ms, covering the default 330-second Ghidra
|
||||
startup; an explicit Ghidra startup timeout of 2700000 ms produces a 2820000 ms
|
||||
tool timeout. The startup allowance follows an explicitly selected Ghidra or
|
||||
Hopper provider, and otherwise uses the larger known Ghidra/Hopper deadline.
|
||||
An explicit `REA_JEB_MCP_TIMEOUT_MS` request budget also contributes to that
|
||||
maximum. For `ida` or `auto` selection, a valid IDA registration's parsed
|
||||
`timeoutMs` also contributes to that maximum; its default is 300000 ms.
|
||||
Setup forwards these explicitly selected REA deadlines and the input schema
|
||||
profile into the registration; unrelated process values are omitted. An
|
||||
explicit `REA_JADX_OPERATION_TIMEOUT_MS` is forwarded with the JADX
|
||||
registration but does not contribute to the derived tool timeout; raise
|
||||
`toolTimeoutMs` to cover a longer selected JADX deadline.
|
||||
This headroom is a practical default, not a guarantee for every analysis
|
||||
duration. Setup preserves positive timeout values already in the `rea` entry.
|
||||
You can edit `startupTimeoutMs` and `toolTimeoutMs` there; doctor keeps positive
|
||||
caller-selected values aligned and reports a non-blocking advisory when a tool
|
||||
timeout is shorter than the known provider allowance.
|
||||
Setup selects the compact input-schema advertisement for new or refreshed Kimi
|
||||
registrations unless their stored configuration or setup environment explicitly
|
||||
selects `REA_MCP_INPUT_SCHEMA_PROFILE=full` or `compact`. This keeps REA's
|
||||
canonical tool validation unchanged while avoiding a Moonshot Kimi Code 2.2.0
|
||||
failure observed with the full catalog: its request was rejected because a
|
||||
single tool schema exceeded the provider's size limit. The limit is
|
||||
provider-specific and not an MCP protocol limit. `rea doctor --client kimi`
|
||||
reports an older registration with no explicit profile as stale. To restore the
|
||||
compact profile, run `rea setup --client kimi` or add
|
||||
`REA_MCP_INPUT_SCHEMA_PROFILE=compact` to the registration's `env`, then restart
|
||||
Kimi Code. An explicit `full` profile remains respected and can still exceed
|
||||
Moonshot's limit.
|
||||
stdio from the `command` entry, so setup does not add a `type` field. The
|
||||
registration includes `startupTimeoutMs = 30000` and `toolTimeoutMs = 120000`.
|
||||
Kimi Code also discovers personal skills in `~/.agents/skills` and project-local
|
||||
`.agents/skills`, so no separate skill root is required; setup still installs
|
||||
and verifies the matching skill files through the normal shared-skill flow.
|
||||
@@ -243,23 +207,8 @@ standalone CLI check.
|
||||
|
||||
## Codex and Devin
|
||||
|
||||
Codex treats an unset or empty `CODEX_HOME` as `~/.codex`. Its MCP server
|
||||
registration supports `startup_timeout_sec` for connection initialization and
|
||||
`tool_timeout_sec` for each tool call. New REA registrations use a 30-second
|
||||
startup timeout and a tool timeout derived from the known provider
|
||||
allowance plus 120 seconds of operation headroom. This yields 450 seconds for
|
||||
the default Ghidra allowance; an explicit Ghidra startup timeout of 2700
|
||||
seconds yields 2820 seconds. Setup preserves positive caller-selected timeout
|
||||
values in the REA entry, and doctor reports a non-blocking advisory when a tool
|
||||
timeout is shorter than the known provider allowance. An explicitly selected
|
||||
JEB request budget also contributes to the allowance. A configured IDA
|
||||
registration's parsed `timeoutMs` contributes for `ida` or `auto` selection.
|
||||
An explicit `REA_JADX_OPERATION_TIMEOUT_MS` is forwarded with the JADX
|
||||
registration but does not contribute; raise `tool_timeout_sec` to cover a
|
||||
longer selected JADX deadline.
|
||||
These values are client-side deadlines, so increase them in `~/.codex/config.toml` if a
|
||||
workload needs more time. Devin honors `XDG_CONFIG_HOME` for its
|
||||
`devin/mcp_config.json` on non-Windows systems.
|
||||
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.
|
||||
|
||||
## OMP
|
||||
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
|
||||
REA can attach to an Electron/Chromium CDP endpoint and inspect existing `file://` renderer pages without evaluating JavaScript or invoking Electron APIs. The request supplies the endpoint directly; REA accepts only literal-port loopback HTTP endpoints. Selecting an endpoint exposes every Electron target it serves, including local file paths and page metadata.
|
||||
|
||||
Disconnecting the inspection's page session can clear caller-owned
|
||||
`navigator.platform` emulation inside Chromium. REA cannot restore another
|
||||
client's complete user-agent/client-hint configuration. Use a disposable target
|
||||
or let the owning client reapply its configuration; see the shared
|
||||
[CDP state limitation](browser-observation.md#provider-authorities).
|
||||
|
||||
This passive runtime surface is distinct from the target-free static
|
||||
[`analyze_javascript_application`](javascript-artifact-reconstruction.md)
|
||||
workflow. Static analysis reads a local ASAR or extracted directory without
|
||||
@@ -56,15 +50,8 @@ rea inspect-electron-page http://127.0.0.1:9223 TARGET_ID \
|
||||
|
||||
The normalized result contains canonical local paths, frame and DOM
|
||||
structure, resource metadata, stable script/resource identities, explicit
|
||||
completeness, and content-addressed script artifacts. Resource sizes are unknown
|
||||
when omitted or invalid; supplied invalid sizes also produce an explicit
|
||||
completeness diagnostic.
|
||||
|
||||
DOM node indices retain their snapshot positions. Invalid rows are omitted with
|
||||
completeness diagnostics, so `total_nodes` can exceed the retained node count
|
||||
and a parent index can refer to an omitted source node.
|
||||
|
||||
Script metadata retains its execution-context frame ID when CDP supplies one. The capture also
|
||||
completeness, and content-addressed script artifacts. Script metadata
|
||||
retains its execution-context frame ID when CDP supplies one. The capture also
|
||||
inventories worker, service-worker, and shared-worker targets with
|
||||
validated opener-target and parent-frame IDs. Worker discovery uses passive
|
||||
target metadata; REA does not attach to or execute code in those targets.
|
||||
@@ -114,18 +101,8 @@ scenario controls; their attempted and observed outcomes remain in the
|
||||
timeline. The active hook blocks and records external shell/navigation,
|
||||
permission, download, popup, updater, and OS-integration effects. The timeline
|
||||
is explicitly partial when attachment starts after application activity. The
|
||||
startup, including the initial state snapshot, has a 60-second deadline.
|
||||
Actions wait until completion or request cancellation; a click whose target
|
||||
never appears, or a `wait` without `window_index` in an app that opens no
|
||||
window, remains pending until cancelled. After cancellation, the final state
|
||||
read has 5 seconds before REA keeps the initial snapshot instead; the
|
||||
cancellation keeps the caller's reason and records that expiry in its
|
||||
diagnostics.
|
||||
Blocked synchronous shell APIs keep their return contracts:
|
||||
`showItemInFolder` returns `undefined` and `writeShortcutLink` returns `false`.
|
||||
Their `shell-attempt` events record the blocked phase and argument shapes;
|
||||
neither result means the requested host operation occurred. The existing
|
||||
`openExternal` and `openPath` blocks continue to reject their promises.
|
||||
startup has a 60-second deadline. Actions wait until completion or request
|
||||
cancellation; a click whose target never appears remains pending until cancelled.
|
||||
CLI SIGINT/SIGTERM requests cancellation and awaits owned-process cleanup.
|
||||
Window IDs, URLs, and cached titles come from one main-process Electron snapshot,
|
||||
so a crashed renderer does not require a successful renderer-side title query.
|
||||
@@ -139,69 +116,6 @@ If cleanup cannot be verified, the error retains collected observations in
|
||||
`details.partial_observation` and marks their application cleanup `unverified`.
|
||||
Cleanup uncertainty does not authorize signaling unrelated processes.
|
||||
|
||||
Main-process IPC recording keeps original-function removal for `on` and `once`
|
||||
registrations and records a fired `once` callback once. Native Node.js owns
|
||||
`once` registration, firing and callable dispatch as well as removal order and
|
||||
traversal, including listeners registered by removal observers;
|
||||
the hook translates only its own recording wrappers at the removal boundary.
|
||||
Wrapper metadata uses weak keys and does not retain removed registrations.
|
||||
Wrapper metadata operations, private collection methods and traversal constructors are captured
|
||||
before target startup; later replacement of their global bindings does not
|
||||
change listener registration or removal.
|
||||
|
||||
Native runtimes differ in whether `once` consults callback `.call` or `.apply`.
|
||||
The hook observes actual callback entry without imposing another runtime's
|
||||
property reads or argument-list representation. Application methods selected by
|
||||
native dispatch keep their original receiver and argument-list object; opaque
|
||||
methods produce a `custom-call` or `custom-apply` observation gap when callback
|
||||
execution cannot be established.
|
||||
|
||||
If native wrapper creation or registration-method lookup could expose private
|
||||
instrumentation through an application getter, setter or Proxy, registration
|
||||
stays native and unwrapped. The `once-metadata` observation gap identifies that
|
||||
unobserved registration attempt; it does not prove registration or delivery. The original callback,
|
||||
metadata writes and native method receivers are preserved, including when
|
||||
registration fails. Later registrations resume normal observation. Non-callable
|
||||
`call`/`apply` properties produce failed observation gaps when native dispatch reads
|
||||
them; callback entry is not fabricated.
|
||||
|
||||
An `on` listener's application-defined `.apply` receives the original argument-list
|
||||
object unchanged. Borrowing the exposed method preserves its dynamic receiver.
|
||||
Because that method owns argument interpretation and may not
|
||||
invoke the callback, the hook records a bounded `ipc-observation-gap` timeline
|
||||
entry with the registered channel rather than an IPC invocation. Its empty
|
||||
`argument_shapes` means unobserved arguments, not a zero-argument callback;
|
||||
callback execution and result remain unknown. Coverage and retention include
|
||||
these gaps even when their individual records are dropped. Normal native
|
||||
dispatch continues to record actual invocation frames. Evidence snapshots copy
|
||||
retained arrays and counters without invoking application iterators or Array
|
||||
species.
|
||||
|
||||
Listener-chain recognition distinguishes owned, unowned and unknown metadata.
|
||||
Data links may be inherited; absence is established only after completing the
|
||||
bounded prototype lookup. Exhausting either walk, encountering a getter or seeing a Proxy leaves
|
||||
ownership unknown. The hook preserves native registration without adding another
|
||||
recording wrapper and retains a `listener-chain` observation gap after successful
|
||||
registration. This gap does not prove IPC delivery. An existing inner recording
|
||||
wrapper can still report its actual invocation; otherwise callback activity
|
||||
remains unobserved. Setter-only properties have a known undefined read.
|
||||
Data-descriptor parsing is shared with removal normalization.
|
||||
|
||||
This does not establish complete JavaScript function introspection equivalence.
|
||||
Caller-defined `.listener` properties can change the identity exposed by
|
||||
`listeners()` and meta-events; accessors and Proxy metadata are not followed for
|
||||
wrapper recognition. Re-registering a raw recording wrapper on another channel
|
||||
retains the original registration's channel attribution.
|
||||
Mutating `.listener` on a raw recording wrapper can also prevent removal through
|
||||
application decorators; the reproduced identity conflict is tracked in
|
||||
[#4513](https://github.com/morluto/rea/issues/4513).
|
||||
|
||||
### Target fuse prerequisites
|
||||
|
||||
Active scenario capture requires that the target Electron executable honors Node CLI inspector flags (`--inspect` or `--remote-debugging-port`) so that Playwright can establish its DevTools protocol session.
|
||||
|
||||
When an Electron executable explicitly disables the `EnableNodeCliInspectArguments` fuse (or removes the capability), `capture-electron-scenario` fails immediately before process launch with an `AnalysisUnsupportedTargetError` ("unsupported_target") rather than waiting for the startup deadline. For targets with disabled inspector fuses, use passive CDP inspection via `inspect_electron_page` or run against an unrestricted development binary with the extracted `app.asar`.
|
||||
|
||||
The real verifier exercises compiled CLI and stdio MCP discovery, page/script
|
||||
inspection, static/runtime reconciliation, active observation, and CLI SIGTERM
|
||||
cleanup before checking the IPC, renderer crash/reload, utility/child-process,
|
||||
|
||||
@@ -153,9 +153,7 @@ tree semantics, vulnerability scanning, emulation or hardware runtime capture.
|
||||
## Resource and lifecycle policy
|
||||
|
||||
- Nonempty regular firmware inputs: at most **128 MiB**, copied and hashed into
|
||||
a private workspace before analysis. Growth beyond that allowance during
|
||||
copying receives the same typed input refusal as an already oversized file.
|
||||
Supply a stable copy within the allowance. No in-place source modification.
|
||||
a private workspace before analysis. No in-place source modification.
|
||||
- One queued heavy operation per provider instance; Binwalk one thread and
|
||||
Unblob one worker. No automatic parallel extraction engines.
|
||||
- **120-second** deadline; inherited **1 GiB per-process address-space** limit,
|
||||
|
||||
@@ -124,10 +124,6 @@ FileBytes digests, every source mapping and its memory digest, relocation record
|
||||
module partitions, relocation fixups and linear coordinates rather than relying
|
||||
on the imported executable SHA alone.
|
||||
|
||||
Expected DOS relocation records retain each fixup's pre-application bytes and
|
||||
applied value. Their memory-byte windows come from the final relocated image,
|
||||
including changes made by later overlapping fixups.
|
||||
|
||||
The result is `verified`, `mismatch`, or `unsupported`. Every check retains its
|
||||
expected and observed values. A memory-digest mismatch identifies the source
|
||||
range's file offset and analysis address; it does not locate the first differing
|
||||
@@ -138,10 +134,6 @@ their contents and DOS runtime semantics are not verified. Independent verificat
|
||||
also covers explicit [raw-binary imports](raw-binary.md); other formats return
|
||||
`unsupported` with measured observations.
|
||||
|
||||
MZ verification retains the initialized image described by the header's page
|
||||
count and streams appended overlay bytes into the complete original and modified
|
||||
source digests. Overlay size does not increase the retained image allocation.
|
||||
|
||||
`read_bytes` returns initialized provider memory, including loader fixups; an
|
||||
unmapped or uninitialized byte ends the read with an explicit returned length and
|
||||
`complete: false`. `address_to_file_offset` uses the provider's source mapping;
|
||||
|
||||
@@ -69,12 +69,6 @@ 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 bridge resolves the caller's address spelling once; metadata lookup uses
|
||||
its canonical default-space identity. Bare hexadecimal, prefixed hexadecimal,
|
||||
and encoded default-space selectors therefore select the same MethodTable.
|
||||
Other address spaces and unresolved identities are not matched by offset alone.
|
||||
Metadata already supplied by the engine is retained without reading or deriving
|
||||
an additional source snapshot.
|
||||
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
|
||||
|
||||
+3
-28
@@ -65,14 +65,6 @@ PDB, or change analyzer settings.
|
||||
|
||||
## Loaded addresses and file offsets
|
||||
|
||||
Ghidra computes overview procedure and string counts from the same inventories
|
||||
used by `list_procedures` and `list_strings`, without transporting those rows
|
||||
solely to count them. Counts include external functions and only Ghidra-defined
|
||||
strings; they do not establish discovery of unidentified functions or undefined
|
||||
string bytes. Complete inventories remain available through the list tools.
|
||||
Overview reuse follows the target/profile snapshot lifetime and is invalidated
|
||||
by session metadata edits.
|
||||
|
||||
`rea analyze <path> --provider ghidra --json` and MCP `binary_overview` report
|
||||
the observed loaded `image_base` in `normalized_result`. They retain each
|
||||
segment's reported `image_base` and `address_space`. A provider that does not
|
||||
@@ -147,19 +139,6 @@ overview merely because its source artifact is unchanged.
|
||||
|
||||
## Admitted function-analysis semantics
|
||||
|
||||
Concurrent callers share one startup while retaining independent cancellation.
|
||||
Only the final departing caller abandons startup and waits for its cleanup.
|
||||
New attempts wait for that cleanup; failed cleanup retains its original error
|
||||
and owned directories until a successful close. Closing the provider reports a
|
||||
provider-state failure to live callers rather than cancelling their signals.
|
||||
|
||||
Configured analysis extensions and seeds use owned file reads during profile
|
||||
resolution and launch snapshots. A changed read extent or descriptor state
|
||||
refuses the commitment. Failed source or snapshot descriptor closes remain
|
||||
owned and block new admission until cleanup succeeds; the physical failure
|
||||
and exact cancellation reason remain available. Provider shutdown joins all
|
||||
profile stages before retrying their retained descriptors.
|
||||
|
||||
| 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. |
|
||||
@@ -174,8 +153,8 @@ profile stages before retrying their retained descriptors.
|
||||
|
||||
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, incoming and outgoing
|
||||
references, callee and caller reads, and dossiers report observed terminal call sites in Evidence limitations,
|
||||
Pseudocode, assembly, procedure info, instruction windows, callee and caller
|
||||
reads, and dossiers report observed terminal call sites in Evidence limitations,
|
||||
including resolved callee names, addresses, and FunctionManager flags when
|
||||
available. On x86-32, the same views also report the exact Borland/Delphi-style
|
||||
FS exception-registration pattern when its handler address falls outside the
|
||||
@@ -214,11 +193,7 @@ 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`, `-- --arm`, or `-- --arm64` selects another target architecture;
|
||||
`-- --dll` selects DLLs. Choose one architecture and optionally combine it with
|
||||
`--dll`. These static fixtures contain source-owned encoded instructions; they
|
||||
are not compiler-produced programs. See the [Windows verification scope](windows-ghidra-p0.md#native-authority-and-target-identity)
|
||||
for real-provider coverage and exclusions.
|
||||
`-- --x86` selects x86 and `-- --dll` selects DLLs, and the flags can be combined.
|
||||
These lanes check all 26 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.
|
||||
|
||||
+2
-13
@@ -39,8 +39,8 @@ container format, architecture, word size and byte order. A recognized
|
||||
- `module.dependencies`, with the same fields and their original order;
|
||||
- `module.settings`, retaining ordered key/value entries and duplicate keys;
|
||||
- `module.unparsed_lines`, `module.unparsed_line_bytes_base64` and
|
||||
`module.complete`, which says whether every present module-text line was
|
||||
parsed. It does not establish that the dependency inventory is complete.
|
||||
`module.complete`, so unfamiliar, malformed, conflicting or undecodable records
|
||||
do not disappear behind a complete result.
|
||||
|
||||
Missing checksums are `null`; empty fields and development/local replacement
|
||||
versions remain unchanged. Build settings such as `GOOS`, `GOARCH` or `vcs.revision`
|
||||
@@ -50,13 +50,6 @@ base64 while other decodable module records are still reported; the reader does
|
||||
not insert replacement characters or reject the entire artifact for those
|
||||
strings.
|
||||
|
||||
When no main-module (`mod`) record was decoded, `module.main` is `null` and
|
||||
dependency coverage is unknown. Successfully decoded dependency records remain
|
||||
visible. GOPATH-mode builds may contain only a package `path` and build settings;
|
||||
their empty dependency array does not establish the absence of dependencies.
|
||||
The result's limitations state this explicitly. A module-mode build with a main
|
||||
module record and no dependency records has an observed empty dependency list.
|
||||
|
||||
## Supported boundary
|
||||
|
||||
The built-in TypeScript reader supports ELF, PE and thin Mach-O images with Go's
|
||||
@@ -91,10 +84,6 @@ host permission denial, changed artifacts and cancellation retain distinct
|
||||
errors. The selected file is never modified; this inspection creates no
|
||||
temporary files, starts no subprocesses and accesses no network endpoint.
|
||||
|
||||
An input above 256 MiB returns `resource_constraint` with resource `file-size`
|
||||
and `reported_limits.maximum_input_bytes`. Select a suitable input within that
|
||||
fixed allowance; changing an output-write or transport budget does not admit it.
|
||||
|
||||
Resource guards bound the selected file and cumulative header searches to 256 MiB
|
||||
each, aggregate embedded strings
|
||||
to 1 MiB, structural table decoding to 16 MiB and the complete normalized metadata
|
||||
|
||||
@@ -45,12 +45,6 @@ The MCP tool `project_harmony_application_graph` takes the same
|
||||
- path-based N-API bridge hypotheses between bytecode and `libs/<abi>` native
|
||||
libraries
|
||||
|
||||
File and slice occurrences supply component and child-package paths; directory
|
||||
trees and symlinks retain their identities in the source inventory without
|
||||
being classified as code files. Ark and JavaScript runtime hints summarize the
|
||||
classified bytecode and JavaScript lists; supported source extensions share the
|
||||
same classification rule as their component rows.
|
||||
|
||||
Every claim is path-presence only. Manifest semantics (module identity,
|
||||
abilities, entry points, permissions, dependencies), Ark bytecode contents and
|
||||
versions, resource resolution, signing verification, and observed native
|
||||
|
||||
@@ -8,8 +8,6 @@ Choose one lifecycle mode in an upstream MCP JSON registration. Set `REA_IDA_MCP
|
||||
|
||||
Each mode accepts one upstream tool profile, checked against `tools/list` before any analysis runs. The attached profile requires the legacy GUI tool names; upstream 2.0.0 renamed those tools, and REA has not established an equivalent attached-mode lifecycle and ownership contract for that catalog. It therefore fails closed with the missing tool names in the error diagnostics.
|
||||
|
||||
Startup failures identify the accepted REA analysis operation. Missing-profile and typed startup transport failures retain the original stage in `details.diagnostics.startup_operation`; existing diagnostics, timeout budgets and resource limits remain available. Startup remains shared within a session; each caller receives its own operation attribution. Cancellation retains live cleanup ownership, so a successful retry releases the originating cancellation outcome as well.
|
||||
|
||||
The headless profile is defined by the database-supervisor API, not by an upstream version string. The upstream source snapshot [`c133c385`](https://github.com/mrexodia/ida-pro-mcp/tree/c133c3853faa111a9b00ee615c013b720d0c4acd) includes `idb_close` (introduced by [upstream PR #495](https://github.com/mrexodia/ida-pro-mcp/pull/495)) alongside `idb_open` and `idb_list`. Earlier builds may report the same `2.0.0` version while lacking that tool, so REA checks the live catalog rather than treating a version number or branch name as a compatibility guarantee.
|
||||
|
||||
| Mode | Upstream profile | Known working |
|
||||
@@ -41,7 +39,7 @@ rea function /absolute/path/to/program main --json
|
||||
rea decompile /absolute/path/to/program main --json
|
||||
```
|
||||
|
||||
Open the **original input binary** in REA, not an `.idb` or `.i64` database. Its SHA-256 must match IDA's recorded input hash. REA checks the attached identity and image base around each analysis request. A mismatch or target switch fails with recovery guidance. The original input must remain readable by REA; WSL can use its mounted alias while the GUI runs on Windows. Attached profiles, including native mode, refuse universal Mach-O inputs at admission: every slice shares the recorded whole-file hash, so REA cannot verify which slice the GUI loaded. Open a thin file extracted with `lipo -thin` in both IDA and REA, or use headless mode, which analyzes the selected slice.
|
||||
Open the **original input binary** in REA, not an `.idb` or `.i64` database. Its SHA-256 must match IDA's recorded input hash. REA checks the attached identity and image base around each analysis request. A mismatch or target switch fails with recovery guidance. The original input must remain readable by REA; WSL can use its mounted alias while the GUI runs on Windows.
|
||||
|
||||
REA's close operation releases its MCP connection or proxy. It never saves or closes the existing GUI database. External edits remain visible because results are live and are not replayed from snapshots. These checks do not lock the GUI or prove that the database is unpatched.
|
||||
|
||||
@@ -133,9 +131,9 @@ Use a package version that actually includes this adapter; repository main can b
|
||||
{"name":"close_binary","arguments":{}}
|
||||
```
|
||||
|
||||
Opening an MCP target starts its selected provider session; headless opening waits for auto-analysis. Set the agent's MCP request deadline long enough for the target. The registration's optional `timeoutMs` defaults to 300000 for upstream requests. An upstream SDK request that reaches this limit returns `provider_timeout` with its operation and actual request budget. A freshly opened headless worker can briefly report `status: "busy"` from `server_health`; REA re-reads health every 100 ms until the worker answers, the caller cancels, or `timeoutMs` has elapsed since the first read. Each health request is capped by the time remaining in that overall wait, so a stalled read cannot extend the readiness deadline by another full request timeout. Expiry while the worker is still busy produces a retryable `provider_timeout`; no further read is started after the deadline. That error names the busy tool from the last observation, or `unknown` when the worker reported none or a value that is not tool-name-shaped. If a health request itself consumes the remaining wait budget, the same last-busy timeout is returned with the stalled request's captured output. Cancellation during the wait produces `cancelled`. Any other unexpected health payload, including a busy payload with an invalid shape, remains `unreadable_output`. Cancellation drains the current upstream request before cleanup; it does not force-stop GUI analysis. An open request that times out without a completed response retains the private workspace because worker inventory alone cannot prove the request has stopped. `binary_session` reports actual tool availability. Repeated doctor/setup calls are unnecessary when the registration already works.
|
||||
Opening an MCP target starts its selected provider session; headless opening waits for auto-analysis. Set the agent's MCP request deadline long enough for the target. The registration's optional `timeoutMs` defaults to 300000 for upstream requests. A freshly opened headless worker can briefly report `status: "busy"` from `server_health`; REA re-reads the health every 100 ms until the worker answers, the caller cancels, or `timeoutMs` has elapsed since the first read. Only expiry while the worker is still busy produces a retryable `provider_timeout`; no further read is started once the deadline has passed. That error names the busy tool of the last observation, or `unknown` when the worker reported none or a value that is not tool-name-shaped. Cancellation during the wait produces `cancelled`. Any other unexpected health payload, including a busy payload with an invalid shape, remains `unreadable_output`. Cancellation drains the current upstream request before cleanup; it does not force-stop GUI analysis. An open request that times out without a completed response retains the private workspace because worker inventory alone cannot prove the request has stopped. `binary_session` reports actual tool availability. Repeated doctor/setup calls are unnecessary when the registration already works.
|
||||
|
||||
For guided registration, set `REA_IDA_MCP_CONFIG` before `rea setup --client <client>`. Setup includes that file reference in its reviewed plan and preserves it after approval; it does not copy upstream credentials into the agent configuration. For `ida` or `auto` selection, Codex/Kimi setup and doctor use the effective client registration's parsed `timeoutMs` (default 300000 ms) when recommending the agent's per-tool deadline. Existing positive client deadlines remain caller choices. `rea doctor --provider ida --json` validates the registration without starting IDA and explicitly leaves runtime compatibility and target binding for analysis.
|
||||
For guided registration, set `REA_IDA_MCP_CONFIG` before `rea setup --client <client>`. Setup includes that file reference in its reviewed plan and preserves it after approval; it does not copy upstream credentials into the agent configuration. `rea doctor --provider ida --json` validates the registration without starting IDA and explicitly leaves runtime compatibility and target binding for analysis.
|
||||
|
||||
## Coverage and evidence
|
||||
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ For runtime instrumentation, see the [Frida guide](./frida-instrumentation.md).
|
||||
| Task | Guides |
|
||||
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-binaries.md), [Rust dependencies](rust-binaries.md), [offline ELF layout](binary-diagnostics.md), [recorded crashes](recorded-crashes.md) |
|
||||
| Select a native provider or import format | [Ghidra semantics](ghidra-provider.md), [Windows](windows-ghidra-p0.md), [DOS](ghidra-dos.md), [raw bytes](raw-binary.md), [MIPS](ghidra-mips.md), [PSP](ghidra-psp.md), [NativeAOT](ghidra-nativeaot.md), [IDA](ida-provider.md), [Kuna](kuna-provider.md), [JEB](jeb-analysis.md) |
|
||||
| Select a native provider or import format | [Ghidra semantics](ghidra-provider.md), [Windows](windows-ghidra-p0.md), [DOS](ghidra-dos.md), [raw bytes](raw-binary.md), [MIPS](ghidra-mips.md), [PSP](ghidra-psp.md), [NativeAOT](ghidra-nativeaot.md), [IDA](ida-provider.md), [JEB](jeb-analysis.md) |
|
||||
| Analyze JavaScript or Electron artifacts | [Static analysis](javascript-artifact-reconstruction.md), [tracing and comparisons](javascript-application-workflows.md), [application graph](javascript-application-graph.md), [source recovery](javascript-recovery.md) |
|
||||
| Compare static JavaScript with runtime observations | [Runtime attribution](javascript-runtime-observation.md), [reconciliation](javascript-runtime-reconciliation.md), [Electron observation](electron-observation.md), [Electron fuses](electron-fuses.md) |
|
||||
| Inspect assemblies, packages, or firmware | [.NET](managed-code-analysis.md), [Android](android-analysis.md), [Apktool resources](apktool-resource-analysis.md), [ADB acquisition](adb-device-analysis.md), [Apple](apple-application-analysis.md), [Harmony](harmony-analysis.md), [firmware](firmware-analysis.md), [WASM](wasm-artifacts.md), [EVM](evm-bytecode.md) |
|
||||
|
||||
+28
-173
@@ -3,13 +3,13 @@
|
||||
Run REA, connect your selected agents, and check the tools needed for your task.
|
||||
Setup previews configuration changes and asks for approval before applying them.
|
||||
|
||||
| Task | Section |
|
||||
| --------------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| Connect an agent | [Start setup](#start-setup), then [review changes](#review-setup-changes) |
|
||||
| Diagnose one task | [Scoped readiness checks](#check-readiness-for-your-task) |
|
||||
| Configure an analysis engine | [Hopper](#hopper), [Ghidra](#ghidra), the [IDA guide](ida-provider.md), or [Kuna](kuna-provider.md) |
|
||||
| Update or remove REA | [Maintenance](#diagnose-update-and-remove) |
|
||||
| Resolve a client-specific problem | [Client configuration](client-configuration.md) |
|
||||
| Task | Section |
|
||||
| --------------------------------- | ------------------------------------------------------------------------- |
|
||||
| Connect an agent | [Start setup](#start-setup), then [review changes](#review-setup-changes) |
|
||||
| Diagnose one task | [Scoped readiness checks](#check-readiness-for-your-task) |
|
||||
| Configure an analysis engine | [Hopper](#hopper), [Ghidra](#ghidra), or the [IDA guide](ida-provider.md) |
|
||||
| Update or remove REA | [Maintenance](#diagnose-update-and-remove) |
|
||||
| Resolve a client-specific problem | [Client configuration](client-configuration.md) |
|
||||
|
||||
## Start setup
|
||||
|
||||
@@ -57,26 +57,12 @@ Before applying changes, REA checks your current configuration. The plan lists:
|
||||
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 and comments,
|
||||
create backups, stage changes in a private directory, and verify their result.
|
||||
Before publication, they refuse detected changes to the selected configuration.
|
||||
Replacement uses an explicit destination under the selected canonical parent;
|
||||
it does not follow a newly inserted destination symlink. First-run setup uses
|
||||
an exclusive hard link and fails without overwriting a newly created destination;
|
||||
filesystems without hard-link support cannot publish a first-run configuration.
|
||||
Setup and uninstall retain an existing `.rea.backup` rather than replacing the
|
||||
first snapshot.
|
||||
If that snapshot differs from the current configuration, setup and uninstall
|
||||
preserve a verified `.rea.backup.<sha256>.recovery` copy of the current bytes
|
||||
before editing; setup also previews it. Both snapshots remain available.
|
||||
When an edit made a backup, a failed uninstall update or restore, and a failed
|
||||
setup readback or rollback, name the backup path that holds the bytes from just
|
||||
before that edit.
|
||||
If setup cannot verify a newly created configuration, it retains the file and
|
||||
reports manual recovery instead of deleting a pathname that may have changed.
|
||||
For an existing configuration, setup and uninstall recovery refuse a detected
|
||||
replacement or edit and name the recovery backup. Quit clients before editing their configuration;
|
||||
these checks do not lock out another writer modifying the same file in place,
|
||||
or exclude pathname changes between the final check and publication.
|
||||
create backups, use atomic replacement, and verify their result. Setup and
|
||||
uninstall retain an existing `.rea.backup` rather than replacing the first snapshot.
|
||||
If that snapshot differs from the current configuration, setup previews and
|
||||
preserves a verified `.rea.backup.<sha256>.recovery` copy of the current bytes.
|
||||
Both snapshots remain available; a failed rollback reports the current recovery
|
||||
copy's path and the restore failure.
|
||||
Setup also retains valid environment overrides in REA's existing server entry,
|
||||
such as `REA_MCP_INPUT_SCHEMA_PROFILE`, `REA_MCP_OUTPUT_SCHEMA_PROFILE`, and
|
||||
`REA_MCP_MAX_RESPONSE_BYTES`.
|
||||
@@ -161,8 +147,7 @@ identity remains available at `identity.catalog`.
|
||||
|
||||
Setup pins package-runner MCP registrations to the exact installed REA version,
|
||||
installs the matching skill and on-demand references in the same plan, and adds
|
||||
`startup_timeout_sec = 30` for Codex and Grok Build. Codex also receives a
|
||||
`tool_timeout_sec` derived from known provider startup plus operation headroom.
|
||||
`startup_timeout_sec = 30` for Codex and Grok Build.
|
||||
|
||||
## Limit REA to one project or agent profile
|
||||
|
||||
@@ -193,8 +178,6 @@ as well, so it is broader than this Claude-only migration.
|
||||
history under `CLAUDE_CONFIG_DIR`. Setup follows the same
|
||||
variable: it writes the registration to `$CLAUDE_CONFIG_DIR/.claude.json` and
|
||||
the skill to `$CLAUDE_CONFIG_DIR/skills`.
|
||||
For REA setup, an empty `CLAUDE_CONFIG_DIR` is treated as unset: registration
|
||||
goes to `~/.claude.json` and the skill goes to `~/.claude/skills`.
|
||||
|
||||
```bash
|
||||
CLAUDE_CONFIG_DIR=~/.claude-rea npx rea-agents setup --client claude_code
|
||||
@@ -276,14 +259,14 @@ Register with the variable unset:
|
||||
<!-- x-release-please-start-version -->
|
||||
|
||||
```bash
|
||||
claude mcp add --scope local rea -- npx -y rea-agents@6.7.0 mcp
|
||||
claude mcp add --scope local rea -- npx -y rea-agents@6.5.0 mcp
|
||||
```
|
||||
|
||||
On native Windows, use the same project directory and wrap the package-runner
|
||||
shim so the stdio client can launch it:
|
||||
|
||||
```powershell
|
||||
claude mcp add --scope local rea -- cmd.exe /d /c npx -y rea-agents@6.7.0 mcp
|
||||
claude mcp add --scope local rea -- cmd.exe /d /c npx -y rea-agents@6.5.0 mcp
|
||||
```
|
||||
|
||||
<!-- x-release-please-end -->
|
||||
@@ -414,9 +397,8 @@ running server or its registration.
|
||||
The npm release checked on **2026-10-11** was **6.4.0**, published from
|
||||
[`a56f7bb6`](https://github.com/morluto/rea/commit/a56f7bb668ab23fec8d33f7af353ac7ed2fe1895).
|
||||
The actual registry package accepted dry-run setup plans for the 17 client IDs
|
||||
in that release, including Qwen Code, Pi and Hermes. Seven client IDs are
|
||||
included from 6.5.0 and were absent from the checked npm 6.4.0 package: `droid`,
|
||||
`dsh`, `kimi`, `qoder`, `trae`, `workbuddy` and `zcode`.
|
||||
in that release, including Qwen Code, Pi and Hermes. DeepSeek Harness (`dsh`)
|
||||
is included from 6.5.0 and was absent from the checked npm 6.4.0 package.
|
||||
The 6.4.0 registry check does not establish 6.5.0 publication or live DeepSeek
|
||||
API integration.
|
||||
OpenCode's plan selected
|
||||
@@ -499,8 +481,8 @@ hosted connector; see [its configuration](client-configuration.md#other-client-s
|
||||
| ZCode | `zcode` |
|
||||
| DeepSeek Harness | `dsh` |
|
||||
|
||||
`droid`, `dsh`, `kimi`, `qoder`, `trae`, `workbuddy`, and `zcode` require
|
||||
`rea-agents@6.5.0` or later. The 6.4.0 registry check above does not cover them.
|
||||
`dsh`, `kimi`, and `workbuddy` require a release containing them. The registry
|
||||
check above does not cover them.
|
||||
|
||||
See [client configuration and troubleshooting](client-configuration.md) for
|
||||
configuration paths, profiles, trust policies, and schema-limit workarounds.
|
||||
@@ -558,37 +540,6 @@ search permissions (`0700`) on a directory you own before retrying.
|
||||
|
||||
On supported Linux distributions, approved setup verifies Hopper's official
|
||||
`.deb`, `.rpm`, or Arch package before invoking the native package manager.
|
||||
The official release feed selects the current public demo without a version
|
||||
pin. REA verifies the package's detached PGP signature against Hopper's stable
|
||||
primary fingerprint `7C2D73BAFAF5B9A710A69DA1A26DF815099B1BCD`, then checks
|
||||
that the signed package and installed launcher agree with `main_exe_hash`.
|
||||
Rotating signing subkeys remain bound to that primary identity.
|
||||
The feed row itself is not PGP-signed; doctor labels its display version as
|
||||
`reported_release_version`, separately from the authenticated launcher identity.
|
||||
|
||||
The approval plan includes the caller-selected cache location. Approved setup
|
||||
retains the signed archive, public key and release metadata under
|
||||
`${XDG_CACHE_HOME:-$HOME/.cache}/rea/hopper-releases/<launcher-sha256>`.
|
||||
An empty `XDG_CACHE_HOME` uses `$HOME/.cache`. Approved setup can repair a
|
||||
damaged caller-owned entry after authenticating a fresh package; the previous
|
||||
entry is preserved beside it as `<launcher-sha256>.backup-<id>`. Ordinary doctor
|
||||
and launches reject damaged evidence and never repair it implicitly.
|
||||
Approved publications of the same canonical cache entry share a process-backed
|
||||
lease. Concurrent setup waits without moving another writer's evidence; a
|
||||
failed replacement restores the previous directory when possible and reports
|
||||
any retained backup path. Unavailable reads or native inspection tools do not
|
||||
authorize replacing existing evidence.
|
||||
Doctor and launches authenticate this evidence for offline use; an editable
|
||||
digest receipt alone cannot authorize a launcher. Verification reuses at most
|
||||
eight immutable package proofs per process, keyed by the complete package,
|
||||
key, signature, package format and expected launcher digest. Cached file reads
|
||||
still check identity and content. Without retained evidence, inspecting an
|
||||
existing install requires the matching current official package and network
|
||||
access. Successful live inspection can be reused within that process after
|
||||
rehashing the launcher; it does not write a persistent cache or claim that a
|
||||
previously observed release is still the latest. Older uncached builds require
|
||||
an approved update while the feed exposes only its current release.
|
||||
|
||||
REA runs the supported demo build on a private Xvfb display and selects Hopper's
|
||||
offered demo mode for each analysis session; it does not require the user's
|
||||
desktop display. Unattended package-manager access requires
|
||||
@@ -651,11 +602,6 @@ bridge readiness. For large targets, set `REA_HOPPER_STARTUP_TIMEOUT_MS` to a
|
||||
decimal integer from 1 to 2,147,483,647 milliseconds in the environment that
|
||||
starts REA. CLI and MCP use the same setting; invalid values fail configuration
|
||||
validation. An MCP client's own request timeout must also allow enough time.
|
||||
`open_binary` validates and selects a target without waiting for native provider
|
||||
readiness. During Hopper startup, `binary_session.provider_operation_health`
|
||||
reports `busy` at stage `launch`; `analysis_activity` describes bridge requests
|
||||
and can remain idle until the socket is ready. Cleanup work reports `busy` at
|
||||
stage `connection`.
|
||||
|
||||
If macOS denies Apple Events, allow the application that starts REA under
|
||||
**System Settings → Privacy & Security → Automation**, then retry. REA releases
|
||||
@@ -665,12 +611,9 @@ Arguments containing quotes, backslashes, or line breaks remain unchanged but
|
||||
cannot establish that a failed handoff opened no document. Other failed handoffs
|
||||
retain ownership until document closure is confirmed. If a timed-out bridge
|
||||
becomes ready later, `close_binary` connects to that run, authenticates its
|
||||
identity, and requests document shutdown. Once its listener is ready, the bridge
|
||||
allows 30 seconds for the first connection and capability validation. After a
|
||||
connection drops, it allows the same grace period for an authenticated cleanup
|
||||
reconnect, then releases Hopper's Python execution thread. Initial analysis is
|
||||
outside this listener grace period, and authenticated native work is not bounded
|
||||
by it. Expiry does not establish document closure, so REA
|
||||
identity, and requests document shutdown. After a connection drops, the bridge
|
||||
allows 30 seconds for an authenticated cleanup reconnect, then releases Hopper's
|
||||
Python execution thread. Expiry does not establish document closure, so REA
|
||||
retains unconfirmed ownership. Retry close while the bridge remains available.
|
||||
|
||||
If a Linux launcher exists but cannot start, inspect its shared libraries:
|
||||
@@ -691,20 +634,6 @@ If startup reports `Cannot launch Hopper! Connection is invalid.` or waits for
|
||||
bridge readiness, check Hopper for a pending demo, license, or loader dialog.
|
||||
Complete the dialog and retry. If REA reports `cleanup_incomplete`, follow the
|
||||
retained-resource guidance below before reopening the target.
|
||||
|
||||
On macOS, Hopper can show an `Executing Python Script...` overlay while the REA
|
||||
bridge serves an active MCP connection. Long-lived MCP clients can keep that
|
||||
connection open across agent turns, so the overlay may remain visible after the
|
||||
analysis calls finish; by itself, it does not establish a stalled startup. REA
|
||||
does not automatically idle-close a still-connected target. When the
|
||||
investigation is finished, export an Evidence bundle first if you need to keep
|
||||
the session ledger, then call `close_binary`; set `snapshot_path` to save a
|
||||
provider-neutral analysis snapshot as part of closing. A successful close
|
||||
shuts down the REA bridge and clears its overlay; REA does not control the
|
||||
macOS Hopper application lifetime.
|
||||
The Hopper GUI Cancel button's behavior for this bridge has not been verified;
|
||||
`close_binary` is the supported cleanup path.
|
||||
|
||||
Hopper serializes analysis requests. Cancelling a wait can leave provider work
|
||||
running, which the session reports. Successful decompilation is cached until
|
||||
a relevant rename or comment changes it.
|
||||
@@ -760,17 +689,9 @@ 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 available. The same authentication and process-identity capture apply
|
||||
when the first successful handshake occurs during cleanup after a startup
|
||||
timeout. REA can confirm closure if that exact authenticated process exits,
|
||||
including while a shutdown request is in flight. A helper exit alone is
|
||||
insufficient, and an application that never authenticated has no verified
|
||||
process identity. If no matching bridge becomes available, inspect and close
|
||||
the reported document in Hopper before ending the owning REA connection.
|
||||
Export the Evidence bundle before `close_binary` clears session records.
|
||||
`binary_session.cleanup_pending` remains true while provider cleanup is retained,
|
||||
and provider health remains visible even with `open: false`; that flag alone
|
||||
does not establish successful cleanup.
|
||||
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
|
||||
|
||||
@@ -829,7 +750,7 @@ and `set_addresses_names` name a function entry or any other mapped address
|
||||
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, x86-64, ARMNT (Thumb-2) and ARM64 PE applications and DLLs, plus explicitly
|
||||
Windows P0 admits native x86 and x86-64 PE applications and DLLs, plus explicitly
|
||||
selected [raw NMOS 6502 images](raw-binary.md#nmos-6502) with a caller-supplied
|
||||
entry at file offset 0, on fixed local NTFS volumes. Other raw CPU families remain
|
||||
unsupported on Windows.
|
||||
@@ -847,16 +768,6 @@ rea doctor --json
|
||||
rea setup
|
||||
```
|
||||
|
||||
On macOS, [Homebrew OpenJDK is keg-only](https://formulae.brew.sh/formula/openjdk)
|
||||
and may be unavailable to the system `java` wrapper. Set `JAVA_HOME` to the
|
||||
selected formula's `libexec/openjdk.jdk/Contents/Home`, for example
|
||||
`/opt/homebrew/opt/openjdk/libexec/openjdk.jdk/Contents/Home` or
|
||||
`/usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home`. Use a JDK inside the
|
||||
Java version bounds declared by your Ghidra installation; REA does not select
|
||||
another installed JDK automatically. Doctor distinguishes an absent Java
|
||||
command from a command that runs and fails, and retains bounded probe output
|
||||
and any parsed properties when the selected runtime cannot be admitted.
|
||||
|
||||
On Windows, configure the existing installation in PowerShell:
|
||||
|
||||
```powershell
|
||||
@@ -894,34 +805,6 @@ MCP clients do not depend on an incidental shell path. Setup shows every exact
|
||||
environment entry in its plan, writes only after approval, and never downloads,
|
||||
installs, upgrades, or modifies Ghidra or Java.
|
||||
|
||||
Installation inspection derives the private configuration directory identity from
|
||||
`application.version` and `application.release.name` in
|
||||
`Ghidra/application.properties`. The directory's version spelling follows Ghidra
|
||||
(for example, `12.1.0` becomes
|
||||
`12.1`), while the reported provider version preserves the original value.
|
||||
The launcher uses that inspected coordinate; it does not reread the properties
|
||||
or guess from the extracted folder's name.
|
||||
If the identity is missing, malformed, or unsafe as a single path component,
|
||||
the launcher fails before preparing its home/cache/config/temp directories or
|
||||
starting Java. The client may already have allocated private runtime/endpoint
|
||||
resources and a target snapshot; existing startup-failure cleanup still applies.
|
||||
Restore the selected release's properties instead of renaming its installation folder.
|
||||
Inspection follows selected properties symlinks, admits only a regular file,
|
||||
and caps the metadata payload at 1 MiB under REA's resource budget. A final
|
||||
one-byte probe checks for growth. This is not a Java
|
||||
Properties format limit. Reads preserve Ghidra's Latin-1 byte mapping and check
|
||||
the descriptor and selected name for changes. Permission failures and resource
|
||||
refusals remain explicit; failed descriptor cleanup must succeed before that
|
||||
owner admits another inspection.
|
||||
Native decompiler compatibility inspection follows the selected executable symlink
|
||||
and reads at most the first 4096 bytes through the same descriptor owner. It
|
||||
checks the full extent and selected name for changes without reading the remainder.
|
||||
An unreadable or unrecognized header leaves compatibility unknown; diagnostics
|
||||
retain read failures. Cancellation and incomplete cleanup propagate as failures,
|
||||
and failed cleanup retains the exact descriptor for retry.
|
||||
This coordinate selects only REA's session-private configuration directory, not
|
||||
the installation or an existing user configuration directory.
|
||||
|
||||
Each verified session uses an ephemeral temporary project and isolated
|
||||
home/cache/config/temp paths. REA passes `-readOnly`, `-deleteProject`, uses
|
||||
Ghidra's default analysis settings, and loads its packaged Java
|
||||
@@ -937,10 +820,6 @@ ownership inspection, so retaining those wrappers would prevent verified
|
||||
process-group cancellation during startup.
|
||||
If ownership remains unverifiable, it reports the reason and retains the process
|
||||
supervisor and private runtime instead of removing files beneath a live provider.
|
||||
Startup preserves an observed launch failure when cancellation arrives during
|
||||
rollback. Producer cancellation retains the caller's exact reason separately
|
||||
from LaunchSupport warnings and cleanup failures. Failed rollback keeps the
|
||||
original process owner for a later cleanup retry.
|
||||
The experimental Windows transport uses authenticated IPv4 loopback with a
|
||||
private native-owned bearer descriptor and Job Object process ownership.
|
||||
|
||||
@@ -952,9 +831,6 @@ 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 setting uses the default;
|
||||
empty, invalid or out-of-range supplied values fail configuration validation.
|
||||
When the deadline elapses, the `provider_timeout` error names
|
||||
`REA_GHIDRA_STARTUP_TIMEOUT_MS` with the deadline that was applied and suggests
|
||||
`REA_GHIDRA_DISABLED_ANALYZERS` for analyzers that dominate the time.
|
||||
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
|
||||
@@ -1036,8 +912,6 @@ export REA_GHIDRA_COMPILER_SPEC_ID="borlandcpp" # optional; requires a languag
|
||||
|
||||
REA passes `-processor`/`-cspec`, checks both against the installation's `.ldefs`, and records them in the analysis profile. DOS imports reject an override.
|
||||
|
||||
Language definitions must be well-formed XML encoded as UTF-8 or BOM-marked UTF-16, with any encoding declaration matching the bytes. Literal Unicode replacement characters (U+FFFD) are accepted; malformed source bytes are rejected.
|
||||
|
||||
To seed code that auto-analysis cannot reach (computed jumps, pointers in data):
|
||||
|
||||
```bash
|
||||
@@ -1137,10 +1011,6 @@ compiler remains distinguishable from a compiler that exited with an error.
|
||||
The helper compile deadline defaults to 120,000 ms; set
|
||||
`REA_SWIFTC_COMPILE_TIMEOUT_MS` to an integer between 1 and 2,147,483,647 when
|
||||
a busy host needs longer.
|
||||
On macOS, the Java prerequisite probe waits for this independently bounded
|
||||
preparation before starting its five-second command deadline. Caller cancellation
|
||||
still interrupts preparation, and failed helper cleanup remains owned for retry.
|
||||
Linux process-table preparation remains inside the command deadline.
|
||||
Other rejection values retain their primitive value or an explicit type.
|
||||
Shutdown warnings include the failure
|
||||
kind, message, and diagnostics, while process and temporary-project cleanup
|
||||
@@ -1187,7 +1057,7 @@ For a client that requires manual configuration, use:
|
||||
"mcpServers": {
|
||||
"rea": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "rea-agents@6.7.0", "mcp"]
|
||||
"args": ["-y", "rea-agents@6.5.0", "mcp"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1252,21 +1122,6 @@ on the shell `PATH`. Use the setup command above for the guided setup
|
||||
journey, `npx -y rea-agents@latest` for unattended one-off commands, or install globally
|
||||
with `npm install --global rea-agents` for a shell-visible `rea` command.
|
||||
|
||||
For many concurrent agent sessions, run setup directly from a global installation
|
||||
to avoid keeping a separate npm launcher process for each MCP connection:
|
||||
|
||||
```bash
|
||||
npm install --global rea-agents
|
||||
rea setup
|
||||
```
|
||||
|
||||
Review the plan, approve the selected client changes, then restart those clients.
|
||||
This registers the installed entrypoint directly; installing the global package
|
||||
alone does not replace existing `npx` registrations. Each client still has its own
|
||||
REA process and analysis state. Direct registrations follow the installed CLI;
|
||||
use `rea update` to update it. Running setup through `npx` again selects the pinned
|
||||
package-runner command. Do not register paths inside npm's temporary package cache.
|
||||
|
||||
The optional curl wrapper installs only the global npm package:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -68,17 +68,6 @@ The node vocabulary covers:
|
||||
- runtime script instance;
|
||||
- an explicit `unknown` kind when classification is not justified.
|
||||
|
||||
Static network endpoints can have `resolution: "partial"` when the analyzer
|
||||
recognizes a request call but cannot resolve its target to one exact value.
|
||||
The observation's `value` then preserves the source expression, and its
|
||||
evidence points to the call site. Partial and exact endpoints have distinct
|
||||
identities even when their displayed values match. Partial identities also retain
|
||||
the source site: matching expression text at different sites does not establish
|
||||
the same runtime target. This records observed source syntax; it does not
|
||||
establish that the call ran or contacted that endpoint.
|
||||
Graph coverage describes the analyzed artifact scope and resource limits, not
|
||||
runtime execution. A partial target alone does not imply omitted source.
|
||||
|
||||
The directed relation vocabulary is `contains`, `loads`, `imports`, `maps_to`,
|
||||
`exposes`, `sends`, `invokes`, `handles`, `calls`, `persists_to`, `observed_as`,
|
||||
and `changed_from`. Provider names are deliberately absent from both
|
||||
|
||||
@@ -6,7 +6,7 @@ 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, typed module references, or one module from already completed application
|
||||
summary, module page, or one module from already completed application
|
||||
Evidence; it does not walk relationships.
|
||||
|
||||
`inspect_analysis_view` also projects retained `inspect_binary_layout`
|
||||
@@ -40,105 +40,6 @@ 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.
|
||||
|
||||
## Retained module facts
|
||||
|
||||
For canonical identities and retained source-range counts, query the existing
|
||||
`inspect_analysis_view` tool with a typed module-reference projection:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": {
|
||||
"kind": "retained-evidence",
|
||||
"evidence_id": "ev_ACTUAL_PARENT_ID"
|
||||
},
|
||||
"view": {
|
||||
"kind": "javascript",
|
||||
"collection": "modules",
|
||||
"projection": "references",
|
||||
"where": { "path": "main.js", "kind": "javascript-module" },
|
||||
"offset": 0,
|
||||
"limit": 16
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace the parent ID with the actual analysis summary's `parent_evidence_id`.
|
||||
Filters match exact retained paths and kinds. Omission includes all values;
|
||||
`path: null` selects an unavailable path and `path: ""` selects a recorded empty
|
||||
path. Multiple identities can share a path. The default offset is 0 and limit
|
||||
is 64; follow `coverage.next_offset` for later matching rows in retained order.
|
||||
|
||||
Each row contains its `node_id`, kind, path, canonical identity, retained
|
||||
source-range observation count, and distinct supporting authority/state/confidence
|
||||
combinations in `basis`. These counts do not prove unique reference sites or
|
||||
runtime loading. Use the existing module item view with the row's `node_id` for
|
||||
exact source ranges and complete observations. The result retains parent/query
|
||||
Evidence identity, artifact identity, limitations and unknowns. `source_coverage`
|
||||
keeps selected/unselected sources, graph coverage and unknown counts separate
|
||||
from page exhaustion; an exhausted or empty page cannot prove absence from an
|
||||
incompletely analyzed application. CLI `inspect-analysis-view` reads the same
|
||||
request from a JSON file; portable input uses `source.kind: "inline"` with the
|
||||
complete parent Evidence.
|
||||
|
||||
## Retained file and native facts
|
||||
|
||||
Read metadata, native inventory and unavailable processing scopes directly from
|
||||
retained application observations:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": {
|
||||
"kind": "retained-evidence",
|
||||
"evidence_id": "ev_ACTUAL_PARENT_ID"
|
||||
},
|
||||
"view": {
|
||||
"kind": "javascript-facts",
|
||||
"where": { "paths": ["package.json", "build/Release/addon.node"] },
|
||||
"property_keys": [
|
||||
"name",
|
||||
"version",
|
||||
"bytes",
|
||||
"availability",
|
||||
"operation",
|
||||
"analysis_status"
|
||||
],
|
||||
"offset": 0,
|
||||
"limit": 32
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Each row preserves its node identity, observation ID, source-map reference and
|
||||
original Evidence, including location, authority, confidence, coverage and
|
||||
limitations. `property_keys` selects exact retained property names; absent keys
|
||||
stay omitted and retained null values stay null. An empty list requests only
|
||||
identity/provenance. Observations are not merged into a single asserted fact.
|
||||
When property names are unknown, opt into
|
||||
`include_available_property_keys: true`. Each returned row then lists its
|
||||
original `available_property_keys`, without unselected values; combine this with
|
||||
`property_keys: []` for discovery only. The default is false, so known-field
|
||||
reads do not pay for field inventories. Keep node/observation IDs paired when
|
||||
combining rows; location-related observations need not belong to the same node.
|
||||
|
||||
`where.paths` compares exact Evidence `artifact-path` values or `source-range`
|
||||
sources. Empty query strings remain valid selectors, though current location
|
||||
contracts require nonempty paths/sources. It does not inspect display labels or a
|
||||
property named `path`, normalize URLs, or reopen files. Omission includes unknown
|
||||
locations; an empty list matches none. Optional `where.kinds` filters original
|
||||
node kinds, with an empty list likewise matching none. Multiple locations of
|
||||
shared content remain separate rows with the same canonical node identity.
|
||||
|
||||
These rows select application-graph observations. Semantic relationships and
|
||||
semantic unknown records remain in complete parent Evidence and trace tools.
|
||||
|
||||
Rows follow retained node/observation order. The default offset/limit is 0/64;
|
||||
follow `coverage.next_offset`. Page totals count matching retained observations,
|
||||
while `source_coverage` preserves caller selection and application/semantic
|
||||
partial or unknown states. An empty or exhausted page does not establish absence
|
||||
outside examined coverage. Complete source Evidence remains available through
|
||||
export. CLI `inspect-analysis-view` and portable Evidence use the same contract
|
||||
and application implementation as MCP.
|
||||
|
||||
## Feature tracing
|
||||
|
||||
Select one literal seed kind: node ID, route, string, API, IPC channel, module,
|
||||
@@ -154,14 +55,6 @@ matches exactly. Otherwise the result recommends provider-neutral follow-up
|
||||
tools and reports `requires-provider-analysis`; it never starts or switches a
|
||||
provider implicitly.
|
||||
|
||||
A handoff requires the add-on's exact content identity. Unavailable unpacked
|
||||
companions remain visible in the trace graph with their canonical path,
|
||||
availability and container-backed Evidence. They yield no actionable handoff
|
||||
until their bytes are available and the application is reanalyzed; the archive
|
||||
digest does not identify the missing add-on. An empty handoff list does not prove
|
||||
that the trace contains no native components. Source partial coverage remains
|
||||
visible independently of handoff eligibility.
|
||||
|
||||
## Semantic relation tracing
|
||||
|
||||
`trace_javascript_semantics` queries the authenticated companion graph without
|
||||
@@ -184,17 +77,6 @@ registrations/removals and dispatch, Node timers and cancellation handles, async
|
||||
defaults, request construction and response consumers, parse/coercion/
|
||||
validation boundaries, and built-in resource acquisition/release.
|
||||
|
||||
Local callback candidates do not establish a complete target set when a
|
||||
conditional write may leave a parameter, catch binding, or uninitialized
|
||||
variable unchanged. These calls retain candidate edges and dynamic uncertainty;
|
||||
default traces remain ambiguous with partial coverage. Opt into
|
||||
`include_ambiguous_dynamic_edges` to traverse the candidates. Proven preceding
|
||||
unconditional assignments, including writes dominating a read in the same
|
||||
conditional block, can resolve a target; later writes do not replace an
|
||||
earlier read or captured alias. Unproved ordering across branches or function
|
||||
activations remains conservative. Returned-reference effects use the same
|
||||
read-position facts as call resolution.
|
||||
|
||||
Mutation tracking covers explicit member assignments, updates, deletion, and
|
||||
loop assignment targets, including the supported local aliases and shared
|
||||
nested references. Calls conservatively invalidate exposed mutable references;
|
||||
@@ -244,13 +126,8 @@ 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 observations keep their value in `properties.value`. When
|
||||
`properties.resolution` is `partial`, that value is the unresolved source
|
||||
expression, with an identity distinct from an exact endpoint of the same text.
|
||||
Semantic request and response nodes keep their endpoint in `properties.endpoint`. Endpoint
|
||||
lookup identities are preserved independently of the primitive-value lattice's
|
||||
byte budget. An oversized normalized literal can become unknown while the same
|
||||
string remains an exact endpoint for tracing and comparison. Endpoint
|
||||
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
|
||||
@@ -288,27 +165,6 @@ and the result includes its basis, candidates, changed dimensions, Evidence
|
||||
links, limitations, and a `changed_from` graph containing all compared nodes,
|
||||
their observations, and relationships.
|
||||
|
||||
A matched pair whose only differing dimension is `location` counts as
|
||||
`unchanged` when both input graphs have complete coverage and its neighboring
|
||||
relationship identities are resolved. This includes an
|
||||
identical module shifted by an earlier bundle edit and a named IPC channel
|
||||
observed at a new offset. The item still reports `dimensions: ["location"]`
|
||||
and both node IDs; the graph retains both original observations and coordinates.
|
||||
Content, property, and complete relationship differences still count as
|
||||
`changed`. With incomplete coverage, relocation alone remains `unknown` and
|
||||
retains the location and coverage dimensions. Matching confidence is unchanged:
|
||||
an inferred pair is not promoted to exact identity by this classification.
|
||||
|
||||
Complete inventory does not resolve ambiguous or unmatched relationship targets.
|
||||
A matched module with identical bytes can therefore remain `unknown` when a
|
||||
neighbor, including its containing chunk, has no cross-version match. The item
|
||||
retains its exact content match, coordinates, candidate inventory, and an explicit
|
||||
relationship-identity limitation. `coverage` is added to its dimensions only for
|
||||
incomplete inventory. Definite content, property, or complete topology differences
|
||||
remain `changed` while retaining any separate relationship uncertainty.
|
||||
An unknown item with no observed content, property, or relationship difference
|
||||
does not emit a `changed_from` edge; its pairing and uncertainty remain in the item.
|
||||
|
||||
One-sided absence is `added` or `removed` only when the opposite input graph has
|
||||
complete coverage. With partial, unavailable, or truncated input, the same
|
||||
condition is `unknown`. The comparison retains every classified item and
|
||||
@@ -352,13 +208,6 @@ 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.
|
||||
Rebound values are evaluated at their read position: saving an incoming parameter
|
||||
before a later assignment preserves caller-dependent uncertainty, while a proven
|
||||
preceding assignment can supply a constant. Unresolved ordering remains unknown.
|
||||
Supported reads within object and array literals follow left-to-right evaluation;
|
||||
an unproved relative order remains unknown. A later write in a separate conditional
|
||||
block can still leave an earlier capture unknown because ordering across those
|
||||
blocks is not proven.
|
||||
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
|
||||
|
||||
@@ -182,18 +182,6 @@ partial Evidence. Cancellation after source analysis begins can also retain
|
||||
completed facts, including when interrupted during cleanup, graph construction,
|
||||
or Evidence sealing. Unexamined relationships remain unknown.
|
||||
|
||||
Per-file gaps identify the applicable processing phase: JavaScript source analysis
|
||||
uses AST authority, while package/JSON, HTML-reference and source-map processing
|
||||
use artifact-byte authority. File-analysis interruption gaps carry `analysis_status`:
|
||||
`interrupted` means the phase was entered (including source-worker startup),
|
||||
and `not-started` means interruption prevented that phase from beginning.
|
||||
Neither state establishes that parsing completed. Remaining parsers are not run
|
||||
after interruption just to populate a result.
|
||||
|
||||
Native add-ons remain metadata-only and acquire no JavaScript parse or analysis
|
||||
gap. This also applies when their paths are outside `source_paths`; their inventory
|
||||
and caller selection remain available without implying applicable AST work.
|
||||
|
||||
MCP returns a `partial_observation` retained reference after recording succeeds;
|
||||
open it with `inspect_analysis_view` on the same connection. If the SDK stopped
|
||||
waiting before receiving the reply, follow [MCP cancellation recovery](mcp-contracts.md#progress-and-cancellation)
|
||||
@@ -218,9 +206,6 @@ code unit, matching the original bytes identified by the artifact digest.
|
||||
|
||||
Plain `.ts` artifact sources use TypeScript syntax without JSX, including
|
||||
angle-bracket type assertions. `.tsx` and `.jsx` retain JSX parsing.
|
||||
JavaScript sources use JavaScript grammar with JSX, never TypeScript syntax,
|
||||
so valid JavaScript that TypeScript reads differently keeps its JavaScript
|
||||
meaning.
|
||||
|
||||
Relative TypeScript imports can name their emitted `.js`, `.mjs`, or `.cjs`
|
||||
counterparts while resolving to inventoried source files. This substitution
|
||||
@@ -235,10 +220,7 @@ Selected bounded text is then parsed as inert data to recover:
|
||||
- Webpack and Rspack chunk registrations and module factories represented as
|
||||
AST literals;
|
||||
- static imports, dynamic imports, CommonJS `require` calls, workers, and
|
||||
service workers (only `new Worker(new URL(path, import.meta.url))` resolves
|
||||
relative to the calling module; string worker and service-worker paths use
|
||||
the document base URL or Node's working directory, which static analysis
|
||||
does not establish, so they keep their expression and stay unresolved);
|
||||
service workers;
|
||||
- route, network endpoint, storage, and vendor-marker observations;
|
||||
- local source-map declarations and original
|
||||
source names and content digests;
|
||||
@@ -288,13 +270,8 @@ RPC client syntax also contributes network endpoint candidates, in both
|
||||
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 standalone Source object's `body`
|
||||
remains an operation candidate even when it has `locationOffset` metadata.
|
||||
A graphql-tag `loc.source.body` copy is suppressed only when that source
|
||||
belongs to a recovered document with the same operation and its containing
|
||||
document, location and source have proven private metadata ownership. Writes,
|
||||
escapes and classic-script global bindings retain the source observation.
|
||||
Anonymous operations are not reported.
|
||||
`OperationDefinition` document object. A graphql-tag `loc.source.body` copy is
|
||||
not reported twice. Anonymous operations are not reported.
|
||||
|
||||
Literal link options and precompiled document fields follow object property
|
||||
order: the final definition owns the key. A later spread, dynamic computed key,
|
||||
@@ -311,25 +288,13 @@ 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-v3` structural fingerprint. It ignores
|
||||
ordinary identifier spellings while retaining literal and directive values,
|
||||
operators, fixed property names, and selected syntax flags such as computed
|
||||
keys, declaration kind, function async/generator state, update-expression
|
||||
prefix, method kind, and class static state. Local names used in computed keys
|
||||
remain rename-resistant; private member names are also ignored while their
|
||||
method kind and static state remain represented.
|
||||
|
||||
This fingerprint is structural evidence for candidate matching, not proof that
|
||||
two modules behave equivalently. Its scope follows the AST facts listed above;
|
||||
unrepresented syntax can still collide. The exact source digest remains
|
||||
available to show byte-level change, and comparison reports content changes even
|
||||
when structural matching succeeds.
|
||||
|
||||
Version comparison includes the algorithm in its structural matching key.
|
||||
Retained `babel-ast-v1` results can still match other v1 results, and v2 results
|
||||
can still match v2 results, but v1/v2 results cannot structurally match v3
|
||||
results. Other matching tiers remain available across algorithm versions.
|
||||
Re-analyze both snapshots to compare using the v3 rules.
|
||||
bounded AST also receives a `babel-ast-v2` structural fingerprint that ignores
|
||||
ordinary identifier names while retaining syntax, literals, operators, object
|
||||
keys, and member properties. Computed member identifiers retain their access
|
||||
syntax without treating a local variable's spelling as a fixed property; template
|
||||
literal contents remain part of the fingerprint. Version comparison keeps the
|
||||
algorithm in its matching key, so retained `babel-ast-v1` fingerprints cannot match
|
||||
these new fingerprints. Re-analyze both snapshots to compare their new structure.
|
||||
If fingerprint construction reaches its structural
|
||||
bound, the fingerprint is unavailable and its status is `truncated`; a bounded
|
||||
prefix is never presented as a complete stable fingerprint.
|
||||
@@ -350,17 +315,6 @@ substitute version-dependent Electron defaults for omitted `webPreferences`.
|
||||
Unresolved option objects, bridge keys, API objects, and IPC channel expressions
|
||||
remain unknown and make coverage partial.
|
||||
|
||||
BrowserWindow options and `webPreferences` can follow local `const` aliases
|
||||
whose initialization precedes the use. The shared lexical and mutation index
|
||||
checks the selected `webPreferences` path, so an unrelated `options.icon` write
|
||||
does not discard these facts. Reassignment, relevant writes, prior escapes,
|
||||
ambiguous initialization, and unresolved spreads remain unknown. The binding
|
||||
association is an inference: the window observation retains the constructor
|
||||
location and `resolution_sources` identifies the original object literals in
|
||||
the same artifact. Inline option syntax keeps its observed Evidence. This
|
||||
does not execute code or establish runtime configuration; popup overrides from
|
||||
`setWindowOpenHandler` are not covered by this constant-options resolution.
|
||||
|
||||
Recognized literal module-table bootstraps also support bounded lexical
|
||||
substitution through module exports, import helper bodies, local wrapper calls,
|
||||
returned closures, object spreads, and callback parameters. Recovered Electron
|
||||
@@ -374,29 +328,6 @@ conditions retain both return branches, including fallthrough. Short-circuit
|
||||
selection distinguishes truthiness from nullishness; uncertain `??` paths
|
||||
retain a nullish guard rather than a falsy guard.
|
||||
|
||||
Recognized module factories retain a separate initialization boundary for each
|
||||
reachable return and for fallthrough. A conditional early return does not hide
|
||||
later exports on the continuing path; exports and captured initializers after a
|
||||
definite exit remain unavailable. Fallthrough candidates retain their branch
|
||||
predicates. Exports shared by the complete set of proven exits also retain
|
||||
unconditional facts. Their shared view excludes later overwrites and bounds
|
||||
captured initializers by the earliest completion; branch-dependent facts keep
|
||||
their predicates. Incomplete or additionally guarded exit sets cannot use that
|
||||
proof. Completed factory control flow is reused within that analysis only.
|
||||
Guarded main-process registrations remain candidate paths even with empty
|
||||
callbacks; they do not become unconditional IPC summary facts.
|
||||
Factory guards read export writes at their source position. Destructured and
|
||||
spread snapshots retain their capture position rather than reading later writes.
|
||||
An unproven namespace read boundary remains unknown.
|
||||
Completed factory environments preserve their `exports` and `module.exports`
|
||||
alias identity when a namespace escapes through an export or returned closure.
|
||||
Synchronous helper calls retain the caller's factory activation and read point;
|
||||
lexical captures and executing callers remain separate facts.
|
||||
Async calls retain their truthy Promise identity until an explicit `await`;
|
||||
generator calls produce iterators without evaluating their bodies. Iterator
|
||||
advancement and Promise/iterator members remain explicitly unresolved. Awaited
|
||||
function values retain their source origins and captured initialization bounds.
|
||||
|
||||
These paths appear as contextual `javascript-expression` nodes. An exact `api`
|
||||
seed such as `desktop.copy` can trace an exposed member through a unique IPC
|
||||
pairing to an external API call. `addListener` is normalized to `on`. Semantic
|
||||
@@ -460,13 +391,10 @@ For `.node` bindings, member names mean “requested by JavaScript syntax.” A
|
||||
resolved add-on path does not convert them into verified native exports. Native
|
||||
symbol verification remains a separate deep-analysis claim.
|
||||
|
||||
Exact endpoint values preserve useful local diagnostics, including query values
|
||||
and fragments, while removing URL username/password credentials when the value
|
||||
parses as a URL. When a recognized request target cannot be resolved exactly,
|
||||
the endpoint's partial resolution retains the original source expression with
|
||||
its call-site provenance. This does not establish that the request executed.
|
||||
Artifact paths, digests, parse locations, and analysis metadata remain
|
||||
actionable because REA is local-only.
|
||||
Endpoint observations preserve useful local diagnostics, including query values
|
||||
and fragments, while removing only URL username/password credentials. Artifact
|
||||
paths, digests, parse locations, and analysis metadata remain actionable
|
||||
because REA is local-only.
|
||||
|
||||
## Safety boundary
|
||||
|
||||
@@ -498,18 +426,7 @@ retained candidate strings and temporary canonical-key serialization. This is
|
||||
an in-memory semantic allocation bound independent of CLI or MCP transport
|
||||
budgets. Source literal bytes remain in the parsed source and artifact evidence;
|
||||
when a normalized semantic value exceeds the bound, its value is unknown and
|
||||
coverage is partial. Direct string literals, cooked templates without
|
||||
substitutions, and derived strings all use this normalization boundary. A
|
||||
single exact primitive is validated without allocating deduplication or sort
|
||||
state or serializing a canonical key. Configuration defaults use the same
|
||||
normalizer; limited defaults retain `value_resource_limit` and an anchored
|
||||
resource-limit unknown. Known null, false, zero, and empty-string defaults stay
|
||||
exact. This primitive-value bound does not truncate lookup identities such as
|
||||
source paths, field names or request endpoints. Full endpoint properties remain
|
||||
available for endpoint queries, tracing and comparison. Each analysis records encountered limit classifications independently of
|
||||
later projections: a selected healthy sibling can remain exact while whole-file
|
||||
coverage reports the encountered bound. Projection preserves limiting values
|
||||
from the shared property-slot owner. Expression
|
||||
coverage is partial. Expression
|
||||
evaluation and provenance walks stop after 256 nested levels. Union products
|
||||
and string lengths are checked before allocating combinations or concatenated
|
||||
strings. When a boundary is reached, the value stays unknown, semantic coverage
|
||||
@@ -586,21 +503,6 @@ not bypass worker heap, execution deadline or parent result admission. Truncated
|
||||
coverage reports both effective node ceilings; omitted relationships remain
|
||||
unknown.
|
||||
|
||||
Unknown records have independent defaults of 100000 across the application and
|
||||
20000 per source. Select `max_semantic_unknowns` and
|
||||
`max_semantic_unknowns_per_file` (CLI: `--max-semantic-unknowns` and
|
||||
`--max-semantic-unknowns-per-file`), each from 1 to 1000000. The parent offers the
|
||||
remaining capacity to the worker, and rejects excess records before adoption.
|
||||
Unknown admission happens before canonical identity and provenance construction.
|
||||
When capacity is exhausted, coverage is partial and truncated and names both
|
||||
effective unknown ceilings. `coverage.omitted_unknown_occurrences` counts examined
|
||||
emission occurrences by family and reason, including repeated emissions. It does
|
||||
not claim distinct discarded identities or count frontiers in unexamined source.
|
||||
Omitted unknown provenance and IDs are not retained. Existing source, node,
|
||||
execution and memory limits continue to determine examined coverage. Raising only
|
||||
a node capacity does not raise the unknown capacity. Graphs without unknown
|
||||
omissions omit this optional coverage field, preserving their existing identities.
|
||||
|
||||
While sources remain, the sequential worker reserves one next compact static
|
||||
checkpoint at its 8 MiB bound with the same 6x retention expansion used at
|
||||
admission. Earlier checkpoints are already charged to retained bytes; the
|
||||
@@ -724,10 +626,6 @@ 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.
|
||||
ESM, HTML, and URL references apply URL dot segments to empty path segments:
|
||||
`./assets//../app.js` selects `assets/app.js`, while a remaining empty segment
|
||||
such as `./assets//app.js` stays unavailable. CommonJS keeps filesystem path
|
||||
semantics and selects `app.js` for the same text.
|
||||
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
|
||||
|
||||
@@ -133,11 +133,8 @@ Each operation uses one worker, a 1 GiB address-space ceiling and a 120-second
|
||||
deadline; it accepts up to 64 MiB of total input across all selected files and
|
||||
128 MiB/10000 entries of staged
|
||||
output, with 8 MiB per diagnostic/report stream. Exceeding a limit is an explicit
|
||||
failure with rollback. Selected inputs beyond the total input allowance return a
|
||||
non-retryable `resource_constraint` with `resource: "file-size"` and
|
||||
`reported_limits.maximum_input_bytes`/`remaining_input_bytes`; input that is not
|
||||
valid UTF-8 is an `invalid_format` request issue. These limits apply per
|
||||
operation and do not claim aggregate host containment across concurrent callers.
|
||||
failure with rollback. These limits apply per operation and do not claim aggregate
|
||||
host containment across concurrent callers.
|
||||
|
||||
See [testing.md](testing.md#javascript-source-recovery) for the focused real
|
||||
Wakaru CLI/MCP lane and its source-owned compiler fixtures. Other host platforms
|
||||
|
||||
@@ -95,11 +95,6 @@ pauses or resumes execution, calls `Runtime.runIfWaitingForDebugger`, launches
|
||||
the target, instruments JavaScript, or invokes Electron APIs. Closing a call
|
||||
closes only REA's WebSocket.
|
||||
|
||||
Each WebSocket handshake and command response has its own 20-second deadline,
|
||||
separate from the caller-selected observation window. A stalled handshake or
|
||||
command reports `provider_timeout` and retains observations already received;
|
||||
caller cancellation still reports cancellation.
|
||||
|
||||
The direct observations are:
|
||||
|
||||
- `Debugger.scriptParsed`, establishing that a bounded script location was
|
||||
@@ -109,9 +104,7 @@ The direct observations are:
|
||||
- `Runtime.executionContextCreated`,
|
||||
`Runtime.executionContextDestroyed`, and
|
||||
`Runtime.executionContextsCleared`, establishing context lifecycle within
|
||||
the capture window. A created or destroyed event whose context ID is
|
||||
missing or not a safe integer adds no context record; it is retained only
|
||||
as a count reported in `unknowns`.
|
||||
the capture window.
|
||||
|
||||
The Inspector protocol does not directly expose require/import caller edges,
|
||||
EventEmitter emissions or listener invocation, Electron IPC messages or
|
||||
|
||||
@@ -91,20 +91,17 @@ nodes. REA evaluates compatible static candidates conservatively:
|
||||
|
||||
1. A captured-source SHA-256 plus one matching mapped location yields
|
||||
a content-and-location match.
|
||||
2. When no static candidate exists at a mapped location, one unique exact
|
||||
content digest can match. Whole-asset digests and reconstructed module-factory source
|
||||
2. One unique exact content digest can match even when no location mapping is
|
||||
available. Whole-asset digests and reconstructed module-factory source
|
||||
digests remain distinguishable in the reported basis.
|
||||
3. Without captured bytes, one unique mapped artifact path can produce a
|
||||
medium-confidence location match.
|
||||
4. Multiple candidates remain `ambiguous`; no `observed_as` edge is emitted.
|
||||
With captured source and mapped candidates, only mapped content matches
|
||||
qualify; unrelated content matches elsewhere are excluded.
|
||||
`candidate_static_count` reports the full qualified layer/node count, and
|
||||
`candidate_static_nodes` includes every unique candidate reference.
|
||||
5. If captured bytes disagree with the static candidate at the mapped path,
|
||||
the result is an explicit mismatch. An equal digest elsewhere cannot hide
|
||||
that disagreement. If a mapped candidate's digest is unavailable and no
|
||||
mapped content match is known, the comparison remains `unknown`.
|
||||
the result is an explicit mismatch. A path never overrides a digest
|
||||
disagreement.
|
||||
6. Missing authorization mappings and incomplete or truncated input coverage
|
||||
remain unknown or truncated rather than becoming absence claims.
|
||||
|
||||
|
||||
@@ -22,15 +22,6 @@ inspection and decompilation while refusing `open_jeb_project`. Catalog discover
|
||||
uses one 60-second deadline across connection and pagination; a responsive server
|
||||
cannot keep discovery running indefinitely by returning more pages.
|
||||
|
||||
Each upstream tool call has an absolute 60-second request deadline by default.
|
||||
Set `REA_JEB_MCP_TIMEOUT_MS` to a positive decimal number of milliseconds to
|
||||
select a different per-request budget, for example `REA_JEB_MCP_TIMEOUT_MS=300000`
|
||||
for a five-minute decompilation. This budget starts after discovery and applies
|
||||
to each individual `tools/call`; it does not extend the separate catalog deadline
|
||||
or establish one end-to-end deadline across a whole CLI or MCP operation. A
|
||||
request that reaches its budget returns a typed timeout, while caller
|
||||
cancellation remains a cancellation.
|
||||
|
||||
Verified against JEB 5.48.0 (Linux x64, licensed build) serving `jeb-mcp-server` 1.3.0 over streamable HTTP.
|
||||
|
||||
## Operations
|
||||
@@ -52,7 +43,6 @@ All four are read-only with respect to the target file; only `open_jeb_project`
|
||||
- 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.
|
||||
- Successfully parsed client information is reused for the lifetime of the MCP connection, including when the engine omits its version. Explicit client inspection and availability probes refresh it.
|
||||
- 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.
|
||||
@@ -1,133 +0,0 @@
|
||||
# Kuna provider
|
||||
|
||||
[Kuna](https://github.com/Noelo-Lab/kuna) is an Apache-2.0 decompiler distributed as one `kuna` executable. REA uses a `kuna` you supply. It does not download, install, update or bundle Kuna. REA verified this provider with Kuna 1.833; it accepts other releases and reports them as unverified in `rea doctor` and in each analysis profile.
|
||||
|
||||
Kuna is static: it reads the selected image and never executes it.
|
||||
|
||||
## Configure
|
||||
|
||||
```bash
|
||||
export REA_KUNA_COMMAND=/absolute/path/to/kuna
|
||||
rea doctor --provider kuna
|
||||
```
|
||||
|
||||
Select it explicitly with `--provider kuna`, MCP's `open_binary.provider_id: "kuna"`, or `REA_ANALYSIS_PROVIDER=kuna`. With Kuna and another provider configured for the same target, `auto` reports `ambiguous` instead of choosing one.
|
||||
|
||||
| Setting | Default | Meaning |
|
||||
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `REA_KUNA_COMMAND` | none (required) | Absolute path of the `kuna` executable. |
|
||||
| `REA_KUNA_CACHE_DIR` | `~/Library/Caches/rea/kuna` (macOS), `$XDG_CACHE_HOME/rea/kuna` (Linux; `~/.cache/rea/kuna` when `XDG_CACHE_HOME` is unset or relative) | Absolute directory REA owns for project exports. Kuna's own spec cache also lives here, not in your Kuna cache. |
|
||||
| `REA_KUNA_CACHE_MAX_BYTES` | 4 GiB | Size cap; least recently used exports are evicted above it. |
|
||||
| `REA_KUNA_PROJECT_TIMEOUT_MS` | 30 minutes | Deadline for whole-program inventory/export, reference and string scans. |
|
||||
| `REA_KUNA_TIMEOUT_MS` | 120 s | Deadline for one single-function decompile, and for the inventory run REA makes when the export ends without one. |
|
||||
| `REA_KUNA_JOBS` | 1 | `decompile-project --jobs`. 1 is Kuna's reference answer; more jobs finish sooner but lose callee-first prototypes, and change about 40–60% of function bodies on the measured binaries. |
|
||||
|
||||
A single-function decompile, inventory, string, graph or xref run that exceeds its deadline fails as `provider_timeout`, naming the setting that owns the deadline and that raising it takes a restart. A project export that exceeds `REA_KUNA_PROJECT_TIMEOUT_MS` is an export failure instead: requests that need the export report `capability_unavailable` with the export's own retry guidance.
|
||||
|
||||
Windows is not supported yet. Supported targets are ELF and thin Mach-O executables for x86-64, AArch64 and ARM; PE and universal Mach-O are rejected with a typed reason.
|
||||
|
||||
## What Kuna answers
|
||||
|
||||
| Tool | Source |
|
||||
| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `list_procedures`, `search_procedures`, `procedure_address` | Kuna's callable inventory (`kuna functions --json`), including import slots it does not decompile |
|
||||
| `address_name` | Function entries, then the data labels Kuna's export assigns |
|
||||
| `procedure_pseudo_code`, `batch_decompile` | The project export, or a single-function run while the export builds |
|
||||
| `procedure_assembly` | The project export's labeled listing |
|
||||
| `procedure_callers`, `procedure_callees` | Call-kind edges from a lazy, body-free Kuna graph; synthetic import nodes are accepted by address |
|
||||
| `list_strings`, `search_strings` | Typed string candidates from one cached, reference-free scan; exact-address, literal and ECMAScript regex selection |
|
||||
| `xrefs` | Exact-address incoming reference sites, with forwarding aliases filtered explicitly |
|
||||
| `analyze_function` | Pseudocode and assembly from the export, plus call relationships; typed references, comments, strings and CFG remain unavailable |
|
||||
|
||||
Typed procedure references, basic blocks, raw-memory tools, annotations and type recovery are not available from this provider. Use another provider for those operations.
|
||||
|
||||
## How answers are produced
|
||||
|
||||
The first text or assembly request in a session looks for this target's export in the cache. `list_documents` reads the selected path without initializing analysis. Inventory, function lookup, string queries, call relationships and xrefs do not start a C export. A data-name lookup starts it only when the address is absent from the function inventory. The export is keyed by the target's SHA-256, the Kuna executable's SHA-256, its version and `--jobs`.
|
||||
|
||||
- **Warm cache:** analysis reads reuse the verified export. A fresh server verifies its file digests once, even for concurrent first requests; that cost scales with export size.
|
||||
- **Cold cache:**
|
||||
- REA starts `kuna decompile-project` in the background on a private copy of the target.
|
||||
- Meanwhile, pseudocode comes from one `kuna decompile --addr` run. Name and address lookups, and listings, use the inventory the export takes with `kuna functions --json` before it decompiles. The session runs `kuna functions` itself, under `REA_KUNA_TIMEOUT_MS`, only when no export is building (an inventory-only request does not start one) or the export ends without an inventory.
|
||||
- Requests for the same function share one run; it stops when its last waiting request is cancelled. Each run analyzes the whole image again in its own process, so one REA process runs at most as many at once as the host has cores beyond `REA_KUNA_JOBS` (at least one). Further requests wait in order, and a waiting request is answered from the export if it finishes first. A run whose stop REA cannot prove keeps its slot until `close_binary` proves it stopped.
|
||||
- The session keeps each completed single-function text, up to 16 MiB in all with the least recently used dropped first, and answers repeats from it until the export can. After a failed export that lasts for the session.
|
||||
- Assembly and data names wait for the export; progress notifications report the wait every ten seconds. A session does not rebuild a failed export: requests that need it fail with `retryable: false`, the export's failure, its captured Kuna output and what to change before reopening the target. A setting such as `REA_KUNA_PROJECT_TIMEOUT_MS` or `REA_KUNA_JOBS` is read when REA starts, so changing it also needs a restart. Pseudocode keeps using single-function runs.
|
||||
- A single-function answer says so in its limitations. It lacks the export's whole-program prototypes, so a later request can return different text for the same function.
|
||||
|
||||
Pseudocode, assembly, `analyze_function` and data-name answers record where their text came from in `raw_result.source`: `single-function`, or `project-export` with the cache directory. `procedure_pseudo_code` and `procedure_assembly` answers from the export also name the file, byte span and the file's SHA-256. Combined `analyze_function` answers retain both facet records in `raw_result.source.files`, each with its file, digest and byte span. Both texts come from one export; losing that project retries the complete report. Listings and procedure lookups carry no `raw_result`. Agents can open or search the export's `.c` and `.asm` there directly when that is cheaper than calling a tool per function. Text read that way is target-derived, like any decompiler output, but it bypasses the untrusted-content marker that REA's tool results carry.
|
||||
|
||||
The background export belongs to the session. `close_binary`, or the end of a CLI command, cancels it unless another session still waits for it. A one-shot CLI decompile therefore answers from a single-function run; any request that needs the export, such as `procedure_assembly` or `analyze_function`, keeps it.
|
||||
|
||||
The assembly label index is scanned once per export reader. Cancelling a request stops its wait without interrupting other readers; closing the session aborts and drains the shared scan before releasing its files.
|
||||
|
||||
Regex procedure and string search uses ECMAScript Unicode matching in a cancellable worker with a five-second matching deadline. Literal matching remains the default. Cancellation or a matching deadline leaves the session available.
|
||||
|
||||
Single-function subprocess output and each cached source facet share a 16 MiB buffered-text capacity. Cached spans are checked before allocation; larger text remains in the local export and the error identifies the file and range. `analyze_function` initially returns the complete dossier, which can still be large; later retained views do not remove that first transfer. Prefer the individual text tools for a focused question.
|
||||
|
||||
## Strings
|
||||
|
||||
`list_strings` and `search_strings` share one lazy `kuna strings --json --encoding all --min-length 5 --termination any --no-xrefs` scan of the digest-checked private input. Skipping references avoids program lifting, a call graph and a C export. REA validates the input, scan policy, every row and the total before caching any facts. Encoding, character count, byte length and terminator facts must agree; supplementary UTF-8 characters count as Unicode scalars. Malformed output is an error, not an empty search. REA parses the JSON as Kuna writes it instead of buffering it, so the scan has no fixed size: Kuna writes about 290 bytes per row, 31 MB for a 20 MB Ghostty binary and 179 MB (611k rows) for an arm64 Firefox `XUL`. Rows are validated one at a time, and the first contradiction stops Kuna. Text REA does not keep is dropped unassembled; kept text and retained rows are admitted against the REA process's live heap headroom as they arrive; a refusal is a `memory` resource constraint with `retryable: false`, and closing other targets or starting REA with a larger Node.js heap makes room. String scans use the whole-program `REA_KUNA_PROJECT_TIMEOUT_MS` deadline; `REA_KUNA_TIMEOUT_MS` applies to single-function decompilation. The parsed inventory belongs to one selected target/executable profile and expires on session close; Kuna diagnostics beyond their 8 MiB buffer are retained as a failure until close, while other failures are not cached.
|
||||
|
||||
Results keep exact u64 virtual addresses, decoded text, native encoding, terminator status and byte length including any terminator. Kuna scans mapped sections or segments for runs of at least five characters; unterminated fragments can include instruction bytes. `all` includes ASCII, UTF-8 and the engine's Latin-range UTF-16LE reading. Other text, including short strings, non-Latin wide text and UTF-16BE, can remain undiscovered. An empty result does not prove absence.
|
||||
|
||||
Use `search_strings` for the matching rows or `list_strings` with an exact address for that location. The validated inventory is sorted by numeric address and encoding. Once cached, exact-address reads use binary search and return every encoding at that address without scanning the full inventory or retaining another lookup index. Literal and regex matching run in REA, preserving the existing case and ECMAScript Unicode semantics instead of substituting Kuna's different regex dialect. Procedure and string regex queries share one worker slot per session. Input projections are materialized only after admission, so queued queries retain no per-query inventory arrays. Close cancels and drains matching. Native metadata queries also share one admission slot, including references; a failed stop retains admission until cleanup is proven.
|
||||
|
||||
`raw_result.strings` reports the source JSON digest/size, scanned scope, extraction policy, complete inventory count and selected count without copying unrequested text into the answer. Omit the address from `list_strings` to retrieve the complete inventory as Evidence; normal session retention and bundle export apply, including transport-capacity errors for oversized inline replies. These operations preserve their complete-result contracts and do not add paging. Function-referenced string facets in `analyze_function` remain unavailable; call `xrefs` explicitly when references to one returned string are needed.
|
||||
|
||||
## Calls and references
|
||||
|
||||
The first call query runs `kuna decompile-graph --functions ''`, admitting no C or assembly bodies. One validated graph and forward/reverse indexes serve later call queries and existing `get_call_graph` / `trace_call_path` workflows. Numeric u64 addresses are parsed from their original JSON tokens. Only `call` edges become callers/callees; jumps and data references retain their distinct meaning. Graph counts, edge endpoints and ordering are validated before any relationship is returned. A forwarding address may be an instruction inside a function, so it is retained separately and never promoted to a function node or call edge. Reported indirect calls make affected relationship coverage partial; no target is invented for them.
|
||||
|
||||
`xrefs` runs native `xrefs --to ADDRESS --json` on demand. Kuna unifies forwarding aliases and suppresses edges internal to their class; REA filters to the requested address and records the excluded-row count. Duplicate source sites appear once. An empty result cannot establish the absence of references. Addresses are explicit u64 values or exact, unambiguous procedure names; Kuna has no cursor.
|
||||
|
||||
REA parses the graph as Kuna writes it, like the string scan, so the graph has no fixed size: a 53 MB Raycast binary produces 157 MB (180k functions, 773k edges), which REA retains in about 93 MB after a whole-program walk of about a minute. Unrequested bodies are refused before any of their text is assembled, and edges are indexed as they arrive, so retained rows and their indexes are admitted against live heap headroom. Xref JSON admits at most 16 MiB before parsing. Output or Kuna diagnostics beyond a buffer are reported as a `memory` resource constraint with `retryable: false`, because the same target and executable produce the same output. The session remembers such a graph failure, so later call queries fail at once instead of repeating the whole-program walk. The graph is cached for the selected target and executable profile within one session. Xref reuse is an LRU charged by source bytes plus metadata, limited to 16 MiB and 128 entries; at most eight distinct native xref queries may be pending. Reference commands run one at a time per session and share the provider's foreground budget with single-function decompiles. An unproven process stop retains its admission slots until cleanup succeeds. Concurrent callers share work, individual cancellation releases only that waiter, and the last departing waiter cancels its producer and receives any unproven cleanup. Session close aborts and drains producers, releases parsed caches and retries any retained process/file cleanup.
|
||||
|
||||
Evidence includes only selected addresses or dossier neighbors, the producing JSON's SHA-256/byte count, coverage and relevant function facts; unrequested program-wide JSON and instruction text are omitted. Reference caches are in memory and expire on close: a fresh CLI process or MCP server rebuilds them. A first call query therefore costs a whole-program reference walk even when a C export is warm. These operations do not establish full Ghidra/IDA feature parity.
|
||||
|
||||
Failures from shared installation or inventory work identify the operation the
|
||||
caller requested. `diagnostics.producer_operation` retains the internal producer
|
||||
name when it differs. Caller-specific failures keep the producer's typed outcome,
|
||||
captured output, partial facts and live cleanup dependencies; cleanup retry
|
||||
updates every projection rather than preserving an independent stale marker.
|
||||
Installation acquisition is shared, with independently cancellable caller waits.
|
||||
The final departing caller stops the probe and joins its cleanup; session close
|
||||
also stops and joins acquisition. A cleanly cancelled acquisition can be retried,
|
||||
while a retained cleanup failure blocks replacement until its owner is closed.
|
||||
Shared string and reference queries preserve caller cancellation reasons and
|
||||
join the final departing caller's command cleanup. A command cleanup error keeps
|
||||
its typed primary failure and captured output. Its live resource list follows
|
||||
both process and workspace ownership: proving process exit does not prove that
|
||||
the private workspace was removed, and retry updates earlier caller errors.
|
||||
If workspace setup fails, an unsuccessful rollback retains the original target
|
||||
or read failure together with its cleanup owner. Replacement stays blocked until
|
||||
that rollback is resolved; a clean rollback permits another setup attempt.
|
||||
|
||||
## Provenance and limitations
|
||||
|
||||
- Addresses and bytes are Kuna's observations of the image. Procedure entries and extents are its derivations: extents are upper bounds clipped at the next entry, and Kuna can split one function at an entry its own analysis infers. Pseudocode is its reconstruction, never original source.
|
||||
- Pseudocode and assembly are exact Kuna text; text from Kuna and from another provider is not comparable as equal or different.
|
||||
- Results are re-read rather than replayed from REA's analysis snapshots, because a cold answer can differ from the export's.
|
||||
|
||||
## Cache ownership
|
||||
|
||||
REA writes Kuna's exports only inside `REA_KUNA_CACHE_DIR`:
|
||||
|
||||
- `projects/<key>/` holds published, immutable exports with a manifest of file digests.
|
||||
- `staging/` holds builds whose processes may still be live.
|
||||
- `trash/` holds retired builds and evicted exports awaiting removal.
|
||||
- `home/` is Kuna's HOME.
|
||||
|
||||
Builds publish by one rename, so a reader sees a complete export or none. A session keeps the export it uses from eviction only within its own REA process. If another REA process sharing the cache evicts it, the session rebuilds it; meanwhile pseudocode falls back to single-function runs. A damaged or edited export is removed and rebuilt. Staging moves to `trash/` for removal only after REA proves its Kuna process stopped. Staging of a process it cannot prove stopped is never swept; REA keeps it owned, retries the stop on `close_binary`, and reports it until the stop is proven. Failed file removal also stays bound to its export and is retried by `close_binary`; closing does not report success while that cleanup remains. `rea doctor --provider kuna` reports the cache directory without creating it.
|
||||
|
||||
## Verify with a real Kuna
|
||||
|
||||
```bash
|
||||
REA_KUNA_COMMAND=/absolute/path/to/kuna npm run verify:kuna
|
||||
# Compare with Ghidra on caller-built binaries
|
||||
REA_KUNA_COMMAND=/absolute/path/to/kuna GHIDRA_INSTALL_DIR=/absolute/path/to/ghidra \
|
||||
npm run verify:kuna -- --targets DIR --functions inflate,crc32 --compare-ghidra
|
||||
```
|
||||
|
||||
The lane compiles a small source-owned fixture with the host C compiler and verifies the MCP workflow end to end. `--targets DIR --functions a,b` adds caller-built binaries. `--compare-ghidra` (with `GHIDRA_INSTALL_DIR`) runs those same functions through Ghidra; it requires `--targets` and `--functions` and refuses empty matrices or requested function names missing from every target. See [testing](testing.md#kuna-lane) for coverage.
|
||||
|
||||
Failed runs also report process-lineage evidence and exit unsuccessfully. If provider or transport cleanup is unconfirmed, the report says `cleanup: "incomplete"` and records `retained_workspace`; that directory is preserved for investigation and cleanup retries.
|
||||
@@ -352,7 +352,7 @@ install it or its toolchain. The [NativeAOT guide](ghidra-nativeaot.md) defines
|
||||
these routes, their layout/host restrictions, derived-memory provenance, and
|
||||
verification coverage.
|
||||
|
||||
REA's experimental Windows Ghidra boundary admits native x86, x86-64, ARMNT (Thumb-2) and ARM64 PE
|
||||
REA's experimental Windows Ghidra boundary admits native x86 and x86-64 PE
|
||||
applications and DLLs for static analysis. For x64 PE NativeAOT, the read-only
|
||||
parser also runs there; the [NativeAOT guide](ghidra-nativeaot.md) lists what a
|
||||
Windows host covers.
|
||||
|
||||
+9
-104
@@ -393,31 +393,15 @@ concrete version, selection source, and complete analysis profile through
|
||||
choices return typed selection details. A selected provider is never replaced
|
||||
automatically after a runtime failure.
|
||||
|
||||
Each provider client receives `binary_session.analysis_run.run_id` before any
|
||||
provider startup, including clients whose startup fails. `process_lineage` is
|
||||
`not_observed` until a dynamic provider starts, then becomes `snapshots` with
|
||||
every started provider's identity
|
||||
Every successful target transition allocates `binary_session.analysis_run.run_id`
|
||||
before any provider startup. `process_lineage` is `not_observed` until a dynamic
|
||||
provider starts, then becomes `snapshots` with every started provider's identity
|
||||
and retained ownership observation. Each observation records `observed_at` and
|
||||
is `unavailable` with a reason when ownership could not be revalidated, or
|
||||
`verified` with launcher PID, parent PID, process group, and descendants observed
|
||||
at that bounded check. These are historical snapshots, not live process
|
||||
inventories, and do not claim that no short-lived descendant existed.
|
||||
|
||||
`binary_session.cleanup_pending` reports whether the session retains a provider
|
||||
client, session file resource, or provider-candidate resource whose cleanup
|
||||
has not succeeded. It can be true with
|
||||
`open: false`; target retirement does not establish resource release. For a
|
||||
retained provider client, health, activity, and lineage remain available under
|
||||
its original `analysis_run.run_id` where the provider supplies them.
|
||||
Successful provider cleanup clears the retained run;
|
||||
a replacement client receives a fresh run ID. Follow the cleanup error's
|
||||
reported resources and recovery action before reopening; a missing health
|
||||
observation does not establish an idle provider.
|
||||
File cleanup can also remain after snapshot publication or after profile
|
||||
inspection fails or is cancelled before a provider client exists. If no client
|
||||
remains, no provider run or health observation is available; follow the cleanup
|
||||
error's reported resources.
|
||||
|
||||
## Progress and cancellation
|
||||
|
||||
REA accepts ordinary `tools/call` progress tokens. The numeric `progress` counts
|
||||
@@ -435,9 +419,6 @@ 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
|
||||
uses `cleanup_incomplete` and lists only the owned resource kinds that remain.
|
||||
Once those owners confirm cleanup, composed failures recover their original
|
||||
typed primary outcome and recovery guidance. Historical composition diagnostics
|
||||
remain in `details.cleanup_history`, separate from the primary diagnostics.
|
||||
An atomic Evidence bundle or snapshot write can publish its complete output
|
||||
before staging cleanup fails. In that case, `details.published: true`,
|
||||
`details.published_path`, and `details.bytes` retain the publication receipt.
|
||||
@@ -447,25 +428,12 @@ 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.
|
||||
For these tools, cancellation observed during result finalization or owned
|
||||
cleanup also returns typed cancellation with the available observations.
|
||||
A normal target exit does not establish request completion. Incomplete cleanup
|
||||
still takes precedence and retains its resource diagnostics.
|
||||
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.
|
||||
|
||||
Bundle recovery requires a recorded Evidence ID. Some provider errors carry
|
||||
typed raw observations in `details.partial_observation` instead of Evidence.
|
||||
Those raw observations are not recorded in the Evidence bundle. If the SDK
|
||||
suppresses the error reply after client cancellation, Evidence tools cannot
|
||||
recover them. An empty bundle does not prove that no partial work or side
|
||||
effect occurred; output receipts and cleanup observations remain distinct.
|
||||
The broader retention decision is tracked in
|
||||
[#4276](https://github.com/morluto/rea/issues/4276).
|
||||
|
||||
`analyze_javascript_application` also yields between reconstruction phases and
|
||||
during graph/result sealing, cross-graph binding checks, Evidence JSON validation,
|
||||
and canonical hashing. Its final result validation reuses exact graphs whose
|
||||
@@ -524,40 +492,12 @@ analysis runtime. These failures are reported at the operation that needs
|
||||
them. A configured provider or an endpoint alone does not establish that a
|
||||
target is supported.
|
||||
|
||||
Composite Hopper regex searches report failures against the accepted
|
||||
`search_strings` or `search_procedures` operation. The underlying inventory
|
||||
method and request ID remain in `details.diagnostics.provider_request`, with
|
||||
the bridge error code and diagnostic type when available. Reattribution
|
||||
preserves the failure class, captured output, and live cleanup ownership.
|
||||
|
||||
Evidence bundles, snapshots, and extraction use the paths and output behavior
|
||||
declared by their tools. Artifact extraction materializes the selected regular
|
||||
files into a fresh REA-chosen temporary directory and reports its path.
|
||||
|
||||
`analyze_javascript_application` reads the supplied local directory or ASAR path
|
||||
and returns its result and Evidence inline. Its owned analysis worker and private
|
||||
temporary source files are declared as `launchesProcess` and `writesFilesystem`,
|
||||
including for a single JavaScript source. This internal analysis does not execute
|
||||
the supplied application code.
|
||||
|
||||
## Static Ghidra bytes and source mappings
|
||||
|
||||
`read_bytes` returns initialized analysis memory, including loader fixups, rather
|
||||
than live process memory. Check `returned_bytes` and `complete` before decoding:
|
||||
reads stop at unmapped or uninitialized bytes. Missing bytes are unknown; do not
|
||||
pad an incomplete read with zeros and treat the result as an observation.
|
||||
|
||||
`list_segments` reports memory-block initialization and address-space facts.
|
||||
`address_to_file_offset` maps one address through the provider's source-byte
|
||||
mapping. A successful start-address mapping does not establish that an entire
|
||||
range is contiguous in the original file, or that its bytes equal analysis
|
||||
memory after loader fixups. Uninitialized, missing, and ambiguous mappings fail
|
||||
explicitly; preserve the reported failure rather than guessing an offset.
|
||||
|
||||
For constructor-populated pointer or resource slots, a static zero is not proof
|
||||
of a later null value. Inspect the slot's `xrefs` and the writer's assembly or
|
||||
pseudocode, retaining uncertainty about execution order and runtime values.
|
||||
These operations inspect static evidence and do not execute the target.
|
||||
and returns its result and Evidence inline.
|
||||
|
||||
## Ghidra first-query deadlines and recovery
|
||||
|
||||
@@ -577,14 +517,6 @@ These deadlines have different owners:
|
||||
| Darwin swiftc helper | REA allows 120,000 ms by default for ownership-helper compilation; `REA_SWIFTC_COMPILE_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid values fail configuration validation. |
|
||||
| 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 [Codex and Kimi registrations](client-configuration.md), setup supplies
|
||||
missing tool deadlines from the known provider allowance plus 120 seconds of
|
||||
operation headroom: 450 seconds with the default Ghidra allowance, or 2820
|
||||
seconds with `REA_GHIDRA_STARTUP_TIMEOUT_MS=2700000`. Positive caller-selected
|
||||
deadlines remain unchanged. Doctor reports an informational recommendation
|
||||
when a configured deadline is shorter than the known provider allowance. An
|
||||
explicit JEB upstream request budget also contributes to that allowance.
|
||||
|
||||
For an already connected client using the pinned SDK, request options are the
|
||||
**second** argument of `callTool`:
|
||||
|
||||
@@ -614,20 +546,10 @@ Waiting notifications stop when startup settles or the caller cancels. They do
|
||||
not measure engine work completed.
|
||||
|
||||
The pinned SDK can reset the request's inactivity timeout on progress with
|
||||
`resetTimeoutOnProgress: true`. These options belong in the same second
|
||||
argument of `callTool`. Without that explicit client policy, the default
|
||||
60-second request deadline still expires despite waiting notifications.
|
||||
|
||||
SDK 2.3.1 checks `maxTotalTimeout` when progress resets the timer; it does not
|
||||
schedule a separate absolute timer for that setting. A silent interval can
|
||||
therefore run beyond the declared total. For an absolute caller deadline,
|
||||
also pass `signal: AbortSignal.timeout(totalBudgetMs)`. If the caller already
|
||||
has a cancellation signal, preserve both with
|
||||
`AbortSignal.any([callerSignal, AbortSignal.timeout(totalBudgetMs)])`.
|
||||
`maxTotalTimeout` can still bound progress resets, and REA's provider startup
|
||||
deadline still applies. Choose the total budget for the expected workload;
|
||||
neither server configuration nor progress can override a remote caller's
|
||||
deadline.
|
||||
`resetTimeoutOnProgress: true`. Also set `maxTotalTimeout` to bound the complete
|
||||
request; the provider's startup deadline still applies. These options belong in
|
||||
the same second argument of `callTool`. Without that explicit client policy, the
|
||||
default 60-second request deadline still expires despite waiting notifications.
|
||||
|
||||
The 240-second setting is a measured example, not a universal timeout: a
|
||||
controlled Linux x64/WSL2 fixture took about 64 seconds for its first overview
|
||||
@@ -751,20 +673,6 @@ 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.
|
||||
|
||||
Boolean literal constraints in input schemas are relaxed only in this
|
||||
advertisement. For example, a boolean `const` is presented as `type: boolean`;
|
||||
an affected `not` is omitted, conditional predicates and their branches are
|
||||
omitted together, pure boolean-literal `oneOf` branches collapse to a boolean,
|
||||
and other affected `oneOf` branches are presented as `anyOf` to retain branch
|
||||
guidance without making overlapping widened branches reject inputs.
|
||||
This can make the advertised schema accept inputs the canonical contract
|
||||
rejects. The MCP handler still validates every call with the canonical
|
||||
contract. The Gemini CLI verifier checks the outgoing
|
||||
`parametersJsonSchema` and canonical contract examples against that declaration
|
||||
using a loopback model fixture; it does not establish live Google API or
|
||||
OpenCode client behavior. Set `REA_VERIFY_GEMINI_SCHEMA_PROFILE=compact` to
|
||||
verify the compact advertisement through the same client boundary.
|
||||
|
||||
### Compact input schema profile
|
||||
|
||||
Some function-calling providers reject a request while any single tool's
|
||||
@@ -782,10 +690,7 @@ reported by strict-depth MCP clients in [#2813](https://github.com/morluto/rea/i
|
||||
WorkBuddy/CodeBuddy gateways have also rejected full REA catalogs with an
|
||||
opaque `11133` error while accepting the compact profile
|
||||
([#2999](https://github.com/morluto/rea/issues/2999)); compatibility depends on
|
||||
the selected gateway and model. That report used ZCode through a gateway to a
|
||||
Kimi-K3 backend, not the WorkBuddy MCP client. Set the profile on REA's
|
||||
registration in the actual MCP host; the host's name alone does not identify
|
||||
the downstream model or its schema constraints.
|
||||
the selected gateway and model.
|
||||
|
||||
The compact profile renders the same tool set, output schemas, annotations,
|
||||
and canonical server-side validation. It changes only the advertised input
|
||||
|
||||
+2
-6
@@ -111,12 +111,8 @@ list does not establish that the target has no procedures.
|
||||
Suggestions are Unicode-normalized, case-insensitive prefix matches. The server
|
||||
deduplicates them and sorts by code point for deterministic results. Procedure
|
||||
completion derives candidates from the complete inventory, so a name is offered
|
||||
only when it identifies one address in that inventory. A completion reply
|
||||
carries at most 100 values, the MCP limit. `total` counts every match and
|
||||
`hasMore` is `true` when values were omitted. Completion has no paging
|
||||
controls. A longer prefix reaches an omitted value only when it excludes other
|
||||
matches; matching uses normalized, case-insensitive forms, so a value can stay
|
||||
unreachable when more than 100 matches share its normalized prefix.
|
||||
only when it identifies one address in that inventory. Completion returns all
|
||||
matching values; it does not expose paging controls.
|
||||
|
||||
## Lifecycle and safety
|
||||
|
||||
|
||||
@@ -261,23 +261,6 @@ Mach-O fixtures check each case against source-owned return values.
|
||||
|
||||
## Static inspection
|
||||
|
||||
`inspect_plist.format` describes the selected source, not plutil's conversion
|
||||
format. Sources explicitly identified as XML, binary or JSON retain those
|
||||
labels. For generic text, a bounded source-prefix probe recognizes leading XML
|
||||
markup, including UTF-8 and BOM-marked UTF-16 sources. Unidentified text and
|
||||
OpenStep plists, including a data-only value such as `<deadbeef>`, report
|
||||
`unknown` even when plutil decodes their values through an XML conversion.
|
||||
|
||||
A plist explicitly selected through the path input or as the active plist target
|
||||
reports an unreadable or malformed selection as `invalid_request`. A missing or
|
||||
unreadable default plist of another target reports `capability_unavailable`.
|
||||
Permission failures remain `access_denied`; output and cleanup failures retain
|
||||
their own error categories.
|
||||
|
||||
A plist decode refusal includes plutil's diagnostic from either output stream.
|
||||
`details.captured_output` retains bounded stdout/stderr excerpts, observed byte
|
||||
totals and exit status. `truncated: true` means those excerpts are incomplete.
|
||||
|
||||
`inspect_macho.selected_architecture` identifies the exact selected lipo slice
|
||||
and its `container_file_offset` in the input file. A thin Mach-O has a known
|
||||
offset of zero; an unknown universal-slice offset stays null. The Evidence
|
||||
@@ -287,9 +270,7 @@ Mach-O image. Architecture
|
||||
`file_offset` values are container-relative. Entrypoint, segment and section
|
||||
`file_offset` values retain their source meaning and are relative to the
|
||||
selected Mach-O slice. Raw load-command fields retain their original values.
|
||||
A field otool prints more than once, such as each `LC_BUILD_VERSION` tool, is
|
||||
keyed `name #n` in print order. Each `LC_LINKER_OPTION` string is keyed
|
||||
`string #n` and checked against the declared `count`. Evidence locations map the LC_MAIN entrypoint and nonempty file-backed segment
|
||||
Evidence locations map the LC_MAIN entrypoint and nonempty file-backed segment
|
||||
ranges to container offsets by adding the observed slice offset. Zero-fill
|
||||
segments do not produce file ranges. When the selected slice's container offset
|
||||
is unknown, those mapped locations are omitted with an explicit limitation;
|
||||
@@ -334,16 +315,12 @@ complete observation.
|
||||
shared/cyclic references, class descriptors, raw serialized fields and
|
||||
malformed/unresolved/nil references. Missing fields stay absent; unknown
|
||||
classes are preserved. Select `root`, `offset` and `limit` explicitly.
|
||||
Object `kind` describes the decoded archive value: data, dates and numbers
|
||||
remain `scalar` when their JSON value uses a `$plist_type` wrapper. An actual
|
||||
dictionary with the same fields remains `dictionary`.
|
||||
UID 0 cannot distinguish conditional nil from ordinary nil. Limits are
|
||||
64 MiB of input, 200,000 objects/references and 128 nesting levels.
|
||||
XML dictionary entries decoded as `__proto__` are omitted with an explicit
|
||||
count because REA results cannot represent that key. XML tag whitespace and
|
||||
comments do not change that handling. XML key names combine their text and
|
||||
CDATA segments without trimming or expanding literal CDATA entities. Other
|
||||
values and the original archive digest are preserved.
|
||||
comments do not change that handling. Other values and the original archive
|
||||
digest are preserved; key interpretation follows the pinned plist decoder.
|
||||
- `decode_interface_builder` / `rea decode-interface-builder <app>` reads
|
||||
compiled storyboard and nib resources into objects, outlets, actions,
|
||||
connections and controller/class names. A full app graph is often several
|
||||
@@ -401,12 +378,7 @@ complete observation.
|
||||
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. A type attribute whose quoted class name
|
||||
never closes is incomplete and marks `objc_properties_categories` partial
|
||||
with `property_attributes_incomplete`. A property record that cannot be
|
||||
decoded, such as one with an empty or unmapped name, is reported as
|
||||
`property_decode_failed` at its entry address while sibling properties are
|
||||
retained. `is_meta_class`, `is_root_class`, and
|
||||
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
|
||||
@@ -419,10 +391,6 @@ complete observation.
|
||||
coroutine tables, and inherited overrides, have explicit unsupported or
|
||||
partial coverage. Other providers retain the
|
||||
existing symbol-based inventory with its narrower coverage.
|
||||
Symbols without a reported location remain in that inventory: Swift symbol
|
||||
`address` and Objective-C `implementation_address` are null. An empty provider
|
||||
address is retained as `reported_address` in the symbol's evidence, whose
|
||||
location also remains unknown. Nonempty provider address syntax is preserved.
|
||||
|
||||
## Native desktop observation
|
||||
|
||||
@@ -439,11 +407,7 @@ decrement scrolling and text-value entry, or bounded waits. No global event
|
||||
injection is used. Unsupported AX actions fail explicitly. The result preserves
|
||||
ordered before/after captures and gaps; an action may have occurred before a
|
||||
post-action capture fails. Application state is left as-is; REA does not attempt
|
||||
to restore it. Failed or cancelled scenarios return a typed error with the
|
||||
collected report in `partial_observation`, including ordered step outcomes.
|
||||
Cancellation preserves the caller's reason and remains observable through helper
|
||||
cleanup. A later abort does not replace an earlier helper or output failure.
|
||||
Cleanup failures retain their runtime owner until a confirmed cleanup retry.
|
||||
to restore it.
|
||||
|
||||
Scenarios accept caller-selected action lists and accessibility node counts.
|
||||
Individual waits cannot exceed the operation's 180-second deadline, and the
|
||||
@@ -480,11 +444,6 @@ The run ends when the process exits, `max_events` entries are recorded,
|
||||
Bounded termination reports partial coverage. REA checks process termination
|
||||
using a launch-time OS start identity; if ownership or cleanup cannot be
|
||||
verified, the result or error preserves that uncertainty. The result reports:
|
||||
Launch errors keep the fact that LLDB created a process separate from whether
|
||||
it remains alive. An exited `SBProcess` is reported as exited only after LLDB
|
||||
confirms that state; unresolved ownership remains retained for cleanup retry.
|
||||
Cancellation observed while output and Evidence are finalized returns partial
|
||||
cancellation Evidence, even if the target has already exited.
|
||||
|
||||
- the outcome, exit status and captured stdout/stderr (1 MiB kept per stream
|
||||
while excess bytes are drained and counted without growing capture files).
|
||||
@@ -515,11 +474,6 @@ with partial coverage. Available output prefixes remain inline; their byte
|
||||
counts are observed lower bounds when final drain counters are unavailable.
|
||||
The original failure classification and cleanup uncertainty remain separate.
|
||||
An interrupted journal row is ignored with an explicit limitation.
|
||||
If the trace completed before cancellation or runtime-directory cleanup failed,
|
||||
the retained observation also keeps its exit status, termination proof, launch
|
||||
identity, breakpoint results and final stream counters. Those fields remain
|
||||
absent when the interrupted producer did not report them; partial coverage alone
|
||||
does not mean that every retained fact is incomplete.
|
||||
|
||||
Only entries are observed: return values, floating-point and stack arguments,
|
||||
and inlined or `objc_direct` calls are not. The target runs with the current
|
||||
@@ -536,7 +490,7 @@ is present. A denied trace reports the `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, x86-64, ARMNT (Thumb-2) and ARM64 PE applications and DLLs, plus explicitly selected
|
||||
x86 and x86-64 PE applications and DLLs, plus explicitly selected
|
||||
[raw NMOS 6502 images](raw-binary.md#nmos-6502) with a caller-supplied load address,
|
||||
on fixed local NTFS volumes. Other raw CPU families remain unsupported on Windows.
|
||||
The boundary uses bundled Job Object ownership, protected runtime DACLs, and
|
||||
@@ -597,10 +551,6 @@ digests identify the original serialized bytes.
|
||||
## Keyed archive integer precision
|
||||
|
||||
The archive reader observes XML number element types and binary number markers.
|
||||
XML values and their number facts are interpreted together from the validated
|
||||
DOM. Hexadecimal `<integer>` text, including an optional sign, retains its value;
|
||||
`<real>` text and CDATA segments are combined without inferring text from nested
|
||||
elements. The XML path does not serialize or reparse character references.
|
||||
Integers beyond the exact range of a JSON number are reported with the original
|
||||
decimal text as `{ "$plist_type": "integer", "decimal": "<exact digits>" }` when
|
||||
that source value can be associated unambiguously. Integral real values remain
|
||||
@@ -620,48 +570,6 @@ Exact and ambiguous value counts describe emitted root/object value instances;
|
||||
a root and an object may contain the same value. Archive digests identify the
|
||||
original bytes.
|
||||
|
||||
Interface Builder's XML and binary plist archives use the same number metadata
|
||||
and exact-decimal representation for emitted node attributes. Projection follows
|
||||
object and connection classification, so archive IDs, UID links and graph counts
|
||||
keep their meaning. Precision limitations name the source document. Unsafe
|
||||
integer-literal counts cover the archive, including fields not emitted as node
|
||||
attributes; exact and ambiguous projection counts cover emitted attribute values.
|
||||
Integral reals stay numbers, and ambiguous or incompletely observed values retain
|
||||
explicit precision limitations. Before plist decoding, the existing aggregate
|
||||
decode budget reserves estimated room for number metadata and attribute
|
||||
projection; these estimates are not a hard process-memory bound. Native
|
||||
NIBArchive decoding is unchanged by this plist-specific representation.
|
||||
|
||||
Dates are reported as `{ "$plist_type": "date", "iso8601": "<timestamp>" }`. A
|
||||
date the decoder cannot represent, such as an XML date with a year beyond 9999
|
||||
or a negative year, is reported as `{ "$plist_type": "date", "iso8601": null }`
|
||||
with a counted limitation; the rest of the plist or archive is still decoded.
|
||||
`inspect_plist` and Interface Builder decoding use the same projection.
|
||||
|
||||
A negative-zero real is reported as `{ "$plist_type": "real", "value": "-0" }`
|
||||
because a JSON number cannot carry the sign of zero. `inspect_plist` and
|
||||
`inspect_keyed_archive` count these values in a limitation, and Interface
|
||||
Builder node attributes use the same value. Positive zero and integer zero,
|
||||
including an `<integer>-0</integer>` literal, remain the number `0`.
|
||||
|
||||
Known non-finite reals are reported as
|
||||
`{ "$plist_type": "real", "value": "nan" | "+infinity" | "-infinity" }`.
|
||||
These are canonical numeric labels, not a claim about original source spelling.
|
||||
Binary IEEE reals retain NaN versus signed infinity; NaN payload bits and sign
|
||||
are not represented in the JSON value, and the original bytes remain the source
|
||||
for those details. XML CFPropertyList literals (`nan`, `+infinity`, `-infinity`,
|
||||
`infinity`, `inf`, `+inf`, `-inf`, case-insensitively) decode to the same known
|
||||
values. Case and aliases normalize; original archive bytes retain source text.
|
||||
|
||||
XML numeric text whose identity the decoder cannot establish, including
|
||||
unrecognized non-finite text and finite literals that overflow the numeric
|
||||
representation, remains `{ "$plist_type": "real", "value": null }` with a
|
||||
counted limitation. The XML decoder marks these values explicitly before shared
|
||||
projection, so they cannot be confused with known binary IEEE values.
|
||||
Incomplete numeric markup retains its existing compatibility behavior described
|
||||
above. Known non-finite and unresolved numeric values have separate counts.
|
||||
Native `inspect_plist` uses these same labels for plutil's XML conversion.
|
||||
|
||||
## Locate a byte signature
|
||||
|
||||
Use `search_bytes` after opening a target with Ghidra to locate a known constant
|
||||
|
||||
@@ -58,11 +58,6 @@ tools read that copy, which is hashed again after analysis. Capture metadata and
|
||||
literal field values are producer observations; address/protocol counts and DNS
|
||||
associations are derivations. Capture Evidence has historical-reference authority.
|
||||
|
||||
`capture_start` and `capture_end` are RFC 3339 UTC instants derived from
|
||||
`capinfos -S` epoch seconds, retaining all producer fractional digits (up to
|
||||
nanoseconds). Empty captures, malformed timestamps and instants outside years
|
||||
0000–9999 remain `null`; host-local timestamps without a zone are not inferred.
|
||||
|
||||
Addresses count once per packet, including loopback and nested IP occurrences.
|
||||
DNS addresses are associated only with one question in the same response packet;
|
||||
additional records may be included, so this does not prove final resolution.
|
||||
|
||||
@@ -425,9 +425,7 @@ 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. A trace difference applies to the dimensions identified by its
|
||||
diagnostic; unrelated dimensions retain their own comparison, including unknown
|
||||
coverage. Captures missing `truncation_details` are rejected on import;
|
||||
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.
|
||||
|
||||
+13
-45
@@ -25,31 +25,27 @@ rea inspect-native-load-image /absolute/path/to/ecu.bin --target-format raw-bina
|
||||
}
|
||||
```
|
||||
|
||||
`architecture` is one of `x86`, `x86_64`, `arm`, `arm64`, `6502`, or `m68k`. `entry_point` is a
|
||||
`architecture` is one of `x86`, `x86_64`, `arm`, `arm64`, or `6502`. `entry_point` is a
|
||||
hexadecimal address of the form `0x…`. The complete file is mapped starting at
|
||||
that address, and Ghidra seeds an `entry` function there before auto-analysis.
|
||||
ARM and AArch64 entries must be 4-byte aligned; m68k entries must be 2-byte
|
||||
aligned; x86 and 6502 entries may be byte-aligned.
|
||||
ARM and AArch64 entries must be 4-byte aligned; x86 and 6502 entries may be byte-aligned.
|
||||
For 6502, the entry and complete mapped file must fit within `0x0000..0xffff`;
|
||||
images that cross the 16-bit boundary are rejected before provider startup.
|
||||
For m68k, the mapping must fit within `0x0..0xffffffff`.
|
||||
`open_binary` and an open `binary_session` return the canonical `entry_point`
|
||||
for raw targets so callers can verify the selected mapping directly.
|
||||
Omitted `format` keeps header-based detection; architecture and entry without
|
||||
`format=raw-binary` are rejected.
|
||||
|
||||
Ghidra imports a private snapshot with `BinaryLoader` and these generic
|
||||
languages and compiler specifications. Each family has one fixed byte order:
|
||||
m68k is big-endian and the others are little-endian.
|
||||
Ghidra imports a private snapshot with `BinaryLoader` and these little-endian
|
||||
generic languages and compiler specifications:
|
||||
|
||||
| architecture | language_id | compiler_spec_id |
|
||||
| ------------ | --------------------- | ---------------- |
|
||||
| x86 | `x86:LE:32:default` | `gcc` |
|
||||
| x86_64 | `x86:LE:64:default` | `gcc` |
|
||||
| arm | `ARM:LE:32:v7` | `default` |
|
||||
| arm64 | `AARCH64:LE:64:v8A` | `default` |
|
||||
| 6502 | `6502:LE:16:default` | `default` |
|
||||
| m68k | `68000:BE:32:default` | `default` |
|
||||
| architecture | language_id | compiler_spec_id |
|
||||
| ------------ | -------------------- | ---------------- |
|
||||
| x86 | `x86:LE:32:default` | `gcc` |
|
||||
| x86_64 | `x86:LE:64:default` | `gcc` |
|
||||
| arm | `ARM:LE:32:v7` | `default` |
|
||||
| arm64 | `AARCH64:LE:64:v8A` | `default` |
|
||||
| 6502 | `6502:LE:16:default` | `default` |
|
||||
|
||||
Compiler specifications select analysis conventions; they do not identify the
|
||||
original compiler or ABI of a headerless target. Ghidra's x86 languages do not
|
||||
@@ -110,40 +106,12 @@ unchanged source bytes and complete runtime cleanup. Windows requires the
|
||||
matching native addon; the POSIX provider path has not been exercised by the
|
||||
Windows run.
|
||||
|
||||
## Motorola 68000
|
||||
|
||||
```bash
|
||||
rea function /absolute/path/to/image.bin 0x1000 --target-format raw-binary --architecture m68k --entry-point 0x1000 --provider ghidra --json
|
||||
rea inspect-native-load-image /absolute/path/to/image.bin --target-format raw-binary --architecture m68k --entry-point 0x1000 --provider ghidra --json
|
||||
```
|
||||
|
||||
Select only headerless big-endian 68000-family code with a known, even entry at
|
||||
file offset 0. Ghidra's `68000:BE:32:default` language decodes the 68040
|
||||
superset in the 32-bit `ram` address space. Instructions that a real MC68000
|
||||
would not execute are therefore not rejected, and 68020, 68030, CPU32, and
|
||||
ColdFire programs are not admitted as those variants. Addresses are not masked
|
||||
to the MC68000 24-bit bus. Evidence preserves `architecture: "m68k"`, the
|
||||
selected language, entry, file digest, and verified source mapping. Register and
|
||||
calling conventions are analysis conventions, not a recovered source ABI.
|
||||
|
||||
This lane does not interpret Amiga hunks, Atari ST, or other container headers,
|
||||
cartridge or console memory maps, or bank switching. REA does not read the
|
||||
initial stack pointer and reset vector from the first eight bytes; select the
|
||||
entry explicitly. Windows Ghidra P0 does not admit m68k.
|
||||
|
||||
`npm run verify:ghidra:m68k` uses a source-owned 22-byte fixture written as
|
||||
annotated hex in the verifier, so it needs no assembler. The lane checks real
|
||||
CLI/MCP load-image parity, mapped bytes, a decoded call, decompilation by address
|
||||
and file offset, misaligned and out-of-range mappings, unchanged source bytes and
|
||||
runtime cleanup. It has been run with Ghidra 12.1.4 on macOS; Linux has not been
|
||||
exercised.
|
||||
|
||||
## Limitations
|
||||
|
||||
- Headers are not discovered from file bytes. This increment does not guess
|
||||
load addresses, vector tables, or memory maps.
|
||||
- Big-endian ARM, Thumb-only, Cortex-M, and other Ghidra processor variants are
|
||||
unsupported. m68k is the only big-endian family.
|
||||
- Big-endian, Thumb-only, Cortex-M, and other Ghidra processor variants are
|
||||
unsupported.
|
||||
- Reset vectors, memory-mapped I/O, and firmware boot sequences are not
|
||||
emulated.
|
||||
- Independent load-image verification covers source identity, mapped file
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: هندسة عكسية لأي شيء
|
||||
|
||||
@@ -166,7 +166,7 @@ npx rea-agents@latest setup
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
تختلف صيغ ملفات الشيفرة الأصلية والأنظمة المضيفة المدعومة باختلاف الموفّر. راجع [إعداد Hopper وGhidra](../installation.md#hopper)، و[دليل IDA](../ida-provider.md)، [Kuna](../kuna-provider.md)، و[دعم Ghidra التجريبي على Windows](../windows-ghidra-p0.md). يدعم Ghidra أيضًا [تحليل DOS ذي 16 بت](../ghidra-dos.md). لاختيار الموفّر، راجع [دليل CLI](../cli.md#choose-a-provider). تحقّق من [توفر الميزات في الإصدارات](../installation.md#released-package-and-main) للميزات المضافة بعد أحدث إصدار على npm.
|
||||
تختلف صيغ ملفات الشيفرة الأصلية والأنظمة المضيفة المدعومة باختلاف الموفّر. راجع [إعداد Hopper وGhidra](../installation.md#hopper)، و[دليل IDA](../ida-provider.md)، و[دعم Ghidra التجريبي على Windows](../windows-ghidra-p0.md). يدعم Ghidra أيضًا [تحليل DOS ذي 16 بت](../ghidra-dos.md). لاختيار الموفّر، راجع [دليل CLI](../cli.md#choose-a-provider). تحقّق من [توفر الميزات في الإصدارات](../installation.md#released-package-and-main) للميزات المضافة بعد أحدث إصدار على npm.
|
||||
|
||||
## دراسات الحالة
|
||||
|
||||
@@ -274,7 +274,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## سجل النجوم
|
||||
|
||||
🎉 **300,000 نجمة على GitHub — شكرًا لكم!**
|
||||
🎉 **200,000 نجمة على GitHub — شكرًا لكم!**
|
||||
|
||||
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Alles reverse-engineeren
|
||||
|
||||
@@ -166,7 +166,7 @@ Statische JavaScript- und .NET-Untersuchungen lesen die bereitgestellten Dateien
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Native Formate und unterstützte Hostsysteme unterscheiden sich je nach Provider. Siehe [Hopper- und Ghidra-Einrichtung](../installation.md#hopper), den [IDA-Leitfaden](../ida-provider.md), [Kuna](../kuna-provider.md) und die [experimentelle Ghidra-Unterstützung unter Windows](../windows-ghidra-p0.md). Ghidra unterstützt auch [16-Bit-DOS-Analyse](../ghidra-dos.md). Die Provider-Auswahl beschreibt der [CLI-Leitfaden](../cli.md#choose-a-provider). Prüfe die [Verfügbarkeit in Releases](../installation.md#released-package-and-main) für Funktionen, die seit der neuesten npm-Version hinzugekommen sind.
|
||||
Native Formate und unterstützte Hostsysteme unterscheiden sich je nach Provider. Siehe [Hopper- und Ghidra-Einrichtung](../installation.md#hopper), den [IDA-Leitfaden](../ida-provider.md) und die [experimentelle Ghidra-Unterstützung unter Windows](../windows-ghidra-p0.md). Ghidra unterstützt auch [16-Bit-DOS-Analyse](../ghidra-dos.md). Die Provider-Auswahl beschreibt der [CLI-Leitfaden](../cli.md#choose-a-provider). Prüfe die [Verfügbarkeit in Releases](../installation.md#released-package-and-main) für Funktionen, die seit der neuesten npm-Version hinzugekommen sind.
|
||||
|
||||
## Fallstudien
|
||||
|
||||
@@ -272,7 +272,7 @@ Melde Sicherheitslücken gemäß [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Sternverlauf
|
||||
|
||||
🎉 **300.000 GitHub-Sterne – vielen Dank!**
|
||||
🎉 **200.000 GitHub-Sterne – vielen Dank!**
|
||||
|
||||
Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds testen und Fehlerbehebungen beitragen.
|
||||
|
||||
|
||||
@@ -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) · [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) · **Ελληνικά** · [മലയാളം](README_ml.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) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md) · **Ελληνικά**
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -179,7 +179,7 @@ npx rea-agents@latest setup
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Οι μορφές κώδικα μηχανής και τα υποστηριζόμενα συστήματα διαφέρουν ανά πάροχο ανάλυσης. Δες τη [ρύθμιση Hopper και Ghidra](../installation.md#hopper), τον [οδηγό IDA](../ida-provider.md) (που περιλαμβάνει προαιρετική γέφυρα MCP για κώδικα μηχανής), [Kuna](../kuna-provider.md) και την [πειραματική υποστήριξη Ghidra στα Windows](../windows-ghidra-p0.md). Το Ghidra υποστηρίζει επίσης [ανάλυση DOS 16 bit](../ghidra-dos.md). Για μεγάλα δυαδικά αρχεία, αύξησε το χρονικό όριο εκκίνησης του παρόχου με `REA_GHIDRA_STARTUP_TIMEOUT_MS` ή `REA_HOPPER_STARTUP_TIMEOUT_MS`. Για την επιλογή παρόχου, δες τον [οδηγό CLI](../cli.md#choose-a-provider). Έλεγξε τη [διαθεσιμότητα ανά έκδοση](../installation.md#released-package-and-main) για λειτουργίες που προστέθηκαν μετά την τελευταία έκδοση στο npm.
|
||||
Οι μορφές κώδικα μηχανής και τα υποστηριζόμενα συστήματα διαφέρουν ανά πάροχο ανάλυσης. Δες τη [ρύθμιση Hopper και Ghidra](../installation.md#hopper), τον [οδηγό IDA](../ida-provider.md) (που περιλαμβάνει προαιρετική γέφυρα MCP για κώδικα μηχανής) και την [πειραματική υποστήριξη Ghidra στα Windows](../windows-ghidra-p0.md). Το Ghidra υποστηρίζει επίσης [ανάλυση DOS 16 bit](../ghidra-dos.md). Για μεγάλα δυαδικά αρχεία, αύξησε το χρονικό όριο εκκίνησης του παρόχου με `REA_GHIDRA_STARTUP_TIMEOUT_MS` ή `REA_HOPPER_STARTUP_TIMEOUT_MS`. Για την επιλογή παρόχου, δες τον [οδηγό CLI](../cli.md#choose-a-provider). Έλεγξε τη [διαθεσιμότητα ανά έκδοση](../installation.md#released-package-and-main) για λειτουργίες που προστέθηκαν μετά την τελευταία έκδοση στο npm.
|
||||
|
||||
## Μελέτες περίπτωσης
|
||||
|
||||
@@ -285,7 +285,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## Ιστορικό αστεριών
|
||||
|
||||
🎉 **300.000 αστέρια στο GitHub — σας ευχαριστούμε!**
|
||||
🎉 **200.000 αστέρια στο GitHub — σας ευχαριστούμε!**
|
||||
|
||||
Ευχαριστούμε όλους όσοι χρησιμοποιούν το REA, αναφέρουν σφάλματα, ζητούν νέες λειτουργίες, δοκιμάζουν builds και συνεισφέρουν διορθώσεις.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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** · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Ingeniería inversa de cualquier cosa
|
||||
|
||||
@@ -166,7 +166,7 @@ La inspección estática de JavaScript y .NET lee los archivos suministrados sin
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Los formatos nativos y los sistemas anfitriones compatibles varían según el proveedor. Consulta [configuración de Hopper y Ghidra](../installation.md#hopper), la [guía de IDA](../ida-provider.md), [Kuna](../kuna-provider.md) y la [compatibilidad experimental de Ghidra en Windows](../windows-ghidra-p0.md). Ghidra también admite [análisis de DOS de 16 bits](../ghidra-dos.md). Para elegir un proveedor, consulta la [guía de CLI](../cli.md#choose-a-provider). Comprueba la [disponibilidad por versión](../installation.md#released-package-and-main) de las funciones añadidas después de la última versión publicada en npm.
|
||||
Los formatos nativos y los sistemas anfitriones compatibles varían según el proveedor. Consulta [configuración de Hopper y Ghidra](../installation.md#hopper), la [guía de IDA](../ida-provider.md) y la [compatibilidad experimental de Ghidra en Windows](../windows-ghidra-p0.md). Ghidra también admite [análisis de DOS de 16 bits](../ghidra-dos.md). Para elegir un proveedor, consulta la [guía de CLI](../cli.md#choose-a-provider). Comprueba la [disponibilidad por versión](../installation.md#released-package-and-main) de las funciones añadidas después de la última versión publicada en npm.
|
||||
|
||||
## Casos prácticos
|
||||
|
||||
@@ -272,7 +272,7 @@ Informa de vulnerabilidades siguiendo [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Historial de estrellas
|
||||
|
||||
🎉 **300.000 estrellas en GitHub: ¡gracias!**
|
||||
🎉 **200.000 estrellas en GitHub: ¡gracias!**
|
||||
|
||||
Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban compilaciones y contribuyen con correcciones.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: مهندسی معکوس هر چیزی
|
||||
|
||||
@@ -158,7 +158,7 @@ REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، بههمراه np
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
فرمتهای بومی و پشتیبانی سیستم میزبان بر اساس ارائهدهنده متفاوتاند. [راهاندازی Hopper و Ghidra](../installation.md#hopper)، [راهنمای IDA](../ida-provider.md)، [Kuna](../kuna-provider.md) و [پشتیبانی آزمایشی Ghidra در ویندوز](../windows-ghidra-p0.md) را ببینید. Ghidra همچنین از [تحلیل DOS شانزدهبیتی](../ghidra-dos.md) پشتیبانی میکند. برای انتخاب ارائهدهنده، به [راهنمای CLI](../cli.md#choose-a-provider) مراجعه کنید. برای قابلیتهایی که پس از آخرین انتشار npm اضافه شدهاند، [وضعیت انتشار](../installation.md#released-package-and-main) را بررسی کنید.
|
||||
فرمتهای بومی و پشتیبانی سیستم میزبان بر اساس ارائهدهنده متفاوتاند. [راهاندازی Hopper و Ghidra](../installation.md#hopper)، [راهنمای IDA](../ida-provider.md) و [پشتیبانی آزمایشی Ghidra در ویندوز](../windows-ghidra-p0.md) را ببینید. Ghidra همچنین از [تحلیل DOS شانزدهبیتی](../ghidra-dos.md) پشتیبانی میکند. برای انتخاب ارائهدهنده، به [راهنمای CLI](../cli.md#choose-a-provider) مراجعه کنید. برای قابلیتهایی که پس از آخرین انتشار npm اضافه شدهاند، [وضعیت انتشار](../installation.md#released-package-and-main) را بررسی کنید.
|
||||
|
||||
## نمونههای عملی
|
||||
|
||||
@@ -257,7 +257,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## تاریخچهٔ ستارهها
|
||||
|
||||
🎉 **۳۰۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
|
||||
🎉 **۲۰۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
|
||||
|
||||
از همهٔ کسانی که از REA استفاده میکنند، خطاها را گزارش میدهند، قابلیتهای جدید پیشنهاد میکنند، buildها را آزمایش میکنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA : rétro-ingénierie de tout
|
||||
|
||||
@@ -170,7 +170,7 @@ L'inspection statique JavaScript et .NET lit les fichiers fournis sans exécuter
|
||||
|
||||
<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](../installation.md#hopper), le [guide IDA](../ida-provider.md), [Kuna](../kuna-provider.md) et [la prise en charge expérimentale de Ghidra sous Windows](../windows-ghidra-p0.md). Ghidra prend aussi en charge [l'analyse DOS 16 bits](../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](../cli.md#choose-a-provider). Vérifiez la [disponibilité dans les versions publiées](../installation.md#released-package-and-main) pour les fonctionnalités ajoutées depuis la dernière version npm.
|
||||
Les formats natifs et les hôtes pris en charge varient selon le fournisseur. Consultez [la configuration de Hopper et Ghidra](../installation.md#hopper), le [guide IDA](../ida-provider.md) et [la prise en charge expérimentale de Ghidra sous Windows](../windows-ghidra-p0.md). Ghidra prend aussi en charge [l'analyse DOS 16 bits](../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](../cli.md#choose-a-provider). Vérifiez la [disponibilité dans les versions publiées](../installation.md#released-package-and-main) pour les fonctionnalités ajoutées depuis la dernière version npm.
|
||||
|
||||
## Études de cas
|
||||
|
||||
@@ -276,7 +276,7 @@ Signalez les vulnérabilités via [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Historique des étoiles
|
||||
|
||||
🎉 **300 000 étoiles GitHub — merci !**
|
||||
🎉 **200 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.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Rekayasa Balik Apa Pun
|
||||
|
||||
@@ -173,7 +173,7 @@ Pemeriksaan JavaScript dan .NET statis membaca berkas yang disediakan tanpa menj
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Format native dan dukungan sistem host berbeda-beda menurut penyedia. Lihat [penyiapan Hopper dan Ghidra](../installation.md#hopper), [panduan IDA](../ida-provider.md), [Kuna](../kuna-provider.md), dan [dukungan eksperimental Ghidra di Windows](../windows-ghidra-p0.md).
|
||||
Format native dan dukungan sistem host berbeda-beda menurut penyedia. Lihat [penyiapan Hopper dan Ghidra](../installation.md#hopper), [panduan IDA](../ida-provider.md), dan [dukungan eksperimental Ghidra di Windows](../windows-ghidra-p0.md).
|
||||
|
||||
Ghidra juga mendukung [analisis DOS 16-bit](../ghidra-dos.md).
|
||||
|
||||
@@ -297,7 +297,7 @@ Laporkan kerentanan melalui [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Riwayat Bintang
|
||||
|
||||
🎉 **300.000 bintang GitHub, terima kasih!**
|
||||
🎉 **200.000 bintang GitHub, terima kasih!**
|
||||
|
||||
Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fitur, menguji build, dan berkontribusi dalam perbaikan.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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**
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -170,7 +170,7 @@ L'ispezione statica di JavaScript e .NET legge i file forniti senza eseguire l'a
|
||||
|
||||
<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](../installation.md#hopper), la [guida IDA](../ida-provider.md), [Kuna](../kuna-provider.md) e il [supporto sperimentale Windows Ghidra](../windows-ghidra-p0.md). Ghidra supporta anche l'[analisi DOS a 16 bit](../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](../cli.md#choose-a-provider). Controlla la [disponibilità delle release](../installation.md#released-package-and-main) per le funzionalità aggiunte dall'ultima release npm.
|
||||
I formati nativi e il supporto host variano in base al provider. Vedi la [configurazione di Hopper e Ghidra](../installation.md#hopper), la [guida IDA](../ida-provider.md) e il [supporto sperimentale Windows Ghidra](../windows-ghidra-p0.md). Ghidra supporta anche l'[analisi DOS a 16 bit](../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](../cli.md#choose-a-provider). Controlla la [disponibilità delle release](../installation.md#released-package-and-main) per le funzionalità aggiunte dall'ultima release npm.
|
||||
|
||||
## Showcase
|
||||
|
||||
@@ -276,7 +276,7 @@ Segnala vulnerabilità tramite [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Cronologia delle stelle
|
||||
|
||||
🎉 **300.000 stelle su GitHub — grazie!**
|
||||
🎉 **200.000 stelle su GitHub — grazie!**
|
||||
|
||||
Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, testano le build e contribuiscono con correzioni.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA:あらゆるものをリバースエンジニアリング
|
||||
|
||||
@@ -166,7 +166,7 @@ REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
対応するネイティブ形式とホストは、プロバイダーによって異なります。[Hopper と Ghidra のセットアップ](../installation.md#hopper)、[IDA ガイド](../ida-provider.md)、[Kuna](../kuna-provider.md)、[Windows 向け Ghidra の実験的対応](../windows-ghidra-p0.md)を参照してください。Ghidra は [16 ビット DOS 分析](../ghidra-dos.md)にも対応しています。プロバイダーの選択は [CLI ガイド](../cli.md#choose-a-provider)を参照してください。最新の npm リリース以降に追加された機能については、[リリースでの利用可否](../installation.md#released-package-and-main)を確認してください。
|
||||
対応するネイティブ形式とホストは、プロバイダーによって異なります。[Hopper と Ghidra のセットアップ](../installation.md#hopper)、[IDA ガイド](../ida-provider.md)、[Windows 向け Ghidra の実験的対応](../windows-ghidra-p0.md)を参照してください。Ghidra は [16 ビット DOS 分析](../ghidra-dos.md)にも対応しています。プロバイダーの選択は [CLI ガイド](../cli.md#choose-a-provider)を参照してください。最新の npm リリース以降に追加された機能については、[リリースでの利用可否](../installation.md#released-package-and-main)を確認してください。
|
||||
|
||||
## 事例
|
||||
|
||||
@@ -274,7 +274,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## スター履歴
|
||||
|
||||
🎉 **GitHub スター 300,000 件、ありがとうございます!**
|
||||
🎉 **GitHub スター 200,000 件、ありがとうございます!**
|
||||
|
||||
REA の利用、バグ報告、機能の要望、ビルドのテスト、修正への貢献に感謝します。
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: 무엇이든 리버스 엔지니어링
|
||||
|
||||
@@ -62,7 +62,7 @@ REA는 에이전트를 분석 도구에 연결해 네이티브 바이너리, Jav
|
||||
|
||||
설정 과정은 에이전트에 REA를 등록하고 해당 버전에 맞는 워크플로 지침을 설치합니다. 네이티브 분석에는 기존 Hopper, Ghidra 또는 IDA 설치를 사용할 수 있습니다. 승인하면 설정 과정에서 Hopper를 설치할 수도 있습니다. 정적 JavaScript 분석에는 네이티브 분석 엔진이 필요하지 않습니다.
|
||||
|
||||
> <strong>[REA 웹사이트](https://rea.tools/ko/)</strong>에서 설정 방법, 그림으로 설명한 가이드, 실제 사례를 확인하세요.
|
||||
> **[REA 웹사이트](https://rea.tools/ko/)**에서 설정 방법, 그림으로 설명한 가이드, 실제 사례를 확인하세요.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
@@ -175,7 +175,7 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
지원하는 네이티브 형식과 호스트는 제공자마다 다릅니다. [Hopper 및 Ghidra 설정](../installation.md#hopper), [IDA 가이드](../ida-provider.md)(선택 사항인 네이티브 MCP 브리지 포함), [Kuna](../kuna-provider.md), [실험적 Windows Ghidra 지원](../windows-ghidra-p0.md)을 참고하세요. Ghidra는 [16비트 DOS 분석](../ghidra-dos.md)도 지원합니다. 큰 바이너리를 분석할 때는 `REA_GHIDRA_STARTUP_TIMEOUT_MS` 또는 `REA_HOPPER_STARTUP_TIMEOUT_MS`로 제공자의 시작 제한 시간을 늘리세요. 제공자 선택은 [CLI 가이드](../cli.md#choose-a-provider)를 참고하세요. 최신 npm 릴리스 이후 추가된 기능은 [릴리스에서의 사용 가능 여부](../installation.md#released-package-and-main)를 확인하세요.
|
||||
지원하는 네이티브 형식과 호스트는 제공자마다 다릅니다. [Hopper 및 Ghidra 설정](../installation.md#hopper), [IDA 가이드](../ida-provider.md)(선택 사항인 네이티브 MCP 브리지 포함), [실험적 Windows Ghidra 지원](../windows-ghidra-p0.md)을 참고하세요. Ghidra는 [16비트 DOS 분석](../ghidra-dos.md)도 지원합니다. 큰 바이너리를 분석할 때는 `REA_GHIDRA_STARTUP_TIMEOUT_MS` 또는 `REA_HOPPER_STARTUP_TIMEOUT_MS`로 제공자의 시작 제한 시간을 늘리세요. 제공자 선택은 [CLI 가이드](../cli.md#choose-a-provider)를 참고하세요. 최신 npm 릴리스 이후 추가된 기능은 [릴리스에서의 사용 가능 여부](../installation.md#released-package-and-main)를 확인하세요.
|
||||
|
||||
## 사례
|
||||
|
||||
@@ -283,7 +283,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## 스타 기록
|
||||
|
||||
🎉 **GitHub 스타 300,000개, 감사합니다!**
|
||||
🎉 **GitHub 스타 200,000개, 감사합니다!**
|
||||
|
||||
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
|
||||
|
||||
@@ -309,10 +309,6 @@ REA에 도움을 보태 주세요! [issue를 등록](https://github.com/morluto/
|
||||
|
||||
개발 환경과 검사 항목은 [CONTRIBUTING.md](../../CONTRIBUTING.md), 검증 절차는 [테스트 가이드](../testing.md), 프로젝트 구조는 [아키텍처 지도](../architecture.mermaid)를 참고하세요.
|
||||
|
||||
한국어 번역도 개선할 수 있습니다. 이 README를 수정할 때는 [영문 README](../../README.md)의 명령어, 요구 사항, 분석 범위와 일치하는지 확인하세요. 웹사이트 번역은 `website/locales/ko/messages.po`의 `msgstr` 값을 수정하세요.
|
||||
|
||||
웹사이트 번역의 수정 방법, 검사 명령, 로컬 미리보기는 `website/locales/README.md`를 따르세요. 위 기여 문서의 **Translation corrections** 절에서 이 가이드로 이동할 수 있습니다. 명령어, 경로, 자리표시자, 기록된 근거는 그대로 보존하세요. `website/_site/`의 한국어 HTML은 자동 생성되므로 직접 수정하지 마세요.
|
||||
|
||||
## 라이선스
|
||||
|
||||
[MIT](../../LICENSE)
|
||||
|
||||
@@ -1,325 +0,0 @@
|
||||
<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](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · **മലയാളം**
|
||||
|
||||
# REA: എന്തും Reverse Engineer ചെയ്യുക
|
||||
|
||||
### Binaries, applications, runtime behavior എന്നിവയുടെ Reverse Engineering-നായി ഒരൊറ്റ MCP.
|
||||
|
||||
**നിങ്ങൾക്ക് ഇഷ്ടപ്പെട്ട ഒരു feature കണ്ടോ? അത് എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്ന് binary തലത്തിലേക്ക് വരെ മനസ്സിലാക്കൂ.**
|
||||
|
||||
[](https://www.npmjs.com/package/rea-agents)
|
||||
[](../mcp-contracts.md#generated-catalog)
|
||||
[](#what-you-can-analyze)
|
||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||
[](../../LICENSE)
|
||||
[](https://discord.gg/GkcryMnJDM)
|
||||
|
||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&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>
|
||||
|
||||
**[വെബ്സൈറ്റ്](https://rea.tools/) · [ഗൈഡുകൾ](https://rea.tools/guides/) · [ഉദാഹരണങ്ങൾ](https://rea.tools/showcase/)**
|
||||
|
||||
[ദ്രുതാരംഭം](#ദ്രുതാരംഭം) · [REA എങ്ങനെ പ്രവർത്തിക്കുന്നു](#rea-എങ്ങനെ-പ്രവർത്തിക്കുന്നു) · [എന്തൊക്കെ വിശകലനം ചെയ്യാം](#എന്തൊക്കെ-വിശകലനം-ചെയ്യാം) · [ഉദാഹരണങ്ങൾ](#ഉദാഹരണങ്ങൾ) · [പതിവുചോദ്യങ്ങൾ](#പതിവുചോദ്യങ്ങൾ) · [ഡോക്യുമെന്റേഷൻ](#ഡോക്യുമെന്റേഷൻ)
|
||||
|
||||
<code>npx rea-agents setup</code>
|
||||
|
||||
</div>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> REA ലഭ്യമാക്കേണ്ടത് [morluto/rea](https://github.com/morluto/rea),
|
||||
> [rea.tools](https://rea.tools/), അല്ലെങ്കിൽ [rea-agents npm package](https://www.npmjs.com/package/rea-agents) എന്നിവയിൽ നിന്നാണ്.
|
||||
> ഈ ഔദ്യോഗിക ഉറവിടങ്ങളിലെ ഇൻസ്റ്റലേഷൻ, റിലീസ് ലിങ്കുകൾ പിന്തുടരുക. സമാനമായ
|
||||
> repository പേരോ പകർത്തിയ README-യോ മാത്രം ഒരു download ഔദ്യോഗികമാണെന്ന് ഉറപ്പാക്കുന്നില്ല.
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<img src="../assets/rea-hopper-analysis.png" alt="ഒരു native binary പരിശോധിക്കുന്നതിനിടെ Hopper-ൽ REA അതിന്റെ analysis bridge ആരംഭിക്കുന്നു" width="1200" />
|
||||
|
||||
<br /><br />
|
||||
|
||||
<table aria-label="REA community">
|
||||
<tr>
|
||||
<td align="center" width="360">
|
||||
<a href="https://discord.gg/GkcryMnJDM">
|
||||
<img src="../assets/discord.svg" height="42" alt="Discord" /><br />
|
||||
<strong>Reverse Engineering കമ്മ്യൂണിറ്റിയിൽ ചേരുക</strong>
|
||||
</a><br />
|
||||
<sub>Discord · ചോദ്യോത്തരങ്ങൾ · അനുഭവങ്ങളും കണ്ടെത്തലുകളും പങ്കിടുക</sub>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
നിങ്ങളുടെ സ്വന്തം product-ൽ ഉൾപ്പെടുത്താൻ ആഗ്രഹിക്കുന്ന ഒരു feature ഏതെങ്കിലും app-ൽ കണ്ടോ? REA ഉപയോഗിച്ച് അത് പരിശോധിക്കാൻ നിങ്ങളുടെ agent-നോട് ആവശ്യപ്പെടുക. source code ഇല്ലാതെയും അതിന് app പരിശോധിക്കാനും feature എങ്ങനെ പ്രവർത്തിക്കുന്നുവെന്ന് വിശദീകരിക്കാനും അതിനുള്ള തെളിവുകൾ കാണിക്കാനും നിങ്ങളുടെ project-നായി അതിന് സമാനമായൊരു പതിപ്പ് നിർമ്മിക്കാനും കഴിയും.
|
||||
|
||||
Native binaries, JavaScript, Electron apps, .NET assemblies, websites എന്നിവ പരിശോധിക്കുന്നതിനുള്ള tools-ലേക്ക് REA നിങ്ങളുടെ agent-നെ ബന്ധിപ്പിക്കുന്നു. ഇതേ tools നിങ്ങളുടെ terminal-ൽ നിന്നും ഉപയോഗിക്കാം. വിശകലനം local ആയി നടക്കുന്നു; ഓരോ നിഗമനത്തിനും പിന്നിലെ തെളിവുകളും പരിമിതികളും ഫലങ്ങളിൽ ഉൾപ്പെടുന്നു.
|
||||
|
||||
Setup നിങ്ങളുടെ agent-ിൽ REA രജിസ്റ്റർ ചെയ്യുകയും അനുയോജ്യമായ workflow നിർദ്ദേശങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്യുകയും ചെയ്യുന്നു. Native analysis-നായി നിലവിലുള്ള Hopper, Ghidra, അല്ലെങ്കിൽ IDA installation ഉപയോഗിക്കാം; അനുമതി നൽകിയാൽ setup-ന് Hopper ഇൻസ്റ്റാൾ ചെയ്യാനും കഴിയും. Static JavaScript analysis-ന് native analysis engine ആവശ്യമില്ല.
|
||||
|
||||
> **[REA വെബ്സൈറ്റ് സന്ദർശിക്കുക](https://rea.tools/)** — setup നിർദ്ദേശങ്ങൾക്കും ചിത്രങ്ങളോടുകൂടിയ ഗൈഡുകൾക്കും യഥാർത്ഥ case study-കൾക്കും.
|
||||
|
||||
## ദ്രുതാരംഭം
|
||||
|
||||
Linux-ൽ Ghidra, JADX, firmware tool launches, static JavaScript/Electron analysis എന്നിവയ്ക്ക് process ownership പരിശോധിക്കാൻ REA-യുടെ `PATH`-ൽ procps-compatible `ps` ആവശ്യമാണ്. പരിഹാര നടപടികൾ `docs/installation.md`-യിലെ "Linux owned-process prerequisite" എന്ന വിഭാഗത്തിൽ ലഭ്യമാണ്.
|
||||
|
||||
### നിങ്ങളുടെ agent സജ്ജമാക്കുക
|
||||
|
||||
Node.js-ഉം npm-ഉം ഇൻസ്റ്റാൾ ചെയ്തശേഷം ഈ command പ്രവർത്തിപ്പിക്കുക:
|
||||
|
||||
```bash
|
||||
npx rea-agents setup
|
||||
```
|
||||
|
||||
നിങ്ങൾ ഉപയോഗിക്കുന്ന agents തിരഞ്ഞെടുക്കുക, നിർദ്ദേശിച്ച മാറ്റങ്ങൾ പരിശോധിക്കുക, തുടർന്ന് അവയ്ക്ക് അനുമതി നൽകുക. നിലവിലുള്ള configuration-ന്റെ backup-ുകൾ സൂക്ഷിച്ചുകൊണ്ട് setup, REA-യുടെ MCP server-ഉം അനുയോജ്യമായ workflow നിർദ്ദേശങ്ങളും ചേർക്കും. അതിനുശേഷം നിങ്ങളുടെ agent വീണ്ടും ആരംഭിക്കുക.
|
||||
|
||||
Claude Code, Codex, Cursor, Gemini CLI, Grok Build, കൂടാതെ [മറ്റ് agents](../installation.md#supported-agents) എന്നിവയെ setup പിന്തുണയ്ക്കുന്നു. provider configuration-നും manual MCP registration-നും [installation and setup](../installation.md) കാണുക.
|
||||
|
||||
### നിങ്ങളുടെ agent-നോട് ആവശ്യപ്പെടുക
|
||||
|
||||
```text
|
||||
Notes app-ൽ search എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്ന് മനസ്സിലാക്കി, അതിനുള്ള തെളിവുകൾ കാണിച്ചുതരികയും എന്റെ project-നായി സമാനമായൊരു feature നിർമ്മിക്കുകയും ചെയ്യുക.
|
||||
```
|
||||
|
||||
`Notes` എന്നതിന് പകരം നിങ്ങൾ പരിശോധിക്കാൻ ആഗ്രഹിക്കുന്ന app-ിന്റെയും മനസ്സിലാക്കേണ്ട feature-ിന്റെയും പേരുകൾ നൽകുക.
|
||||
|
||||
### Terminal ഉപയോഗിക്കുക
|
||||
|
||||
Extract ചെയ്ത JavaScript/Electron app directory അല്ലെങ്കിൽ ASAR പരിശോധിക്കുക:
|
||||
|
||||
```bash
|
||||
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
|
||||
```
|
||||
|
||||
ഫലത്തിൽ modules, imports, Electron boundaries, അവയ്ക്കുള്ള തെളിവുകൾ എന്നിവ ഉൾപ്പെടും. `/absolute/path/to/app` എന്നതിന് പകരം നിങ്ങളുടെ target-ന്റെ path നൽകുക; Windows-ൽ ഉദാഹരണത്തിന് `"D:/apps/example"` ഉപയോഗിക്കാം.
|
||||
|
||||
സാധാരണ ഉപയോഗത്തിനായി `rea` command ഇൻസ്റ്റാൾ ചെയ്യാൻ:
|
||||
|
||||
```bash
|
||||
npm install --global rea-agents
|
||||
rea --help
|
||||
```
|
||||
|
||||
Native analysis നടത്തുന്നതിന് മുമ്പ് ഒരു provider ക്രമീകരിക്കുക. Native commands, provider തിരഞ്ഞെടുക്കൽ, snapshots, scripting എന്നിവയ്ക്കായി [CLI and Evidence guide](../cli.md) കാണുക.
|
||||
|
||||
### REA അപ്ഡേറ്റ് ചെയ്യുക
|
||||
|
||||
REA-യിൽ പതിവായി മാറ്റങ്ങൾ വരുന്നു; പുതിയ releases-ൽ പല bug fixes-ഉം ഉൾപ്പെടുന്നു. നിങ്ങളുടെ installation ഏറ്റവും പുതിയ പതിപ്പിലേക്ക് അപ്ഡേറ്റ് ചെയ്യുക.
|
||||
|
||||
`npm install --global` അല്ലെങ്കിൽ `bun add --global` ഉപയോഗിച്ച് ഇൻസ്റ്റാൾ ചെയ്ത CLI-ക്കായി:
|
||||
|
||||
```bash
|
||||
rea update
|
||||
```
|
||||
|
||||
Bun-ന്റെ global updates-ന് Bun 1.2.17 അല്ലെങ്കിൽ അതിനുശേഷമുള്ള പതിപ്പ് ആവശ്യമാണ്. പഴയ Bun പതിപ്പാണെങ്കിൽ `rea update` പ്രവർത്തിപ്പിക്കുന്നതിന് മുമ്പ് Bun സ്വമേധയാ അപ്ഗ്രേഡ് ചെയ്യുക.
|
||||
|
||||
Agent registrations-ഉം skill-ഉം പുതുക്കാൻ, update കാണിക്കുന്ന setup command പ്രവർത്തിപ്പിക്കുക.
|
||||
|
||||
`npx` ഉപയോഗിക്കുന്നുവെങ്കിൽ, agent setup പുതുക്കാൻ:
|
||||
|
||||
```bash
|
||||
npx rea-agents@latest setup
|
||||
```
|
||||
|
||||
Setup-ൽ വരുത്തുന്ന മാറ്റങ്ങൾ പരിശോധിച്ച് നിങ്ങളുടെ agent വീണ്ടും ആരംഭിക്കുക. ഒറ്റത്തവണ മാത്രം ഉപയോഗിക്കുന്ന CLI commands-നായി command-ന് മുമ്പ് `npx rea-agents@latest` ഉപയോഗിക്കുക. Bun ഉപയോഗിക്കുമ്പോൾ `npx rea-agents@latest`-ന് പകരം `bunx rea-agents@latest` ഉപയോഗിക്കുക.
|
||||
|
||||
## REA എങ്ങനെ പ്രവർത്തിക്കുന്നു
|
||||
|
||||
Target പരിശോധിക്കാനും പ്രസക്തമായ code-ന്റെ പാത പിന്തുടരാനും നിങ്ങളുടെ agent MCP വഴി REA-യെ വിളിക്കുന്നു. REA കണ്ടെത്തലുകളും അവയ്ക്കുള്ള തെളിവുകളും തിരികെ നൽകുന്നു. തുടർന്ന് agent കൂടുതൽ ചോദ്യങ്ങൾ ചോദിക്കാനും പെരുമാറ്റം വിശദീകരിക്കാനും implementation എഴുതുകയും പരിശോധിക്കുകയും ചെയ്യാനും അവ ഉപയോഗിക്കുന്നു. CLI commands-ഉം ഇതേ workflows ഉപയോഗിക്കുന്നു.
|
||||
|
||||

|
||||
|
||||
[പൂർണ്ണ വലുപ്പത്തിലുള്ള ചിത്രം തുറക്കുക](../../website/public/assets/figures/rea-investigation-flow.svg).
|
||||
|
||||
<a id="current-status"></a>
|
||||
|
||||
## എന്തൊക്കെ വിശകലനം ചെയ്യാം
|
||||
|
||||
REA-യ്ക്ക് Node.js 22.x (>=22.19), 24.x (>=24.11), അല്ലെങ്കിൽ 26+ പതിപ്പും npm-ഉം ആവശ്യമാണ്. Target അനുസരിച്ച് അധിക tools-ഉം host support-ഉം വ്യത്യാസപ്പെടും:
|
||||
|
||||
| Target | REA നൽകുന്ന ഫലങ്ങൾ | ആവശ്യകതകളും ഗൈഡും |
|
||||
| ---------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Native binaries | Pseudocode, assembly, strings, symbols, calls, references | Hopper, Ghidra അല്ലെങ്കിൽ IDA; [native analysis](../native-investigation.md) |
|
||||
| Offline ELF layout | Sections, segments, യഥാർത്ഥ symbols/relocations, static mitigation candidates | Linux x64-ൽ caller നൽകുന്ന pwntools; [binary diagnostics](../binary-diagnostics.md) |
|
||||
| Go binaries | ഉൾച്ചേർത്ത compiler version, modules, replacements, build settings | Built-in static ELF/PE/thin Mach-O പരിശോധന; Go installation ആവശ്യമില്ല |
|
||||
| Rust binaries | ഉൾച്ചേർത്ത cargo-auditable crate പേരുകൾ, versions, sources, dependency edges | Built-in static ELF/PE/thin Mach-O പരിശോധന; [Rust binaries](../rust-binaries.md) |
|
||||
| WASM artifact | Validation, sections, കൃത്യമായ import/export WAT രൂപങ്ങൾ, decoded WAT | Caller നൽകുന്ന WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM bytecode | Dispatch selectors, byte offsets, അനുമാനിച്ച arguments, mutability | Linux x64-ൽ local raw/hex carrier; [offline EVM guide](../evm-bytecode.md) |
|
||||
| SQLite databases | Tables, columns, indexes, views, triggers, തിരഞ്ഞെടുത്ത സാധാരണ table rows | Local database/WAL snapshot; native SQLite പരിമിതികളോടെ Node.js 24.x >=24.15 അല്ലെങ്കിൽ 26+ |
|
||||
| Recorded Linux crashes | Raw notes, രേഖപ്പെടുത്തിയ ഓരോ thread-ന്റെയും registers/signals, ഐച്ഛിക mapping candidates | Linux x64-ൽ caller നൽകുന്ന pwntools; ഐച്ഛിക GDB/pwndbg; [recorded crashes](../recorded-crashes.md) |
|
||||
| JavaScript / Electron | Modules, imports, source maps, routes, IPC, native add-on ബന്ധങ്ങൾ | Node.js, npm; Linux: procps-compatible `ps`; [application analysis](../javascript-application-workflows.md) |
|
||||
| Websites | Page structure, scripts, network observations, ആവശ്യപ്പെട്ട screenshots | Chrome-family browser; [browser analysis](../browser-observation.md) |
|
||||
| Saved network captures | Requests, responses, പുറത്തുകാണുന്ന payload-ുകൾ, source locations | HAR അല്ലെങ്കിൽ Fiddler Everywhere SAZ; native mitmproxy-നായി Linux-ൽ mitmdump; [capture guide](../web-network-captures.md) |
|
||||
| .NET assemblies | Metadata, CIL instructions, പ്രഖ്യാപിച്ച native dependencies, build comparisons | ഒന്നും ആവശ്യമില്ല (static മാത്രം); [managed-code guide](../managed-code-analysis.md) |
|
||||
| Android APKs | Manifest declarations, classes, decompiled methods, references | Linux/macOS/Windows x64-ൽ Headless JADX-ഉം full JDK-ഉം; [Android guide](../android-analysis.md) |
|
||||
| Android devices | Devices, packages, processes, logs, dumps, screen captures, APK/file transfers | Caller നൽകുന്ന adb (emulator അല്ലെങ്കിൽ hardware); [ADB guide](../adb-device-analysis.md) |
|
||||
| JEB projects | Engine-backed project units, artifact digests, type/method pseudo-code | MCP സേവനം നൽകുന്ന caller ആരംഭിച്ച JEB client; REA_JEB_MCP_URL ഉപയോഗിച്ച് തിരഞ്ഞെടുക്കുക; [JEB guide](../jeb-analysis.md) |
|
||||
| Android resources | Decoded manifest, string tables, locales, version വിവരങ്ങൾ | Caller നൽകുന്ന Apktool launcher; [resource guide](../apktool-resource-analysis.md) |
|
||||
| Flutter apps | Dart snapshot hash, ഓരോ ABI-യിലെയും library digests, engine build provenance | ഒന്നും ആവശ്യമില്ല (static APK parsing); [Flutter guide](../flutter-analysis.md) |
|
||||
| Firmware | Regions, extraction results, native-analysis handoffs | Linux-ൽ Binwalk / Unblob; [firmware guide](../firmware-analysis.md) |
|
||||
| Recorded packets | തിരഞ്ഞെടുത്ത fields, ആവർത്തിക്കുന്ന values, filters, decode-as rules | Linux: TShark 4.x + prlimit; [capture guide](../packet-captures.md) |
|
||||
| Packet summaries | Endpoints, DNS, TLS SNI, protocol distribution, HTTP requests | Caller നൽകുന്ന tshark, capinfos (Linux-ൽ പരിശോധിച്ചത്); [pcap guide](../pcap-analysis.md) |
|
||||
| Recorded logic signals | Decoder annotations, sample ranges, diagnostics | Linux: sigrok-cli 0.7.2 + prlimit; [signal recordings](../signal-recordings.md) |
|
||||
| Packages and resources | File inventories, digests, plists, Apple bundle ഘടന, extracted resources | [Artifact and JavaScript guide](../javascript-artifact-reconstruction.md), [Apple applications](../apple-application-analysis.md) |
|
||||
| Process behavior | Terminal output, interactions, exit, filesystem observations, run comparisons | Native PTY ഉള്ള Linux/macOS; [process capture](../process-capture.md) |
|
||||
|
||||
Static JavaScript, .NET പരിശോധനകൾ application പ്രവർത്തിപ്പിക്കാതെ നൽകിയ files വായിച്ചാണ് നടത്തുന്നത്. Runtime capture, നിങ്ങളുടെ user permissions ഉപയോഗിച്ച് തിരഞ്ഞെടുത്ത target പ്രവർത്തിപ്പിക്കുകയോ അതുമായി ഇടപെടുകയോ ചെയ്യുന്നു; ഓരോ runtime guide-ലും അതിന്റെ പ്രത്യാഘാതങ്ങൾ വിശദീകരിച്ചിട്ടുണ്ട്.
|
||||
|
||||
Offline native-binary പരിശോധനയ്ക്കായി REA, caller നൽകുന്ന GNU objdump, Rizin എന്നിവയും പിന്തുണയ്ക്കുന്നു. Provider setup, CLI commands, Evidence-ന്റെ പരിമിതികൾ എന്നിവയ്ക്കായി [reverse-engineering tools guide](../reverse-engineering-tools.md) കാണുക. ഈ providers ഒന്നും REA ഇൻസ്റ്റാൾ ചെയ്യുകയോ അപ്ഡേറ്റ് ചെയ്യുകയോ ചെയ്യുന്നില്ല.
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Native formats-ഉം host support-ഉം provider അനുസരിച്ച് വ്യത്യാസപ്പെടും. [Hopper and Ghidra setup](../installation.md#hopper), [IDA guide](../ida-provider.md) (ഐച്ഛിക native MCP bridge ഉൾപ്പെടെ), [Kuna decompiler guide](../kuna-provider.md), [പരീക്ഷണഘട്ടത്തിലുള്ള Windows Ghidra support](../windows-ghidra-p0.md) എന്നിവ കാണുക.
|
||||
Ghidra, [16-bit DOS analysis](../ghidra-dos.md)-ഉം പിന്തുണയ്ക്കുന്നു.
|
||||
വലിയ binaries-നായി `REA_GHIDRA_STARTUP_TIMEOUT_MS` അല്ലെങ്കിൽ `REA_HOPPER_STARTUP_TIMEOUT_MS` ഉപയോഗിച്ച് provider-ന്റെ startup deadline വർധിപ്പിക്കുക.
|
||||
Provider തിരഞ്ഞെടുക്കാൻ [CLI guide](../cli.md#choose-a-provider) കാണുക.
|
||||
ഏറ്റവും പുതിയ npm release-നുശേഷം ചേർത്ത features അറിയാൻ [release availability](../installation.md#released-package-and-main) പരിശോധിക്കുക.
|
||||
|
||||
## ഉദാഹരണങ്ങൾ
|
||||
|
||||
[](https://rea.tools/showcase/)
|
||||
|
||||
### DX-Ball: sound-pan കണക്കുകൂട്ടൽ പുനർനിർമ്മിക്കുക
|
||||
|
||||
ഒരു sound call-നെ അതിന്റെ position-to-pan helper വരെ പിന്തുടരുക, instructions പരിശോധിക്കുക, അപൂർണ്ണമായ pseudocode-നെ C-യാക്കി മാറ്റുക. ഈ പുനർനിർമ്മാണം യഥാർത്ഥ x86-ലെ 3,205 test cases വിജയിക്കുകയും compile ചെയ്ത function-ന്റെ 63 bytes-ഉം അതേപടി പുനരുത്പാദിപ്പിക്കുകയും ചെയ്യുന്നു.
|
||||
|
||||
[Case study വായിക്കുക](https://rea.tools/showcase/dx-ball/) ·
|
||||
[പുനർനിർമ്മാണ repository](https://github.com/N0zoM1z0/dx-ball)
|
||||
|
||||
### Notion: Electron clipboard bridge പിന്തുടരുക
|
||||
|
||||
Renderer-ന്റെ clipboard API കണ്ടെത്തി, അതിനെ preload-ഉം IPC-ഉം വഴി main process വരെ പിന്തുടർന്ന് rich clipboard format പരിശോധിക്കുക.
|
||||
|
||||
[Case study വായിക്കുക](https://rea.tools/showcase/notion/)
|
||||
|
||||
### TH04: DOS bullet-ring കണക്കുകൂട്ടൽ വീണ്ടെടുക്കുക
|
||||
|
||||
യഥാർത്ഥ PC-98 game-ന്റെ 16-bit instructions പരിശോധിക്കുക, fixed, aimed angle കണക്കുകൂട്ടലുകൾ വീണ്ടെടുക്കുക, പുനർനിർമ്മിച്ച C++-നെ ചരിത്രപരമായ compiler output-ുമായി താരതമ്യം ചെയ്യുക.
|
||||
|
||||
[Case study വായിക്കുക](https://rea.tools/showcase/th04/) ·
|
||||
[പുനർനിർമ്മാണ repository](https://github.com/N0zoM1z0/th04)
|
||||
|
||||
REA ഉപയോഗിച്ച് നിങ്ങൾ രസകരമായ എന്തെങ്കിലും പരിശോധിച്ചിട്ടുണ്ടെങ്കിൽ അത് കാണാൻ ഞങ്ങൾ ആഗ്രഹിക്കുന്നു. പരിശോധിച്ച target, നിങ്ങളുടെ ചോദ്യം, REA എങ്ങനെ സഹായിച്ചു, നിങ്ങൾ കണ്ടെത്തിയത് എന്നിവ ഉൾപ്പെടുത്തി [issue](https://github.com/morluto/rea/issues) അല്ലെങ്കിൽ [pull request](https://github.com/morluto/rea/pulls) വഴി നിങ്ങളുടെ case പങ്കിടുക.
|
||||
|
||||
## പതിവുചോദ്യങ്ങൾ
|
||||
|
||||
<details>
|
||||
<summary><strong>ഏതൊക്കെ agents-ന് REA ഉപയോഗിക്കാം?</strong></summary>
|
||||
|
||||
Local MCP servers പിന്തുണയ്ക്കുന്ന ഏത് agent-നും REA ഉപയോഗിക്കാം. Setup, [പിന്തുണയ്ക്കുന്ന agents](../installation.md#supported-agents) ക്രമീകരിക്കുന്നു; മറ്റ് clients-ന് [manual MCP registration](../installation.md#mcp-registry) ഉപയോഗിക്കാം.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Hopper, Ghidra അല്ലെങ്കിൽ IDA ആവശ്യമാണോ?</strong></summary>
|
||||
|
||||
ആഴത്തിലുള്ള native analysis-ന് ഇവയിൽ ഒന്ന് ആവശ്യമാണ്. Static JavaScript, .NET പരിശോധനകൾ native analysis engine ഇല്ലാതെയും പ്രവർത്തിക്കും. അനുമതി ലഭിച്ചാൽ setup-ന് Hopper ഇൻസ്റ്റാൾ ചെയ്യാം; Ghidra, IDA എന്നിവയ്ക്കായി നിങ്ങളുടെ നിലവിലുള്ള installations ഉപയോഗിക്കുന്നു. [Provider setup](../installation.md#hopper) കാണുക.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Hopper ആദ്യം ആരംഭിക്കേണ്ടതുണ്ടോ?</strong></summary>
|
||||
|
||||
ഒരു operation-ന് ആവശ്യമാകുമ്പോൾ REA Hopper ആരംഭിക്കും. macOS-ൽ ആദ്യമായി പ്രവർത്തിപ്പിക്കുമ്പോൾ demo mode തിരഞ്ഞെടുക്കാനോ license activate ചെയ്യാനോ ആവശ്യപ്പെടുന്ന dialog പ്രത്യക്ഷപ്പെടാം. ആദ്യ CLI/MCP operation അല്ലെങ്കിൽ unattended job നടത്തുന്നതിന് മുമ്പ് അതേ user session-ൽ ആ prompt പൂർത്തിയാക്കുക. ആവശ്യമെങ്കിൽ Hopper സ്വമേധയാ തുറക്കുക. [Hopper startup and troubleshooting](../installation.md#launcher-paths-and-troubleshooting) കാണുക.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>skills.sh-ൽ നിന്ന് skill ഇൻസ്റ്റാൾ ചെയ്യുന്നത് എന്താണ് ചെയ്യുന്നത്?</strong></summary>
|
||||
|
||||
ഈ skill നിങ്ങളുടെ agent-ന് അന്വേഷണ നിർദ്ദേശങ്ങൾ നൽകുന്നു. REA-യുടെ MCP server രജിസ്റ്റർ ചെയ്യാനും അനുയോജ്യമായ നിർദ്ദേശങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്യാനും `npx rea-agents setup` ഉപയോഗിക്കുക; തുടർന്ന് നിങ്ങളുടെ agent വീണ്ടും ആരംഭിക്കുക. [Skill-only installation](../installation.md#skill-only-installation) കാണുക.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>REA ഏത് തരത്തിലുള്ള code ആണ് നൽകുന്നത്?</strong></summary>
|
||||
|
||||
Native analysis pseudocode-ഉം assembly-ഉം നൽകുന്നു. JavaScript/Electron analysis modules-ഉം അവയുടെ ബന്ധങ്ങളും വീണ്ടെടുക്കുന്നു. ഈ കണ്ടെത്തലുകൾ ഉപയോഗിച്ച് നിങ്ങളുടെ agent implementation എഴുതുകയും പരിശോധിക്കുകയും ചെയ്യും; പ്രായോഗിക ഉദാഹരണങ്ങൾക്കായി [ഉദാഹരണങ്ങൾ](#showcases) കാണുക.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>REA എന്റെ app upload ചെയ്യുമോ?</strong></summary>
|
||||
|
||||
REA targets local ആയി വിശകലനം ചെയ്യുന്നു. Tool-ൽ നിന്നുള്ള ഫലങ്ങൾ നിങ്ങളുടെ agent-ന് ലഭിക്കും; അതിന്റെ model provider-ന് സ്വന്തമായ data policy ഉണ്ടായിരിക്കും.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>ഒരു bug നേരിട്ടാൽ എന്തുചെയ്യണം?</strong></summary>
|
||||
|
||||
ആദ്യം അപ്ഡേറ്റ് ചെയ്യുക; പുതിയ release-ൽ ആ പ്രശ്നത്തിനുള്ള പരിഹാരം ഇതിനകം ഉണ്ടായേക്കാം.
|
||||
|
||||
`npm install --global` അല്ലെങ്കിൽ `bun add --global` ഉപയോഗിച്ച് ഇൻസ്റ്റാൾ ചെയ്ത CLI-ക്കായി:
|
||||
|
||||
```bash
|
||||
rea update
|
||||
```
|
||||
|
||||
`npx` വഴി agent setup നടത്തുന്നതിനായി:
|
||||
|
||||
```bash
|
||||
npx rea-agents@latest setup
|
||||
```
|
||||
|
||||
നിങ്ങൾ agent ഉപയോഗിക്കുന്നുണ്ടെങ്കിൽ, [setup പുതുക്കൽ](#update-rea) പൂർത്തിയാക്കി അത് വീണ്ടും ആരംഭിക്കുക. അതേ task വീണ്ടും ശ്രമിക്കുക. പ്രശ്നം തുടരുകയാണെങ്കിൽ, നിങ്ങളുടെ REA version, target type, പ്രശ്നം ആവർത്തിക്കാൻ ആവശ്യമായ ഘട്ടങ്ങൾ, error output എന്നിവ ഉൾപ്പെടുത്തി [issue തുറക്കുക](https://github.com/morluto/rea/issues).
|
||||
|
||||
</details>
|
||||
|
||||
## ഡോക്യുമെന്റേഷൻ
|
||||
|
||||
വെബ്സൈറ്റിലെ [പ്രായോഗിക ഗൈഡുകൾ](https://rea.tools/guides/) ഉപയോഗിച്ച് തുടങ്ങുക.
|
||||
കൃത്യമായ options, prerequisites, result contracts എന്നിവയ്ക്കായി:
|
||||
|
||||
- [Installation and setup](../installation.md): agent registration, provider configuration, updates, uninstall.
|
||||
- [Readiness and troubleshooting](../installation.md#check-readiness-for-your-task): ഒരു agent-ന്റെയോ analysis engine-ന്റെയോ പ്രശ്നങ്ങൾ കണ്ടെത്തുക.
|
||||
- [CLI and Evidence](../cli.md): commands, provider തിരഞ്ഞെടുക്കൽ, snapshots, import/export, exit statuses.
|
||||
- [MCP contracts](../mcp-contracts.md), [agent prompts](../mcp-prompts.md): tool results, sessions, guided investigations.
|
||||
- [Tool catalog](../mcp-contracts.md#generated-catalog): tools, providers, CLI commands എന്നിവയുടെ സ്വയമേവ സൃഷ്ടിച്ച പട്ടിക.
|
||||
- [Roadmap](../roadmap.md): ആസൂത്രണം ചെയ്ത പ്രവർത്തനങ്ങളും capability trackers-ഉം.
|
||||
|
||||
സുരക്ഷാ ദുർബലതകൾ [SECURITY.md](../../SECURITY.md) വഴി റിപ്പോർട്ട് ചെയ്യുക.
|
||||
|
||||
## Star ചരിത്രം
|
||||
|
||||
🎉 **250,000 GitHub stars — നന്ദി!**
|
||||
|
||||
REA ഉപയോഗിക്കുന്നവർക്കും, bugs റിപ്പോർട്ട് ചെയ്യുന്നവർക്കും, features ആവശ്യപ്പെടുന്നവർക്കും, builds പരിശോധിക്കുന്നവർക്കും, fixes സംഭാവന ചെയ്യുന്നവർക്കും നന്ദി.
|
||||
|
||||
<a href="https://www.star-history.com/?repos=morluto%2Frea&type=date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&type=date&theme=dark&legend=top-left" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&type=date" />
|
||||
<img alt="REA GitHub star ചരിത്രം" src="https://api.star-history.com/chart?repos=morluto/rea&type=date" />
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
## നിരാകരണം
|
||||
|
||||
ഉത്തരവാദിത്തത്തോടെ ഉപയോഗിക്കുന്നതിനുള്ള മാർഗനിർദ്ദേശങ്ങൾക്ക് [DISCLAIMER.md](../../DISCLAIMER.md) കാണുക.
|
||||
|
||||
നിയമവിരുദ്ധമോ അനുമതിയില്ലാത്തതോ ആയ ഉപയോഗത്തെക്കുറിച്ചുള്ള project-ന്റെ നിലപാട് എല്ലാ REA versions-നും distribution channels-നും platforms-നും ബാധകമാണ്; ഓരോ copy-യും അതിന് ബാധകമായ licenses നിലനിർത്തുന്നു.
|
||||
|
||||
നിയമാനുസൃതമായ research, education, interoperability, software preservation, കൂടാതെ നിങ്ങൾക്ക് സ്വന്തമായതോ പരിശോധിക്കാൻ അനുമതിയുള്ളതോ ആയ software-ന്റെ analysis എന്നിവയ്ക്കാണ് REA ഉദ്ദേശിച്ചിരിക്കുന്നത്.
|
||||
|
||||
## സംഭാവനകൾ
|
||||
|
||||
REA-യ്ക്കായി നിങ്ങളുടെ സഹായം ഞങ്ങൾ സ്വാഗതം ചെയ്യുന്നു! bug റിപ്പോർട്ട് ചെയ്യാനോ feature നിർദ്ദേശിക്കാനോ [issue തുറക്കുക](https://github.com/morluto/rea/issues), code അല്ലെങ്കിൽ docs മെച്ചപ്പെടുത്താൻ [pull request അയയ്ക്കുക](https://github.com/morluto/rea/pulls).
|
||||
|
||||
Development setup-നും checks-നും [CONTRIBUTING.md](../../CONTRIBUTING.md), verification lanes-നായി [testing](../testing.md), project ഘടനയ്ക്കായി [architecture map](../architecture.mermaid) എന്നിവ കാണുക.
|
||||
|
||||
## ലൈസൻസ്
|
||||
|
||||
[MIT](../../LICENSE)
|
||||
|
||||
REA-യുടെ രചയിതാക്കൾ സൃഷ്ടിച്ച code MIT license പ്രകാരമാണ് ലൈസൻസ് ചെയ്തിരിക്കുന്നത്. Third-party material അതിന്റെ സ്വന്തം licenses-ഉം copyright notices-ഉം നിലനിർത്തുന്നു; dependencies-ന്റെ പട്ടിക, നിലനിർത്തിയ license text-ുകൾ, external tool നിബന്ധനകൾ എന്നിവയ്ക്കായി [Third-party notices](../../THIRD_PARTY_NOTICES.md) കാണുക.
|
||||
|
||||
**IDA Pro / Hex-Rays decompilers, Hopper, JEB എന്നിവ ഉൾപ്പെടെയുള്ള commercial tools നിയമാനുസൃതമായി സ്വന്തമാക്കുകയും അവയുടെ ബാധകമായ licenses പ്രകാരം ഉപയോഗിക്കാൻ അനുമതിയുണ്ടെന്ന് ഉറപ്പാക്കുകയും വേണം.** REA ഒരു tool license-ഓ key-യോ activation entitlement-ഓ നൽകുന്നില്ല. Trials-ഉം demos-ഉം ഉൾപ്പെടെ vendor നിബന്ധനകൾക്ക് വിധേയമാണ്; ഇതിൽ user, feature, automation, output sharing നിയന്ത്രണങ്ങളും ഉൾപ്പെടാം. Cracked copies, മോഷ്ടിച്ച keys, അനുമതിയില്ലാത്ത key sharing, license നിയന്ത്രണങ്ങൾ മറികടക്കൽ എന്നിവയ്ക്ക് അനുമതിയില്ല. ഈ മാർഗനിർദ്ദേശം MIT അല്ലെങ്കിൽ third-party licenses-ൽ മാറ്റം വരുത്തുന്നില്ല.
|
||||
@@ -1,7 +1,7 @@
|
||||
<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** · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -166,7 +166,7 @@ Statyczna analiza JavaScript i .NET odczytuje dostarczone pliki bez uruchamiania
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Obsługiwane formaty natywne i platformy zależą od dostawcy analizy. Zobacz [konfigurację Hoppera i Ghidry](../installation.md#hopper), [przewodnik IDA](../ida-provider.md), [Kuna](../kuna-provider.md) oraz [eksperymentalną obsługę Ghidry w systemie Windows](../windows-ghidra-p0.md). Ghidra obsługuje też [analizę 16-bitowego DOS-a](../ghidra-dos.md). Wybór dostawcy opisuje [przewodnik CLI](../cli.md#choose-a-provider). Sprawdź [dostępność w wydaniach](../installation.md#released-package-and-main) dla funkcji dodanych po najnowszym wydaniu npm.
|
||||
Obsługiwane formaty natywne i platformy zależą od dostawcy analizy. Zobacz [konfigurację Hoppera i Ghidry](../installation.md#hopper), [przewodnik IDA](../ida-provider.md) oraz [eksperymentalną obsługę Ghidry w systemie Windows](../windows-ghidra-p0.md). Ghidra obsługuje też [analizę 16-bitowego DOS-a](../ghidra-dos.md). Wybór dostawcy opisuje [przewodnik CLI](../cli.md#choose-a-provider). Sprawdź [dostępność w wydaniach](../installation.md#released-package-and-main) dla funkcji dodanych po najnowszym wydaniu npm.
|
||||
|
||||
## Przykłady zastosowań
|
||||
|
||||
@@ -272,7 +272,7 @@ Zgłaszaj podatności zgodnie z [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Historia gwiazdek
|
||||
|
||||
🎉 **300 000 gwiazdek na GitHubie — dziękujemy!**
|
||||
🎉 **200 000 gwiazdek na GitHubie — dziękujemy!**
|
||||
|
||||
Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują nowe funkcje, testują kompilacje i przesyłają poprawki.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Faça engenharia reversa de qualquer coisa
|
||||
|
||||
@@ -166,7 +166,7 @@ A inspeção estática de JavaScript e .NET lê os arquivos fornecidos sem execu
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Os formatos nativos e os sistemas anfitriões compatíveis variam por provedor. Consulte [configuração do Hopper e Ghidra](../installation.md#hopper), o [guia do IDA](../ida-provider.md), [Kuna](../kuna-provider.md) e o [suporte experimental ao Ghidra no Windows](../windows-ghidra-p0.md). O Ghidra também oferece [análise de DOS de 16 bits](../ghidra-dos.md). Para selecionar um provedor, consulte o [guia da CLI](../cli.md#choose-a-provider). Verifique a [disponibilidade nas versões](../installation.md#released-package-and-main) das funcionalidades adicionadas após a versão mais recente no npm.
|
||||
Os formatos nativos e os sistemas anfitriões compatíveis variam por provedor. Consulte [configuração do Hopper e Ghidra](../installation.md#hopper), o [guia do IDA](../ida-provider.md) e o [suporte experimental ao Ghidra no Windows](../windows-ghidra-p0.md). O Ghidra também oferece [análise de DOS de 16 bits](../ghidra-dos.md). Para selecionar um provedor, consulte o [guia da CLI](../cli.md#choose-a-provider). Verifique a [disponibilidade nas versões](../installation.md#released-package-and-main) das funcionalidades adicionadas após a versão mais recente no npm.
|
||||
|
||||
## Casos de uso
|
||||
|
||||
@@ -272,7 +272,7 @@ Relate vulnerabilidades conforme [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Histórico de estrelas
|
||||
|
||||
🎉 **300.000 estrelas no GitHub — muito obrigado!**
|
||||
🎉 **200.000 estrelas no GitHub — muito obrigado!**
|
||||
|
||||
Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam builds e contribuem com correções.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Реверс-инжиниринг чего угодно
|
||||
|
||||
@@ -166,7 +166,7 @@ REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а так
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Нативные форматы и поддерживаемые системы различаются у разных провайдеров. См. [настройку Hopper и Ghidra](../installation.md#hopper), [руководство по IDA](../ida-provider.md), [Kuna](../kuna-provider.md) и [экспериментальную поддержку Ghidra в Windows](../windows-ghidra-p0.md). Ghidra также поддерживает [анализ 16-битного DOS](../ghidra-dos.md). Выбор провайдера описан в [руководстве по CLI](../cli.md#choose-a-provider). Для функций, добавленных после последней версии в npm, проверьте [доступность в релизах](../installation.md#released-package-and-main).
|
||||
Нативные форматы и поддерживаемые системы различаются у разных провайдеров. См. [настройку Hopper и Ghidra](../installation.md#hopper), [руководство по IDA](../ida-provider.md) и [экспериментальную поддержку Ghidra в Windows](../windows-ghidra-p0.md). Ghidra также поддерживает [анализ 16-битного DOS](../ghidra-dos.md). Выбор провайдера описан в [руководстве по CLI](../cli.md#choose-a-provider). Для функций, добавленных после последней версии в npm, проверьте [доступность в релизах](../installation.md#released-package-and-main).
|
||||
|
||||
## Примеры
|
||||
|
||||
@@ -272,7 +272,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## История звёзд
|
||||
|
||||
🎉 **300 000 звёзд на GitHub — спасибо!**
|
||||
🎉 **200 000 звёзд на GitHub — спасибо!**
|
||||
|
||||
Спасибо всем, кто использует REA, сообщает об ошибках, предлагает новые функции, тестирует сборки и помогает с исправлениями.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -166,7 +166,7 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
รูปแบบไบนารีเนทีฟและแพลตฟอร์มที่รองรับแตกต่างกันตามผู้ให้บริการวิเคราะห์ ดู[การตั้งค่า Hopper และ Ghidra](../installation.md#hopper), [คู่มือ IDA](../ida-provider.md) [Kuna](../kuna-provider.md) และ[การรองรับ Ghidra บน Windows แบบทดลอง](../windows-ghidra-p0.md) Ghidra ยังรองรับ[การวิเคราะห์ DOS แบบ 16 บิต](../ghidra-dos.md) สำหรับการเลือกผู้ให้บริการ ดู[คู่มือ CLI](../cli.md#choose-a-provider) ตรวจสอบ[ความพร้อมใช้งานในแต่ละรุ่น](../installation.md#released-package-and-main) สำหรับฟีเจอร์ที่เพิ่มหลังรุ่นล่าสุดบน npm
|
||||
รูปแบบไบนารีเนทีฟและแพลตฟอร์มที่รองรับแตกต่างกันตามผู้ให้บริการวิเคราะห์ ดู[การตั้งค่า Hopper และ Ghidra](../installation.md#hopper), [คู่มือ IDA](../ida-provider.md) และ[การรองรับ Ghidra บน Windows แบบทดลอง](../windows-ghidra-p0.md) Ghidra ยังรองรับ[การวิเคราะห์ DOS แบบ 16 บิต](../ghidra-dos.md) สำหรับการเลือกผู้ให้บริการ ดู[คู่มือ CLI](../cli.md#choose-a-provider) ตรวจสอบ[ความพร้อมใช้งานในแต่ละรุ่น](../installation.md#released-package-and-main) สำหรับฟีเจอร์ที่เพิ่มหลังรุ่นล่าสุดบน npm
|
||||
|
||||
## ตัวอย่างการใช้งาน
|
||||
|
||||
@@ -272,7 +272,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## ประวัติดาว
|
||||
|
||||
🎉 **300,000 ดาวบน GitHub — ขอบคุณทุกคน!**
|
||||
🎉 **200,000 ดาวบน GitHub — ขอบคุณทุกคน!**
|
||||
|
||||
ขอบคุณทุกคนที่ใช้ REA รายงานบั๊ก เสนอฟีเจอร์ ทดสอบบิลด์ และช่วยแก้ไข
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Her şeyi tersine mühendislikle inceleyin
|
||||
|
||||
@@ -171,7 +171,7 @@ Statik JavaScript ve .NET incelemesi, uygulamayı çalıştırmadan sağlanan do
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Yerel makine kodu içeren ikili dosya biçimleri ve ana bilgisayar desteği sağlayıcıya göre değişir. [Hopper ve Ghidra kurulumu](../installation.md#hopper), isteğe bağlı native MCP bridge'i de açıklayan [IDA rehberi](../ida-provider.md), [Kuna](../kuna-provider.md) ve [Windows için deneysel Ghidra desteği](../windows-ghidra-p0.md) belgelerine bakın. Ghidra ayrıca [16 bit DOS analizini](../ghidra-dos.md) destekler. Büyük ikili dosyalar için sağlayıcının başlatma zaman aşımını `REA_GHIDRA_STARTUP_TIMEOUT_MS` veya `REA_HOPPER_STARTUP_TIMEOUT_MS` ile artırın. Sağlayıcı seçimi için [CLI rehberine](../cli.md#choose-a-provider) bakın. En son npm sürümünden sonra eklenen özellikler için [sürümlerde kullanılabilirliği](../installation.md#released-package-and-main) kontrol edin.
|
||||
Yerel makine kodu içeren ikili dosya biçimleri ve ana bilgisayar desteği sağlayıcıya göre değişir. [Hopper ve Ghidra kurulumu](../installation.md#hopper), isteğe bağlı native MCP bridge'i de açıklayan [IDA rehberi](../ida-provider.md) ve [Windows için deneysel Ghidra desteği](../windows-ghidra-p0.md) belgelerine bakın. Ghidra ayrıca [16 bit DOS analizini](../ghidra-dos.md) destekler. Büyük ikili dosyalar için sağlayıcının başlatma zaman aşımını `REA_GHIDRA_STARTUP_TIMEOUT_MS` veya `REA_HOPPER_STARTUP_TIMEOUT_MS` ile artırın. Sağlayıcı seçimi için [CLI rehberine](../cli.md#choose-a-provider) bakın. En son npm sürümünden sonra eklenen özellikler için [sürümlerde kullanılabilirliği](../installation.md#released-package-and-main) kontrol edin.
|
||||
|
||||
## Örnek çalışmalar
|
||||
|
||||
@@ -277,7 +277,7 @@ Güvenlik açıklarını [SECURITY.md](../../SECURITY.md) üzerinden bildirin.
|
||||
|
||||
## Yıldız geçmişi
|
||||
|
||||
🎉 **GitHub'da 300.000 yıldız — teşekkürler!**
|
||||
🎉 **GitHub'da 200.000 yıldız — teşekkürler!**
|
||||
|
||||
REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve düzeltmelere katkıda bulunan herkese teşekkürler.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · **Українська** · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Реверс-інжиніринг будь-чого
|
||||
|
||||
@@ -166,7 +166,7 @@ REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а та
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Нативні формати й підтримка систем відрізняються залежно від провайдера. Дивіться [налаштування Hopper і Ghidra](../installation.md#hopper), [посібник IDA](../ida-provider.md), [Kuna](../kuna-provider.md) та [експериментальну підтримку Ghidra у Windows](../windows-ghidra-p0.md). Ghidra також підтримує [аналіз 16-бітного DOS](../ghidra-dos.md). Для вибору провайдера дивіться [посібник CLI](../cli.md#choose-a-provider). Для функцій, доданих після найновішої версії в npm, перевірте [доступність у випусках](../installation.md#released-package-and-main).
|
||||
Нативні формати й підтримка систем відрізняються залежно від провайдера. Дивіться [налаштування Hopper і Ghidra](../installation.md#hopper), [посібник IDA](../ida-provider.md) та [експериментальну підтримку Ghidra у Windows](../windows-ghidra-p0.md). Ghidra також підтримує [аналіз 16-бітного DOS](../ghidra-dos.md). Для вибору провайдера дивіться [посібник CLI](../cli.md#choose-a-provider). Для функцій, доданих після найновішої версії в npm, перевірте [доступність у випусках](../installation.md#released-package-and-main).
|
||||
|
||||
## Приклади
|
||||
|
||||
@@ -272,7 +272,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## Історія зірок
|
||||
|
||||
🎉 **300 000 зірок на GitHub — дякуємо!**
|
||||
🎉 **200 000 зірок на GitHub — дякуємо!**
|
||||
|
||||
Дякуємо всім, хто використовує REA, повідомляє про помилки, пропонує нові функції, тестує збірки й допомагає з виправленнями.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA: Kỹ thuật dịch ngược cho mọi thứ
|
||||
|
||||
@@ -166,7 +166,7 @@ Kiểm tra tĩnh JavaScript và .NET đọc các tệp được cung cấp mà k
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Định dạng mã máy và nền tảng chạy REA được hỗ trợ khác nhau tùy trình phân tích. Xem [thiết lập Hopper và Ghidra](../installation.md#hopper), [hướng dẫn IDA](../ida-provider.md), [Kuna](../kuna-provider.md) và [hỗ trợ Ghidra thử nghiệm trên Windows](../windows-ghidra-p0.md). Ghidra cũng hỗ trợ [phân tích DOS 16 bit](../ghidra-dos.md). Để chọn trình phân tích, xem [hướng dẫn CLI](../cli.md#choose-a-provider). Kiểm tra [khả năng sử dụng theo bản phát hành](../installation.md#released-package-and-main) đối với tính năng được bổ sung sau phiên bản npm mới nhất.
|
||||
Định dạng mã máy và nền tảng chạy REA được hỗ trợ khác nhau tùy trình phân tích. Xem [thiết lập Hopper và Ghidra](../installation.md#hopper), [hướng dẫn IDA](../ida-provider.md) và [hỗ trợ Ghidra thử nghiệm trên Windows](../windows-ghidra-p0.md). Ghidra cũng hỗ trợ [phân tích DOS 16 bit](../ghidra-dos.md). Để chọn trình phân tích, xem [hướng dẫn CLI](../cli.md#choose-a-provider). Kiểm tra [khả năng sử dụng theo bản phát hành](../installation.md#released-package-and-main) đối với tính năng được bổ sung sau phiên bản npm mới nhất.
|
||||
|
||||
## Các nghiên cứu điển hình
|
||||
|
||||
@@ -272,7 +272,7 @@ Báo cáo lỗ hổng theo [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## Lịch sử sao
|
||||
|
||||
🎉 **300.000 sao trên GitHub — xin cảm ơn!**
|
||||
🎉 **200.000 sao trên GitHub — xin cảm ơn!**
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA:逆向一切
|
||||
|
||||
@@ -170,7 +170,7 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
不同提供者支援的原生格式和主機系統有所不同。請參閱 [Hopper 與 Ghidra 設定](../installation.md#hopper)、[IDA 指南](../ida-provider.md)、[Kuna](../kuna-provider.md)和[實驗性 Windows Ghidra 支援](../windows-ghidra-p0.md)。Ghidra 也支援 [16 位 DOS 分析](../ghidra-dos.md)。提供者選擇見 [CLI 指南](../cli.md#choose-a-provider)。對於最新 npm 版本發佈後新增的功能,請查看[發佈可用性](../installation.md#released-package-and-main)。
|
||||
不同提供者支援的原生格式和主機系統有所不同。請參閱 [Hopper 與 Ghidra 設定](../installation.md#hopper)、[IDA 指南](../ida-provider.md)和[實驗性 Windows Ghidra 支援](../windows-ghidra-p0.md)。Ghidra 也支援 [16 位 DOS 分析](../ghidra-dos.md)。提供者選擇見 [CLI 指南](../cli.md#choose-a-provider)。對於最新 npm 版本發佈後新增的功能,請查看[發佈可用性](../installation.md#released-package-and-main)。
|
||||
|
||||
## 案例
|
||||
|
||||
@@ -278,7 +278,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## Star 歷史
|
||||
|
||||
🎉 **GitHub Star 達到 300,000 個,感謝大家!**
|
||||
🎉 **GitHub Star 達到 200,000 個,感謝大家!**
|
||||
|
||||
感謝每一位使用 REA、報告錯誤、提出功能需求、測試建置和貢獻修復的朋友。
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<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) · [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)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
|
||||
· [Ελληνικά](README_el.md)
|
||||
|
||||
# REA:逆向一切
|
||||
|
||||
@@ -170,7 +170,7 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
不同提供方支持的原生格式和主机系统有所不同。请参阅 [Hopper 与 Ghidra 设置](../installation.md#hopper)、[IDA 指南](../ida-provider.md)、[Kuna](../kuna-provider.md)和[实验性 Windows Ghidra 支持](../windows-ghidra-p0.md)。Ghidra 也支持 [16 位 DOS 分析](../ghidra-dos.md)。提供方选择见 [CLI 指南](../cli.md#choose-a-provider)。对于最新 npm 版本发布后新增的功能,请查看[发布可用性](../installation.md#released-package-and-main)。
|
||||
不同提供方支持的原生格式和主机系统有所不同。请参阅 [Hopper 与 Ghidra 设置](../installation.md#hopper)、[IDA 指南](../ida-provider.md)和[实验性 Windows Ghidra 支持](../windows-ghidra-p0.md)。Ghidra 也支持 [16 位 DOS 分析](../ghidra-dos.md)。提供方选择见 [CLI 指南](../cli.md#choose-a-provider)。对于最新 npm 版本发布后新增的功能,请查看[发布可用性](../installation.md#released-package-and-main)。
|
||||
|
||||
## 案例
|
||||
|
||||
@@ -278,7 +278,7 @@ npx rea-agents@latest setup
|
||||
|
||||
## Star 历史
|
||||
|
||||
🎉 **GitHub Star 达到 300,000 个,感谢大家!**
|
||||
🎉 **GitHub Star 达到 200,000 个,感谢大家!**
|
||||
|
||||
感谢每一位使用 REA、报告错误、提出功能需求、测试构建和贡献修复的朋友。
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# Reconstruction coverage
|
||||
|
||||
`rea evaluate-reconstruction-coverage coverage.json --json` evaluates an inline
|
||||
coverage workspace and its selected `boundary_id`. MCP exposes the same input
|
||||
through `evaluate_reconstruction_coverage`. Results contain a status, reasons,
|
||||
recommended probes and Evidence references; the supplied bundle retains the
|
||||
complete records.
|
||||
|
||||
Evidence IDs and bundle manifests must authenticate before evaluation. A valid
|
||||
record can still be insufficient proof: a passing verifier summary cannot
|
||||
promote inferred Evidence into a replay observation. That case returns
|
||||
`unknown`, while a missing or tampered record remains an input error.
|
||||
|
||||
## Comparable verifier Evidence
|
||||
|
||||
At least one record explicitly cited by the latest verifier observation must
|
||||
support the declared contract authority:
|
||||
|
||||
| Contract authority | Evidence source | Confidence |
|
||||
| ------------------- | ----------------------------------------- | ----------------------- |
|
||||
| `shipped-artifact` | `shipped-artifact` | `observed` or `derived` |
|
||||
| `controlled-replay` | `controlled-replay` | `observed` |
|
||||
| `live-observation` | `controlled-replay` or `external-service` | `observed` |
|
||||
| `external` | `external-service` | `observed` |
|
||||
|
||||
Contextual references can accompany qualifying proof. An unrelated observed
|
||||
record elsewhere in the bundle cannot repair a result that cites only
|
||||
inference. Older observed results cannot replace the newest weak result.
|
||||
Equivalent observations at the same instant can share qualifying proof from
|
||||
one of those observations; conflicting tied assessments remain unknown.
|
||||
|
||||
## Package and integration proof
|
||||
|
||||
Build, clean-install and runtime-routing claims require observed runtime
|
||||
Evidence (`controlled-replay` or `external-service`). Package-content and
|
||||
authority-independence audits can also use observed or derived
|
||||
`shipped-artifact` Evidence. Each proof must cite its qualifying records and
|
||||
cover the selected boundary's artifact digests. An inference alone establishes
|
||||
neither a passing nor a failed package workflow.
|
||||
|
||||
The evaluator preserves Evidence provenance and returns an actionable unknown
|
||||
when qualification is unavailable. It does not change the cited records to
|
||||
make their authority match a caller's declaration.
|
||||
@@ -323,6 +323,3 @@ disposition but does not silently count it as verified.
|
||||
The tool returns every obligation inline. Its `ledger_id` and `closure_digest`
|
||||
identify the complete result, including summaries, reports, ownership and
|
||||
dependency graphs, Evidence links, and limitations.
|
||||
|
||||
For named boundaries with explicit verifier contracts and package-proof kinds,
|
||||
see [reconstruction coverage](reconstruction-coverage.md).
|
||||
@@ -61,21 +61,9 @@ The outer provider owns both processes and one stable core snapshot. An owned
|
||||
Python launcher lowers inherited soft limits before replacing itself with GDB.
|
||||
GDB starts without initfiles, auto-load, debuginfod or automatic shared-library
|
||||
loading. Owned empty library search paths and caches are used, with plugin
|
||||
updates disabled. Debug-file lookup is also restricted to the owned empty
|
||||
search directory. GDB 16 can otherwise locate the recorded executable independently
|
||||
of these settings. While opening the core, fixed package code temporarily selects
|
||||
`/proc/self/exe` (the already running debugger) with `exec-file`, without loading
|
||||
symbols or running an inferior. This occupies GDB's executable slot and prevents
|
||||
its automatic executable discovery. The validated decoder profile selects the
|
||||
core architecture explicitly, so the placeholder cannot select it instead. The
|
||||
bridge discards that selection with `file` before querying mapping candidates,
|
||||
and verifies the core connection and absence of a main symbol file. Before launching GDB, the provider also checks
|
||||
source-bound `NT_FILE` descriptors: mapping names must be absolute Unix paths
|
||||
without dot segments. Relative names bypass GDB's sysroot, and traversal can
|
||||
escape it. Unresolved or unsafe mapping coverage refuses debugger enrichment
|
||||
while retaining the basic decoded observation and original bytes. No caller GDB
|
||||
command language is exposed. The exact observed GDB/plugin version strings are
|
||||
retained.
|
||||
updates disabled. Fixed package code verifies a core connection and no paired
|
||||
executable before querying mapping candidates. No caller GDB command language is
|
||||
exposed. The exact observed GDB/plugin version strings are retained.
|
||||
|
||||
Mapping names are producer display metadata, with unknown current file identity.
|
||||
Map permissions are derived from reported flags; zero/unfamiliar flags leave
|
||||
@@ -105,6 +93,4 @@ GDB/Python/pwndbg/strace. Fixture generation explicitly launches its owned test
|
||||
program; subsequent inspection only reads the resulting core. Real acceptance
|
||||
checks recorded threads, high registers, missing/malformed notes, opaque owners,
|
||||
CLI/MCP parity, optional debugger context and historical PID collision with an
|
||||
owned live sentinel. The syscall trace also rejects access to the still-present
|
||||
source executable. The CI workflow defines Ubuntu 24.04 and Debian 13 (GDB 16)
|
||||
container lanes. Original inputs and host configuration remain unchanged.
|
||||
owned live sentinel. Original inputs and host configuration remain unchanged.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,112 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"repository": "morluto/rea",
|
||||
"version": "6.7.0",
|
||||
"base": "2c4338db1fdb7773e05376301c558cff2a0b4b80",
|
||||
"target": "b83b9caf4a5f0241a5fd370792f1aed1bffbb2cf",
|
||||
"commits": [
|
||||
{
|
||||
"sha": "8cbaf6c7021b97dd4de6b5771c35fbed06b240e9",
|
||||
"subject": "fix(tests): isolate command finalization module mocks",
|
||||
"body": "fix(tests): isolate command finalization module mocks\n\nMove the five registered WASM finalization cases into the existing per-file isolated project. Preserve all result, exit-code, observation and cleanup assertions. A preloaded shared CLI graph reproduces three failures before the move; the isolated covered packet passes.\n\nFixes #4959\n",
|
||||
"parents": ["2c4338db1fdb7773e05376301c558cff2a0b4b80"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "morluto",
|
||||
"email": "76467478+morluto@users.noreply.github.com",
|
||||
"user": {
|
||||
"login": "morluto",
|
||||
"__typename": "User"
|
||||
}
|
||||
}
|
||||
],
|
||||
"pullRequests": []
|
||||
},
|
||||
{
|
||||
"sha": "6b180783ed04ebc87548c8385c80e05725804c47",
|
||||
"subject": "fix(tests): budget CLI coverage from parsed options",
|
||||
"body": "fix(tests): budget CLI coverage from parsed options\n\nUse the pinned Vitest parser for coverage and shard flags. Keep ordinary CLI workers at 384 MiB and covered workers at the tested 512 MiB with unchanged concurrency. Retain complete coverage and add actual-config regressions for false, provider-only and spaced-shard options.\n\nValidation: 27 focused cases; 16 covered cases with CLI preloaded; 5 docs checks; typecheck/lint; exact discovery of 1578 files. Measured covered control: 22.18s elapsed, 46.52s CPU, about 2.33 GiB sampled summed process-family RSS on macOS arm64. Full Linux CI pending. No runtime/device verification claimed.\n\nFixes #4960\n",
|
||||
"parents": ["8cbaf6c7021b97dd4de6b5771c35fbed06b240e9"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "morluto",
|
||||
"email": "76467478+morluto@users.noreply.github.com",
|
||||
"user": {
|
||||
"login": "morluto",
|
||||
"__typename": "User"
|
||||
}
|
||||
}
|
||||
],
|
||||
"pullRequests": []
|
||||
},
|
||||
{
|
||||
"sha": "bb212ffecb47e129cc569b9867b2b6e7c9b65685",
|
||||
"subject": "fix(tests): inherit server identity deadline policy",
|
||||
"body": "fix(tests): inherit server identity deadline policy\n\nRemove per-case ten-second overrides from MCP catalog and identity checks. Keep the suite-owned bounded ordinary and coverage deadlines, all assertions, and session cleanup.\n\nFixes #4967\n",
|
||||
"parents": ["6b180783ed04ebc87548c8385c80e05725804c47"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "morluto",
|
||||
"email": "76467478+morluto@users.noreply.github.com",
|
||||
"user": {
|
||||
"login": "morluto",
|
||||
"__typename": "User"
|
||||
}
|
||||
}
|
||||
],
|
||||
"pullRequests": []
|
||||
},
|
||||
{
|
||||
"sha": "b83b9caf4a5f0241a5fd370792f1aed1bffbb2cf",
|
||||
"subject": "fix(setup): edit the duplicate JSON member that clients read (#4957)",
|
||||
"body": "fix(setup): edit the duplicate JSON member that clients read (#4957)\n\nJSON.parse, JSONC parse, and native Claude Code keep the last duplicate\nobject member, and parseClientConfiguration therefore validates the last\none. The shared setup/uninstall serializer instead edited text through\njsonc-parser's modify and findNodeAtLocation, which select the first\nmatching member, so setup and uninstall on configurations with repeated\nserver tables or rea members wrote into a shadowed member and failed\nreadback.\n\nLocate every JSON text edit by the effective (last) member in one place,\nreplacing the first-member modify path. Removing an effective member\nthat shadows an earlier duplicate would activate that duplicate, whatever\nits ownership, so the serializer now returns a tagged shadowed_member\nfailure and setup and uninstall refuse before writing a backup or the\nconfiguration.\n\nFixes #4952\n\nCo-authored-by: Claude Opus 5.5 <noreply@anthropic.com>",
|
||||
"parents": ["bb212ffecb47e129cc569b9867b2b6e7c9b65685"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kaoru0822",
|
||||
"email": "kanadekitauji@proton.me",
|
||||
"user": {
|
||||
"login": "kaoru0822-kitauji",
|
||||
"__typename": "User"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Claude Opus 5.5",
|
||||
"email": "noreply@anthropic.com",
|
||||
"user": {
|
||||
"login": "claude",
|
||||
"__typename": "User"
|
||||
}
|
||||
}
|
||||
],
|
||||
"pullRequests": [4957]
|
||||
}
|
||||
],
|
||||
"pullRequests": [
|
||||
{
|
||||
"number": 4957,
|
||||
"title": "fix(setup): edit the duplicate JSON member that clients read",
|
||||
"url": "https://github.com/morluto/rea/pull/4957",
|
||||
"author": {
|
||||
"login": "kaoru0822-kitauji",
|
||||
"__typename": "User"
|
||||
},
|
||||
"mergeCommit": {
|
||||
"oid": "b83b9caf4a5f0241a5fd370792f1aed1bffbb2cf"
|
||||
},
|
||||
"issues": [
|
||||
{
|
||||
"number": 4952,
|
||||
"url": "https://github.com/morluto/rea/issues/4952",
|
||||
"author": {
|
||||
"login": "xu91102",
|
||||
"__typename": "User"
|
||||
},
|
||||
"repository": {
|
||||
"nameWithOwner": "morluto/rea"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -16,12 +16,11 @@ can run.
|
||||
|
||||
`inspect_with_objdump` and `rea inspect-with-objdump` capture stdout and stderr as inline Evidence. Artifact inspection Evidence records SHA-256 digests before and after the provider call and whether those observed digests differ; this cannot prove the exact bytes consumed if the artifact changes during execution. Choose one artifact operation: `file_headers`, `section_headers`, `symbols`, `relocations`, `dwarf`, `disassemble`, or `disassemble_all`. `disassemble` maps to `-d`; `disassemble_all` maps to `-D` and has different symbol-boundary semantics. The pathless `inspect_with_objdump {"operation":"architectures"}` MCP call or `rea list-objdump-architectures` CLI command maps to `-i` and produces subjectless provider-capability Evidence describing BFD targets compiled into the installed binary, not a guarantee that a target is supported.
|
||||
|
||||
For DWARF, REA does not follow local debug links by default. Set `follow_debug_links` to `true` to pass `-WK`; external debug-file identities are not bound to Evidence when following links is enabled. The CLI flag is `--follow-debug-links`; `--no-follow-debug-links` or `--follow-debug-links=false` keeps the default. A separate `true` or `false` word after the flag is not its value. REA clears `DEBUGINFOD_URLS` in the objdump child environment to disable debuginfod network access on GNU binutils versions that do not support `-WE`. The complete raw output is authoritative; REA does not normalize it into a version-independent disassembly schema.
|
||||
For DWARF, REA does not follow local debug links by default. Set `follow_debug_links` to `true` to pass `-WK`; external debug-file identities are not bound to Evidence when following links is enabled. The CLI option is `--follow-debug-links true`. REA clears `DEBUGINFOD_URLS` in the objdump child environment to disable debuginfod network access on GNU binutils versions that do not support `-WE`. The complete raw output is authoritative; REA does not normalize it into a version-independent disassembly schema.
|
||||
|
||||
```sh
|
||||
rea inspect-with-objdump ./program disassemble
|
||||
rea inspect-with-objdump ./program dwarf
|
||||
rea inspect-with-objdump ./program dwarf --follow-debug-links
|
||||
rea inspect-with-objdump ./program dwarf --follow-debug-links false
|
||||
```
|
||||
|
||||
Captured stdout and stderr are retained up to a 16 MiB combined limit; `output_truncated` marks output beyond that limit.
|
||||
@@ -73,12 +72,7 @@ invocation. A signed status response also confirms completion of older bridge
|
||||
connections after its UI dispatch, preserving recovery proof for a caller whose
|
||||
receipt another caller has acknowledged. Neither receipt recovery nor a status
|
||||
probe retries the original command. Failed acknowledgements remain pending and
|
||||
block new commands until they can be retried successfully. Status proof failures
|
||||
identify `cutter_command` and retain `status` in
|
||||
`details.diagnostics.auxiliary_operation`; malformed proof still blocks dispatch.
|
||||
Descriptor failures likewise retain the requesting operation through cleanup.
|
||||
Command admission reports typed cancellation and treats the caller's abort reason
|
||||
as opaque metadata, without inferring cleanup ownership from it.
|
||||
block new commands until they can be retried successfully.
|
||||
|
||||
## Configuration and coverage
|
||||
|
||||
|
||||
@@ -57,10 +57,7 @@ triggers or arbitrary SQL.
|
||||
Rows are optional. `table` selects one exact ordinary-table name. `columns`
|
||||
(CLI repeated `--column`) selects exact visible column names in the requested
|
||||
order; omission selects all visible columns, including generated columns.
|
||||
Unselected cells are not evaluated or projected. Malformed column-name bytes
|
||||
cause a format refusal when all columns are requested. In inventory scope, an explicit valid subset can
|
||||
still be sampled without decoding unrelated malformed column names.
|
||||
Column selection requires a
|
||||
Unselected cells are not evaluated or projected. Column selection requires a
|
||||
table and at least one name; empty-string identifiers are valid. `row_limit`
|
||||
requires `table`, defaults to 20 and accepts positive safe integers. Samples
|
||||
remain subject to the byte and worker resource limits below, regardless of row count. The result reports
|
||||
@@ -108,20 +105,6 @@ overall native heap and total resident memory are not capped. Row limits do not
|
||||
override these byte and resource limits. Resource-limit failures do not return
|
||||
an incomplete schema as successful complete evidence.
|
||||
|
||||
If the combined database and WAL exceed the snapshot budget, the refusal is a
|
||||
`resource_constraint` and reports both the configured byte limit and the exact
|
||||
observed combined size as a decimal string. The remediation directs callers to
|
||||
create a smaller consistent offline snapshot containing only relevant data
|
||||
through the application's supported export workflow. A generic backup or copy
|
||||
does not guarantee a smaller result; REA does not truncate or modify the
|
||||
selected source.
|
||||
|
||||
On hosts that cannot address the derived WAL or rollback-journal path for a
|
||||
long selected database name, REA reports that the SQLite capability is
|
||||
unavailable. It does not assume an inaccessible sidecar is absent. Use the
|
||||
application's supported consistent offline export or copy workflow to place
|
||||
the complete known file set at a shorter path.
|
||||
|
||||
MCP also applies its configured response budget to the complete Evidence
|
||||
envelope. If delivery exceeds that budget, it reports a transport constraint
|
||||
with guidance for exporting retained Evidence, requesting a matching larger
|
||||
|
||||
+7
-194
@@ -110,14 +110,9 @@ rendered declarations. Keep canonical rejection checks separate from the
|
||||
intentionally reduced compact advertisement, and probe actual client renderers
|
||||
when changing schema representations.
|
||||
|
||||
The reused CLI boundary workers cap V8 old space at 384 MiB for ordinary runs
|
||||
and 512 MiB with coverage enabled. Covered ADB fixtures exhaust the ordinary
|
||||
384 MiB budget; those fixtures also complete with the shared CLI graph preloaded
|
||||
at 512 MiB. This is a measured capacity control, not a suite-wide speedup claim.
|
||||
Both profiles keep the
|
||||
same bounded worker count, and spawned REA processes retain their own heap
|
||||
settings. Explicitly disabling coverage retains the ordinary profile; coverage
|
||||
provider options alone do not enable instrumentation.
|
||||
The reused CLI boundary workers cap V8 old space at 384 MiB, based on their
|
||||
profiled allocation and cleanup behavior. This encourages collection between
|
||||
files; spawned REA processes retain their own heap settings.
|
||||
|
||||
Vitest worker limits do not bound subprocesses launched within a test. Bound
|
||||
those batches separately so repeated CLI validation cannot oversubscribe the
|
||||
@@ -204,121 +199,6 @@ 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.
|
||||
|
||||
## Lifecycle regressions
|
||||
|
||||
For changes to resource acquisition, readiness, cancellation, or cleanup, select
|
||||
the affected owners and applicable scenarios below. Include temporary snapshots
|
||||
and one-shot commands. Use public CLI/MCP workflows where practical and a
|
||||
controlled production seam for interleavings that cannot be reproduced reliably.
|
||||
|
||||
| Scenario | Assertion and control |
|
||||
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Target admitted; startup still pending | Status preserves the readiness distinction and observed startup activity; readiness requires the provider's documented proof. |
|
||||
| First handshake is late, absent, invalid, or recovered during close | Initial and recovery paths retain the same authenticated identity facts. Foreign run/token controls cannot authorize cleanup; authenticated idle/native work survives the unauthenticated listener deadline. |
|
||||
| Launch returns an error with a valid process handle | Cover already-exited and still-live owned processes. Verify observed exit separately from creation; failed termination or unavailable identity remains unresolved. |
|
||||
| Cancellation arrives after workload exit, during result reads or temporary-root removal | Return typed cancellation with available partial observations and actual cleanup status. The non-aborted control succeeds; existing primary/cleanup failures keep their precedence. |
|
||||
| Children have mixed health or cleanup outcomes | Missing peer health does not erase an observed failure or activity. Idle plus unknown stays unknown. Retry a failed child without closing a successful peer again, including after a close-option change. |
|
||||
| Cleanup fails after success or primary failure | Public output retains the completed observation or primary diagnostic, remaining resources, and owner recovery action. Restore the denied resource and verify the owning cleanup retry. |
|
||||
| Target exits without an acknowledgement, or transport disappears while it stays alive | Positive owned exit proof resolves target lifetime; other resources still need cleanup. Lost transport alone does not prove exit. Verify unrelated/attached targets survive and same-connection recovery works when supported. |
|
||||
|
||||
Shared process-supervision controls separate leader exit from output closure.
|
||||
Cover output during held or failed cleanup, bounded retention and drain timeout,
|
||||
retry, and borrowed stream authority. The POSIX inherited-stderr control uses a
|
||||
separate pipe as a release barrier after leader exit; it does not establish
|
||||
native Windows Job Object behavior.
|
||||
|
||||
Synchronize cancellation with the finalization boundary being tested; a fixed
|
||||
delay after dispatch does not establish that phase. Use markers, barriers, or
|
||||
owned cleanup seams while preserving real cleanup where feasible. Check server
|
||||
settlement and retained resources even if the MCP SDK rejects the client promise
|
||||
before the handler finishes. A cancellation during active execution does not
|
||||
cover cancellation during final cleanup.
|
||||
Use explicit abort reasons and assert their identity at admission and after
|
||||
provider completion, alongside retained observations and cleanup state.
|
||||
|
||||
Electron fuse regressions cover actual descriptor close denial and retry through
|
||||
the built CLI, same-connection MCP recovery, mixed descriptor outcomes, and
|
||||
server shutdown. Controlled seams cover cancellation during final close and
|
||||
after reader finalization, plus active-provider shutdown during preflight.
|
||||
They preserve real filesystem cleanup where possible; mocked launch boundaries
|
||||
do not establish real Electron teardown or naturally occurring OS failures.
|
||||
|
||||
Active Electron cleanup controls retain independent transport and process-family
|
||||
owners, block replacement captures until recovery, and retry only unresolved
|
||||
owners. Cover late close acknowledgement and rejection after a wait deadline,
|
||||
opaque rejection reasons, cancellation during failed finalization, and missing
|
||||
lineage followed by a confirmed passive family census. Windows controls require
|
||||
a fresh lineage observation and do not signal cached descendant PIDs after root
|
||||
termination. Simulated Windows controls do not establish native Windows behavior.
|
||||
|
||||
For atomic writes, exercise cancellation on both sides of the documented commit
|
||||
point and preserve any publication receipt. A late interruption does not prove
|
||||
that no output was published.
|
||||
|
||||
For successful provider reports, test cancellation immediately before the report
|
||||
reaches the application workflow as well as during provider cleanup. Validate
|
||||
the report before classifying completion: a valid report must retain its Evidence
|
||||
on cancellation, and an invalid report must keep its output error. Exercise both
|
||||
the provider boundary and the shared CLI/MCP workflow; a downstream guard does
|
||||
not repair the provider's own completion contract. When callers share startup,
|
||||
cancel each waiter independently and verify that the last departure awaits owned
|
||||
cleanup while interested peers can still reach readiness. Repeat the same
|
||||
shutdown event after a cleanup failure to verify that its listener can retry.
|
||||
Exercise non-default lifecycle deadlines through queued requests and their
|
||||
consumers; default-only controls cannot detect dropped request options.
|
||||
|
||||
For descriptor-backed reads, inject a close failure after a successful read and
|
||||
after a primary read or cancellation failure. Verify that the exact descriptor
|
||||
remains owned, both failures survive, and a later close retries it. Repeat
|
||||
admission attempts while close still fails: no additional descriptor or
|
||||
native command should start. Restore close and verify that the exact owner
|
||||
resolves the originating cleanup marker and allows later work, while the earlier
|
||||
failure remains available as a diagnostic. Retain errors returned by multiple
|
||||
failed retries, including admission and shutdown aggregates, and assert that
|
||||
each becomes complete after recovery. For an aggregate with multiple owners,
|
||||
release one owner while another still fails and assert that it remains incomplete.
|
||||
Cover recovery before the
|
||||
caller-specific error is bound to its retained owner, as
|
||||
another request can retry cleanup concurrently. Confirm that an already released
|
||||
owner resolves a later binding too. Include
|
||||
admission failure after opening the descriptor. If caller cancellation returns
|
||||
before an inspection settles, gate its final read or close and verify that
|
||||
session shutdown waits for the owned work and reports any retained resources.
|
||||
Gate a later read in a multi-read inspection, not only its first read. Overlap
|
||||
operations so one retains a failed descriptor while another reaches its next
|
||||
read; both the operation and shutdown must settle without nested-admission
|
||||
deadlock. Deny child close and verify its containing root survives until retry.
|
||||
|
||||
Exercise publication on filesystems without hard links using an unsupported-link
|
||||
seam. Check exclusive destination creation, stat/write/close failures, completed
|
||||
output receipts, and cancellation at the documented cutoff. A streamed fallback
|
||||
has different visibility from an atomic hard-link commit and must report it
|
||||
accurately. For Windows command supervision, keep a descendant writing after its
|
||||
leader exits, deny cleanup observation, and verify a competing writer remains
|
||||
excluded until the exact Job Object closes. Portable doubles cover retry logic;
|
||||
the native Windows lane must establish actual process-tree behavior.
|
||||
|
||||
Supervisor tests must observe process exit, output-pipe closure, and IPC
|
||||
disconnection separately. In the pinned Node runtime, a parent-initiated IPC
|
||||
disconnect can omit the aggregate `ChildProcess` close event. Join the actual
|
||||
resource observations before reporting completion; process exit alone does not
|
||||
establish pipe or process-tree release.
|
||||
|
||||
When changing an internal helper contract, check its JavaScript verifier and
|
||||
subprocess-script consumers alongside TypeScript references. Source typecheck
|
||||
does not check those calls; run their orchestration tests against the built
|
||||
modules, including the verifier's failure and cleanup paths.
|
||||
|
||||
Representative regressions include
|
||||
[process cleanup-time SIGINT](https://github.com/morluto/rea/blob/e78455338fe2d06c4cd03d59cbf33473d754998b/tests/boundary/process/processCaptureCancellationAdapters.test.ts),
|
||||
[late authenticated cleanup](https://github.com/morluto/rea/blob/e78455338fe2d06c4cd03d59cbf33473d754998b/tests/boundary/providers/hopper/hopperClient.handshakeRecovery.test.ts),
|
||||
[LLDB launch and finalization](https://github.com/morluto/rea/blob/e78455338fe2d06c4cd03d59cbf33473d754998b/tests/boundary/providers/native/lldbCallTracerFailures.test.ts),
|
||||
[composed child ownership](https://github.com/morluto/rea/blob/e78455338fe2d06c4cd03d59cbf33473d754998b/src/application/binary/CompositeProvider.test.ts),
|
||||
and [public CLI cleanup denial](https://github.com/morluto/rea/blob/e78455338fe2d06c4cd03d59cbf33473d754998b/tests/boundary/cli/wasmCleanupCli.test.ts).
|
||||
These controlled probes do not replace the matching real-provider lane. Record
|
||||
the base failure, passing control, exact host/provider, verified cleanup, and
|
||||
unavailable coverage; a missing engine is not a pass.
|
||||
|
||||
## Behavioral depths
|
||||
|
||||
| Depth | Location | What it proves |
|
||||
@@ -529,7 +409,7 @@ costs. Its queue, execution, and failures are independent of the required gate
|
||||
and publication. CPU time and peak process-family memory are not measured by this API.
|
||||
|
||||
The build job saves portable Turbo outputs across runs. Eight Linux real-system
|
||||
lanes reuse its current-run artifact; standalone dispatches restore the cross-run cache. The shared action
|
||||
lanes restore this cache without waiting for the build job. The shared action
|
||||
derives its key from `test:prepare --dry=json` task hashes, runner OS and
|
||||
architecture, `.npmrc`, `.nvmrc`, and the lockfile; test-only changes can reuse compiled outputs. Every
|
||||
build and verification command still runs, so Turbo checks task inputs and
|
||||
@@ -539,15 +419,7 @@ that generator's entry. Native outputs are not stored in this cache.
|
||||
|
||||
Native package jobs, the Windows curated lane, and the Apple artifact lane reuse
|
||||
the same workflow's Turbo cache for portable compiled JavaScript, skills, and
|
||||
catalogs. The key parser retains the validated `test:prepare` task identities in
|
||||
`.cache/ci-build-plan.json`; staging reads this plan without starting another
|
||||
Turbo run that could evict cache entries. The producer stages matching archives,
|
||||
metadata, and available manifests into `.cache/ci-build-cache/`.
|
||||
`portable-build-cache.json` records availability per task. Evicted or partially
|
||||
missing entries are omitted as whole entries, and consumers rebuild cache misses,
|
||||
including when every entry is unavailable. Malformed plans, non-file entries,
|
||||
and I/O errors other than disappearance still fail publication. Older cross-run entries stay in the
|
||||
original cache. The Windows lane relies on the Linux static job for typechecking. They retain the normal build and prepack
|
||||
catalogs. The Windows lane relies on the Linux static job for typechecking. They retain the normal build and prepack
|
||||
commands, which restore matching outputs or rebuild on a cache miss. Native
|
||||
artifacts, dependency installs, package archives, and runtime verification remain
|
||||
host-local. Keep platform-dependent outputs out of this shared cache.
|
||||
@@ -945,38 +817,6 @@ Native IDA MCP verification uses `"protocol": "native"` with an already-running
|
||||
|
||||
The initial Linux x64 IDA Free 9.4 run used native MCP 1.1.2 with a local navigation correction. Windows x64 verification uses **IDA Pro 9.3**, the two-function public fixture, and the shipped Windows `whoami.exe` application. The native plugin was built from upstream `c9d15d98e8a143fc74f6e14037c48f63889b6d6c`, including the merged navigation fix, with a local loopback-listener change. Production CLI/MCP parity, switching, identity and cleanup passed. Correctness and performance measurements are recorded in the [Windows native verification notes](https://github.com/morluto/rea/blob/main/experiments/analysis-efficiency/ida-native-windows.md). Stock 1.1.2 switching, native macOS, and Windows IDA Free remain unverified. See the [native bridge prerequisites](ida-provider.md#optional-native-ida-mcp-bridge).
|
||||
|
||||
## Kuna lane
|
||||
|
||||
`npm run verify:kuna` requires a caller-supplied `kuna` in `REA_KUNA_COMMAND`
|
||||
and a host C compiler (`REA_CC`, default `cc`) with `strip` and `nm`. It builds a
|
||||
source-owned fixture with non-inlined calls, with symbols and stripped, then verifies through MCP that
|
||||
callers, callees and exact incoming xrefs agree with those calls, graph/path
|
||||
composition reaches the callee, reference-only queries leave project/staging
|
||||
entries unchanged, repeated relationships reuse the graph, and
|
||||
the first cold pseudocode answer comes from a single-function run or an export
|
||||
that already finished, assembly waits for and serves from that export, and
|
||||
pseudocode and both dossier facets match their recorded file spans and digests,
|
||||
a fresh server reuses the export without rebuilding it, staging is empty after
|
||||
a completed export, and no owned process survives. Pass
|
||||
`--targets DIR --functions a,b` to add caller-built binaries laid out as
|
||||
`DIR/<flavor>/<name>` beside `<name>.stripped`; addresses come from the
|
||||
symbol-bearing build. `--compare-ghidra` with `GHIDRA_INSTALL_DIR` runs those
|
||||
caller-built functions through Ghidra (it refuses to run without `--targets` and
|
||||
`--functions`, an empty matrix, or names missing from every supplied target) and
|
||||
reports latency, sampled process-tree CPU and peak memory, UTF-8 response size,
|
||||
and goto and warning-marker counts. Those counts are not a correctness judgement,
|
||||
and model tokens are not measured. Reference timings and response sizes are
|
||||
reported separately; reference caches expire when the server closes. `--report PATH` writes the JSON report.
|
||||
|
||||
The first matrix run used Kuna 1.833 and Ghidra 12.1.4 with JDK 21 on macOS
|
||||
arm64. It covered zlib 1.3.2 `minigzip`, coreutils 9.9 `sort` and the sqlite
|
||||
3.54.0 shell, built at `-O2` for ELF x86-64, ELF AArch64, Mach-O arm64 and
|
||||
Mach-O x86-64, each with symbols and stripped. A separate Linux x86-64 run verified
|
||||
the fixture and system zlib 1.2.13 / SQLite 3.40.1 libraries through MCP, including
|
||||
cached byte spans and a Ghidra comparison. See the [Linux report](https://github.com/morluto/rea/pull/3854#issuecomment-6185870391)
|
||||
for measured scope and limitations. Windows, PE and universal Mach-O remain
|
||||
unverified by this lane.
|
||||
|
||||
## DOS Ghidra analysis
|
||||
|
||||
`npm run verify:ghidra:dos` requires the supported Ghidra and JDK installation
|
||||
@@ -1010,16 +850,6 @@ and runtime cleanup. Windows additionally requires the matching native addon;
|
||||
its verifier lineage remains explicitly unavailable outside the provider's
|
||||
retained Job Object, as in the other Windows lanes.
|
||||
|
||||
`npm run verify:ghidra:m68k` needs no assembler: its 22-byte big-endian 68000
|
||||
fixture is source-owned annotated hex in the verifier, loaded at `0x1000`. With
|
||||
an installed Ghidra 12.1.4 and full JDK on Linux or macOS, it verifies the
|
||||
`68000:BE:32:default` BinaryLoader import, real CLI/stdio MCP load-image parity,
|
||||
exact source bytes, both functions, the `bsr.b` call reference, decompilation
|
||||
through address and file offset, rejection of a misaligned entry and of a mapping
|
||||
past `0xffffffff` without replacing the active session, and runtime cleanup.
|
||||
Windows Ghidra P0 does not admit m68k, so this is not a Windows lane. The lane
|
||||
has been run on macOS; Linux has not been exercised.
|
||||
|
||||
`npm run verify:ghidra:raw` uses a generated ARM little-endian headerless image
|
||||
through the compiled CLI and stdio MCP server. With the same Ghidra/JDK
|
||||
prerequisites, it checks preparation and bridge startup, verified load mappings,
|
||||
@@ -1127,19 +957,7 @@ the Apple or Windows curated lanes invoke explicitly, which also select that
|
||||
lane. Edits to verifier entrypoints run only by manual, licensed or self-hosted
|
||||
workflows run static checks and the Linux suite. Website changes run website
|
||||
checks. Provider workflow changes validate the workflow and run that provider's
|
||||
verifier. Changes under `bridge/ghidra/` also select the `ghidra_bridge` lane,
|
||||
which compiles the packaged bridge sources against the pinned Ghidra 12.1.4
|
||||
jars with `npm run verify:ghidra:bridge-sources`. It never launches Ghidra or
|
||||
imports a target, so a missing import fails the PR instead of every Ghidra
|
||||
session. The launcher, compiler and package checks share named required source
|
||||
roles. The manifest must match the complete Java cohort, so deleting a helper
|
||||
or adding an unregistered dependency cannot silently change the shipped set.
|
||||
The preflight reuses the provider's Java Properties parser with the pinned Node
|
||||
toolchain's native type stripping, without an npm install or runtime build.
|
||||
The shared release policy owns the verified version and JDK major. CI checks
|
||||
the archive pin before downloading and verifies the extracted SDK version;
|
||||
changes to these source owners also select the compile lane.
|
||||
Manual-provider/Android workflow changes run workflow validation only.
|
||||
verifier. Manual-provider/Android workflow changes run workflow validation only.
|
||||
The four-version SQLite compatibility matrix has its own `sqlite` scope for
|
||||
SQLite implementation, contracts, CLI/MCP registration, fixtures, and shared
|
||||
runtime boundaries. SQLite and server-lifecycle test edits and the SQLite npm
|
||||
@@ -1570,12 +1388,7 @@ NUL-containing names. It compares exact WAT,
|
||||
section output and selected/tool digests through the compiled CLI and real MCP
|
||||
SDK, validates advertised schemas, checks identical CLI/MCP Evidence IDs and
|
||||
session bundle readback, retains invalid/truncated module diagnostics, preserves
|
||||
all inputs and checks workspace cleanup.
|
||||
The lane also injects one cleanup denial for exact private runtime roots and
|
||||
input descriptors, checks recovered CLI errors, and verifies retry on the same
|
||||
MCP connection after repeated runtime-removal denial. These are controlled
|
||||
faults, not naturally occurring permission failures; no WASM target is executed.
|
||||
Pass an installed package's
|
||||
all inputs and checks workspace cleanup. Pass an installed package's
|
||||
`scripts/rea.mjs` as the first argument to run the same lane against the package.
|
||||
`npm run verify:wasm:package` packs and installs REA into an isolated temporary
|
||||
prefix with lifecycle scripts disabled and runs the same required real-tool lane.
|
||||
|
||||
@@ -68,100 +68,6 @@ satisfy. A plan without execution does not establish runtime behavior.
|
||||
constraints. Report pagination, truncation, cancellation, and partial failure.
|
||||
An assumed agent budget is insufficient justification for a limit.
|
||||
|
||||
## Own the lifecycle
|
||||
|
||||
For tools that acquire resources, identify the owner and the observations that
|
||||
establish each transition. Include temporary files and one-shot commands, as
|
||||
well as persistent engine sessions. Use the existing provider contracts;
|
||||
providers need not expose identical state machines.
|
||||
|
||||
- Keep target admission, provider readiness, active work, observed process exit,
|
||||
and resource release separate. A valid process handle, successful launcher,
|
||||
or selected target establishes only its own fact. Publish available identity
|
||||
and exit observations even when launch fails; retain unknown ownership.
|
||||
- Process exit does not establish output closure. The shared process supervisor
|
||||
retains at most 64 KiB of additional diagnostics from owned stop entry,
|
||||
including pending cleanup and retries, and drains for up to one second after
|
||||
verified stop. It marks output incomplete when closure cannot be
|
||||
observed and releases owned event-loop references without changing the proven
|
||||
process-cleanup outcome. Failed process cleanup retains capture for retry;
|
||||
borrowed processes and streams retain their own lifetime and reference state.
|
||||
- Authenticate and capture identity through the same boundary on initial and
|
||||
recovery handshakes. Bound abandoned unauthenticated listeners where the
|
||||
protocol permits it; that deadline must not expire authenticated idle sessions
|
||||
or long-running native work. Listener expiry does not prove target closure.
|
||||
- Readiness observations may await owned prerequisite commands. Status must
|
||||
remain readable during owner finalization without starting replacement work;
|
||||
report readiness as unknown when it cannot be re-observed.
|
||||
- Shared startup has one producer and independently cancellable caller waits.
|
||||
Keep it running while any caller still needs it. The final departing caller
|
||||
waits for owned cleanup and retains its failure. Provider closure is distinct
|
||||
from caller cancellation. Retained cleanup capabilities block replacement;
|
||||
derive readiness from the current startup's completion and live connection.
|
||||
- For cancellable observations, carry cancellation through result consumption
|
||||
and awaited cleanup. Before returning success, check the signal after the
|
||||
last awaited finalization step.
|
||||
Retain collected observations under typed cancellation. Preserve an existing
|
||||
primary failure and let incomplete cleanup retain its own classification.
|
||||
Preserve the caller's abort reason as the typed cancellation error's cause,
|
||||
including when cancellation is observed only after provider completion.
|
||||
Shared command owners must retain the observed cancellation reason separately
|
||||
from physical failures and cleanup ownership. Carry that fact through failure
|
||||
wrapping so adapters can preserve the exact reason without interpreting it.
|
||||
Client cancellation alone does not prove native work stopped.
|
||||
For atomic publication, document the cancellation cutoff and preserve any
|
||||
committed output's publication receipt.
|
||||
Queued and retried work must retain the complete accepted execution controls,
|
||||
including non-default lifecycle deadlines and cancellation signals.
|
||||
- Release only owned resources. Attaching owns a connection or session unless
|
||||
the provider contract explicitly establishes target ownership. A helper exit,
|
||||
missing reply, or missing PID does not establish target exit.
|
||||
- Retain successful child cleanup and retry only unresolved children, including
|
||||
when close options change. Preserve observed child failure or activity when
|
||||
another child's health is unavailable; idle plus missing coverage stays
|
||||
unknown.
|
||||
Bind cleanup failures to their exact resource owner. Resolve current cleanup
|
||||
uncertainty only after that owner confirms release, while preserving the
|
||||
original failure and completed observations. Later failure composition must
|
||||
report only resources whose cleanup remains unresolved. Carry cleanup
|
||||
capabilities explicitly in typed outcomes so consumers can bind returned errors
|
||||
to exact owners without reparsing diagnostic cause chains.
|
||||
Bind every caller-visible retry error and aggregate, including an error already
|
||||
produced by the provider. An aggregate remains incomplete until all owners it
|
||||
reports are released; releasing one child cannot clear another child's status.
|
||||
- Await one-shot cleanup without discarding the completed result or primary
|
||||
diagnostic. Preserve partial observations, remaining resources, and the cleanup
|
||||
owner's recovery instructions. CLI adapters should reuse
|
||||
[`finishAnalysisCommand`](https://github.com/morluto/rea/blob/main/src/cli/finishAnalysisCommand.ts) where its contract
|
||||
applies rather than duplicate close/finally handling.
|
||||
- Give descriptor-backed reads an owner before opening the file. A rejected
|
||||
close must retain the exact handle and preserve any earlier failure. If an
|
||||
abortable caller stops waiting, keep the underlying work in that owner's
|
||||
lifetime so shutdown cannot report release before finalization settles.
|
||||
Admit the entire inspection once, including later reads and finalization.
|
||||
Helpers must borrow that admission or use an operation child scope; re-entering
|
||||
the same draining scope can make cleanup wait for its own caller.
|
||||
Retry retained cleanup before admitting new work and keep admission blocked
|
||||
while it remains unresolved. Link the originating cleanup error to its exact
|
||||
owner so confirmed release resolves its cleanup marker while preserving the
|
||||
earlier diagnostic. Shared CLI/MCP adapters cannot infer that confirmation.
|
||||
- Provider profile selection owns every asynchronous candidate through its
|
||||
terminal result and finalization. The registry owns profile-file cleanup,
|
||||
joins all automatic-selection children, and closes those file owners before
|
||||
reporting candidate shutdown. Final caller cancellation joins the selection;
|
||||
an adapter that ignores cancellation remains active and owned until it settles.
|
||||
Block new admission during shutdown and while cleanup remains unresolved;
|
||||
reopen after confirmed retry. Preserve failed results before considering a
|
||||
later signal, and retain every child's attributed cleanup in mixed outcomes.
|
||||
- Release child descriptors before removing their containing root. Retain a
|
||||
composite owner when either stage fails so retry preserves that ordering.
|
||||
A Windows command leader's exit does not establish Job Object closure. Keep
|
||||
the process-tree observer and command lock alive through failed cleanup retries
|
||||
until the owned tree's close event.
|
||||
|
||||
Exercise the applicable [lifecycle regression scenarios](testing.md#lifecycle-regressions)
|
||||
through the producing owner and affected CLI/MCP consumers.
|
||||
|
||||
## Implement and evaluate
|
||||
|
||||
Put provider protocols/parsing in adapters and shared CLI/MCP workflows in the
|
||||
|
||||
@@ -43,7 +43,7 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement
|
||||
31,src/application/ReferenceSourceImportTypes.ts:limit,Import reports terminal limit failure,No reachable constructor found,Declared state may be unreachable; false verification risk,Remove unreachable top-level limit variant; per-entry limit guidance remains caller-visible.,removed,"verified by typecheck, exhaustive projection test, and source search"
|
||||
32,src/application/Setup.ts:configureDetectedClients(backup),Agent configuration backup fails,"{clientName} configuration backup verification failed; no successful configuration was reported.",Exposes machine client key and obscures no-write guarantee,"Agent configuration could not be backed up, so no change was made. Check file permissions, then rerun setup.",implemented,focused assertions passed
|
||||
33,src/application/Setup.ts:configureDetectedClients(write),Agent configuration write fails,"{clientName} configuration write verification failed; no successful configuration was reported.",Exposes machine client key and gives no recovery,"Agent configuration could not be updated. Check file permissions, then rerun setup.",implemented,focused assertions passed
|
||||
34,src/application/Setup.ts:configureDetectedClients(readback),Written agent configuration cannot be verified,"{clientName} configuration readback verification failed; no successful configuration was reported.",Exposes machine client key and omits backup recovery,"Agent configuration could not be verified after writing. The original was restored and its backup at {backupPath} was retained. Repair the configuration file or restore that backup, then rerun setup. Without a backup: Agent configuration could not be verified. Repair the configuration file, then rerun setup.",implemented,focused assertions passed
|
||||
34,src/application/Setup.ts:configureDetectedClients(readback),Written agent configuration cannot be verified,"{clientName} configuration readback verification failed; no successful configuration was reported.",Exposes machine client key and omits backup recovery,"Agent configuration could not be verified after writing. Repair the configuration file or restore its `.rea.backup`, then rerun setup.",implemented,focused assertions passed
|
||||
35,src/application/Setup.ts:installSkill,Skill install or semantic readback fails,Agent skill installation or readback failed.,No useful recovery action,"REA analysis skill could not be installed or verified. Check permissions for `~/.agents/skills`, then rerun setup.",implemented,focused assertions passed
|
||||
36,src/main.ts:serveStdio.onerror,Established MCP client connection reports an error,MCP stdio transport error,Exposes transport implementation and gives no recovery,REA lost its MCP client connection. Restart REA from your MCP client.,implemented,verified by injected transport onerror runtime test
|
||||
37,src/main.ts:serveStdio throw,MCP connection cannot be created,Failed to start MCP stdio transport,Exposes transport implementation and gives no recovery,REA could not start its MCP connection. Restart REA from your MCP client; run `rea doctor` if it fails again.,implemented,verified by injected transport startup-throw runtime test
|
||||
@@ -55,7 +55,7 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement
|
||||
43,src/application/Uninstall.ts:removeClient parse,Agent configuration is malformed,Malformed configuration was preserved without mutation.,Does not name required repair format or retry,"Configuration is not valid JSON/TOML and was not changed. Repair it, then rerun uninstall.",implemented,focused JSON assertion passed; TOML path uses same branch
|
||||
44,src/application/Uninstall.ts:removeClient backup,Configuration backup copy fails,Configuration backup failed; no mutation was attempted.,No recovery step,"Configuration could not be backed up, so no change was made. Check file permissions, then rerun uninstall.",implemented,verified by injected filesystem backup failure test
|
||||
45,src/application/Uninstall.ts:removeClient update,Write or semantic readback fails,Configuration update failed; the original was restored and {backupPath} was retained.,Exposes local path and lacks clear next sequence,"Report whether the original was restored; if restoration also fails, direct the user to the retained backup.",implemented,verified by injected update and restoration failure tests
|
||||
45.5,src/application/Uninstall.ts:removeClient restore,Configuration update fails and restoring the original also fails,"Configuration could not be updated or restored. Restore the backup at {backupPath} manually, then rerun uninstall.","High risk; persistent configuration may be damaged, but retained backup is authoritative",Keep new recovery copy,implemented,verified by injected restoration failure test
|
||||
45.5,src/application/Uninstall.ts:removeClient restore,Configuration update fails and restoring the original also fails,"Configuration could not be updated or restored. Restore its `.rea.backup` manually, then rerun uninstall.","High risk; persistent configuration may be damaged, but retained backup is authoritative",Keep new recovery copy,implemented,verified by injected restoration failure test
|
||||
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
|
||||
|
||||
|
File diff suppressed because it is too large.
Load diff
@@ -1,158 +0,0 @@
|
||||
# Electron cancellation verification, 2026-10-16
|
||||
|
||||
[#4388](https://github.com/morluto/rea/issues/4388), existing
|
||||
[#4387](https://github.com/morluto/rea/pull/4387), umbrella
|
||||
[#4027](https://github.com/morluto/rea/issues/4027).
|
||||
|
||||
The cancellation boundaries and retained cancellation cause are verified below.
|
||||
The complete real Linux Joplin workflow remains **partial or failed** because
|
||||
process ownership/cleanup cannot be verified. Publishing a typed reply, exiting
|
||||
the CLI, and cleaning up its application are separate observations.
|
||||
|
||||
## Source and deterministic regressions
|
||||
|
||||
Latest-main control is `fe2a398dd9ab290ba6cb3411403d319cec8d07a2`.
|
||||
The existing reviewed PR head `af732dd8` was integrated with that main in
|
||||
`3b094802a`. Its initial 47 focused cases passed. An unrelated compact-catalog
|
||||
test hit its unchanged 10-second CI deadline; an unchanged-source job retry
|
||||
passed. The original failed execution remains in CI history.
|
||||
|
||||
Real CLI verification exposed an introduced regression: the PR replaced an
|
||||
already observed cancellation with success after the final snapshot. A later
|
||||
cleanup failure then lost the cancellation category and caller reason. Two
|
||||
deterministic cases reproduced this for process and transport cleanup: 20 old
|
||||
cases passed and both new cases failed. Main's public reply retained category
|
||||
`cancelled`; the reviewed PR returned `execution_failure` for the same kind of
|
||||
cancelled wait plus incomplete cleanup.
|
||||
|
||||
Fix `73d4a712b` records cancellation before finalization and uses one constructor
|
||||
for the early and late partial-capture errors. Cleanup failure keeps precedence,
|
||||
its diagnostics and the earlier cancellation cause. Cancellation first observed
|
||||
during cleanup retains the existing precedence. The fix changes the producing
|
||||
outcome; no CLI/MCP projection repair or ownership-policy exception was added.
|
||||
|
||||
All **49 focused cases in three files** passed after the fix. Full static checks
|
||||
passed: six tasks plus architecture guards. Documentation checks also passed
|
||||
(six tasks, including two cached, plus five README consistency cases). One intermediate build rejected an
|
||||
over-narrowed `aborted === true` comparison; the original truthiness pattern
|
||||
resolved that TypeScript error before the passing build. Recorded catalog
|
||||
metadata is byte-identical to main. No new tool, schema, cache or normal-case
|
||||
result field was added.
|
||||
|
||||
## Real application observations
|
||||
|
||||
The unchanged official Joplin 3.7.21 ASAR is 233,575,014 bytes, SHA-256
|
||||
`767df409b18effe60421fbefcca873de237c7e813eac744ecdeebbc5e825a33a`.
|
||||
Acquisition is linked in the [original Joplin verification](javascript-native-handoff-identity-2026-10-15.md).
|
||||
Its complete unpacked native files/assets accompany it. These trials use the
|
||||
actual application with **generic Electron 44.7.0**, fresh profiles and Xvfb.
|
||||
They exercise startup/cancellation, not a completed Joplin business workflow.
|
||||
|
||||
Frozen verifier revision `279aa29a7` records source/runtime hashes before the
|
||||
final probes. The controlled cases hold a REA-side Playwright reply while the
|
||||
real application runs. They do not establish a naturally occurring Joplin stall.
|
||||
|
||||
| Controlled condition | Observed result |
|
||||
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| Main: first-window reply stays pending | Still pending 20.001 s after cancellation; verifier watchdog fails |
|
||||
| Fixed: same pending first-window reply | Cancellation returned in 5.658 s; cancelled action retained |
|
||||
| Fixed: initial snapshot reply stays pending | Cancellation returned in 5.335 s; no invented partial snapshot |
|
||||
| Fixed: final snapshot reply stays pending | Cancellation returned in 10.262 s; five-second cancellation grace expiry and initial snapshot retained |
|
||||
|
||||
Every fixed case preserves the `cancelled` category. Every real case still has
|
||||
unverified provider cleanup and a nonzero verifier exit; these are cancellation
|
||||
phase proofs, not complete runtime passes. The known Linux ownership gap is
|
||||
tracked in [#4282](https://github.com/morluto/rea/issues/4282). Ownership was not
|
||||
inferred from process names, PIDs or executable paths to make these tests pass.
|
||||
|
||||
The public CLI trials send SIGTERM after actual Joplin startup logging. Main
|
||||
and the fixed version both publish `cleanup_incomplete` with category `cancelled`
|
||||
and a cancelled action. The fixed reply was observed about 5.268 s after SIGTERM
|
||||
(50 ms polling resolution). Both fail the verifier's 20-second first-signal exit
|
||||
deadline and require a second, explicitly recorded recovery signal. The resulting
|
||||
143 exit is not proof that the first signal completed cleanup.
|
||||
|
||||
The official packaged Joplin executable also passed static fuse admission, but
|
||||
its initial Inspector evaluation failed with a destroyed execution context before
|
||||
the cancellation condition was reached. Those attempts remain failed diagnostics;
|
||||
they establish no bundled-runtime compatibility or cancellation result.
|
||||
|
||||
## Costs, limits and reproducibility
|
||||
|
||||
Costly operations run serially on one CPU 10 with an 8 GiB hard limit, 6 GiB
|
||||
early stop, no swap and 192 tasks. The passing static gate used 153.534 s wall,
|
||||
152.274161 family CPU seconds and 6,442,016,768 peak cgroup bytes. It reported
|
||||
no OOM and verified payload cleanup. Cgroup memory includes file cache, not RSS.
|
||||
Other trials' exact counters and failures are preserved in the
|
||||
[compact record](electron-cancellation-2026-10-16.json).
|
||||
|
||||
Payload-exit counters are collected while the observer remains alive and are
|
||||
not final whole-scope counters. Some failed probes retain live app/Xvfb processes
|
||||
at that point. Every recorded scope was independently confirmed inactive/dead
|
||||
after the external owner stopped it. That recovery does not establish successful
|
||||
provider cleanup.
|
||||
|
||||
OS/build caches are uncontrolled. A timed-out baseline and a partial fixed
|
||||
workflow do not establish a completed-task speedup. Live event sets also differ,
|
||||
so reply-size differences do not establish token savings. Model billing, peak
|
||||
agent context and complete host/tool-schema token costs are unmeasured. Historical
|
||||
diagnostic helper hashes were not captured at execution; the record marks that
|
||||
gap instead of assigning the later frozen hash to earlier runs.
|
||||
|
||||
Build each pinned checkout, then run under the existing
|
||||
[resource observer](../../experiments/analysis-efficiency/resource-counters.md)
|
||||
and a private Xvfb instance. The shared verifier supports all four named cases:
|
||||
|
||||
```sh
|
||||
node experiments/analysis-efficiency/electron-cancellation.mjs \
|
||||
--runtime-root /absolute/pinned-checkout \
|
||||
--executable /absolute/electron-44.7.0/electron \
|
||||
--application /absolute/Joplin/resources/app.asar \
|
||||
--profile-root /absolute/temporary-profile-parent --case window-wait
|
||||
```
|
||||
|
||||
Use `initial-state`, `final-state` or `normal-wait` for the other boundaries.
|
||||
The public CLI probe has no injected stalled reply:
|
||||
|
||||
```sh
|
||||
python3 experiments/analysis-efficiency/joplin-cli-cancellation.py \
|
||||
--node /absolute/node-24.18.0/bin/node --runtime-root /absolute/pinned-checkout \
|
||||
--executable /absolute/electron-44.7.0/electron \
|
||||
--application /absolute/Joplin/resources/app.asar \
|
||||
--profile-root /absolute/temporary-profile-parent
|
||||
```
|
||||
|
||||
The scripts return failure rather than claiming complete cleanup when the real
|
||||
owned app remains unresolved. App binaries, extracted runtimes/profiles and raw
|
||||
large output are regenerable and are not committed. No macOS, Windows, full
|
||||
Joplin GUI or live-model success is claimed.
|
||||
|
||||
## Review follow-up: verifier exit semantics
|
||||
|
||||
Review of `beb4a47db` found a verifier false pass: the shared probe could exit
|
||||
successfully once its main process had exited even though provider cleanup was
|
||||
still unverified. The CLI probe also accepted `cleanup_incomplete`. Those are
|
||||
verifier bugs; they do not invalidate the recorded failed Joplin trials above.
|
||||
|
||||
Revision `227217ac3` requires verified provider cleanup in both probes and the
|
||||
public `cancelled` category in the CLI. Six controlled oracle cases cover an
|
||||
exited main process with incomplete cleanup, complete cleanup, transport failure
|
||||
after process cleanup, and a wrong public category. Both old scripts fail these
|
||||
regressions; the fixed scripts pass all six. These cases substitute provider/CLI
|
||||
replies and do **not** establish real-provider compatibility or performance.
|
||||
|
||||
The fixed, frozen scripts were then rerun on the same real Joplin artifact. The
|
||||
shared window-wait probe retained cancellation in 5.577 s and explicitly failed
|
||||
because cleanup remained unverified. The public CLI retained category `cancelled`
|
||||
and a cancelled action, published its reply about 6.335 s after SIGTERM, and
|
||||
again failed the first-signal exit deadline. Both verifiers exited nonzero; their
|
||||
externally owned scopes were stopped separately. Production source and the
|
||||
earlier historical records are unchanged. The compact record appends these
|
||||
observations under `review_followup`.
|
||||
|
||||
Run the controlled oracle regressions separately from the real-app commands:
|
||||
|
||||
```sh
|
||||
python3 experiments/analysis-efficiency/electron-cancellation-oracles.py \
|
||||
--node /absolute/node-24.18.0/bin/node
|
||||
```
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,592 +0,0 @@
|
||||
# Electron IPC listener verification, 2026-10-16
|
||||
|
||||
[#4390](https://github.com/morluto/rea/issues/4390), existing
|
||||
[#4389](https://github.com/morluto/rea/pull/4389), umbrella
|
||||
[#4027](https://github.com/morluto/rea/issues/4027).
|
||||
|
||||
All 73 IPC boundary regressions pass, alongside shared projection/actions and
|
||||
converted MCP schema checks. Real draw.io operation phases succeed.
|
||||
Every real capture still **fails overall provider cleanup**. These are distinct
|
||||
results; neither completed-task acceleration nor token savings is established.
|
||||
|
||||
## Producing boundary and regressions
|
||||
|
||||
The existing PR `efd452948` was integrated with main `180ba03bf` in `5c3b02468`.
|
||||
It fixes removal through the caller's original function and duplicate recording
|
||||
of `once` invocations. Independent review found two further producing-boundary
|
||||
problems: wrapper recognition evaluated caller `.listener` getters, and a copied
|
||||
`removeAllListeners` snapshot loop differed from native live-array traversal when
|
||||
removal observers prepended a listener.
|
||||
|
||||
Both new differential cases failed on that implementation (14 passed, two
|
||||
failed). Fix `3c330f259` delegates traversal to Node, translating only owned `on`
|
||||
wrappers at `removeListener`, and preserves the `off` alias. Descriptor reads
|
||||
avoid evaluating getters. A further Proxy case exposed that descriptor reflection
|
||||
can itself run a trap (16 passed, one failed); `2fb7f5523` uses Node's Proxy
|
||||
identity first and removes the superseded catch. Those initial **17 cases** pass;
|
||||
the later decorator finding and final 23-case validation are recorded below.
|
||||
The native EventEmitter controls are semantic regressions, not real-app proof.
|
||||
|
||||
The change uses weak wrapper keys, removes the copied traversal and its snapshot
|
||||
allocation, and adds no tool, cache, schema or normal reply field. Related
|
||||
compiled provider/service modules and catalog metadata were byte-identical to
|
||||
baseline main `180ba03bf` at the initial source freeze. This does not prove
|
||||
arbitrary function introspection equivalence: custom
|
||||
`.listener` properties and raw wrapper re-registration retain the limitations
|
||||
documented in [Electron observation](../electron-observation.md).
|
||||
|
||||
## Unchanged real application and observed scenario
|
||||
|
||||
Official [draw.io Desktop 32.4.1](https://github.com/jgraph/drawio-desktop/releases/tag/v32.4.1)
|
||||
AppImage SHA-256 is
|
||||
`c687a9f1ddcaa146b78547452d264c03c2afcf125639cba5deeb65f3e9554c9e`;
|
||||
both the release asset digest and published checksum file match. Its unchanged
|
||||
62,941,673-byte ASAR is
|
||||
`e64b9650c0b8241ca9a7d33b56386a385bceee63270cec701d3a467347b697e6`.
|
||||
Complete accompanying resources were extracted; no application source was edited.
|
||||
|
||||
Public fuse inspection reports the official executable's Inspector fuse disabled.
|
||||
No vendor Inspector attempt was made. The following trials explicitly select
|
||||
generic Electron **44.7.0**, Xvfb and fresh profiles; they establish no packaged
|
||||
runtime compatibility.
|
||||
|
||||
The real renderer initially displays an **Invalid file data** dialog. A public
|
||||
CLI startup smoke and independent DOM/argv probes preserve this failure, tracked
|
||||
separately in [#4494](https://github.com/morluto/rea/issues/4494). Its exact cause
|
||||
is not proven. Two attempts to click a palette item without handling the dialog
|
||||
timed out and were cancelled; they remain failed diagnostics. An initial helper
|
||||
also incorrectly queried `application.process()` after transport closure; the
|
||||
corrected helper retains the original ChildProcess handle instead.
|
||||
|
||||
The final scenario uses declared REA clicks to dismiss that actual error and
|
||||
insert a visible palette item, then waits for rendering. Independent DOM reads
|
||||
confirm SVG elements **0 → 2**, disappearance of the error and the real unsaved
|
||||
changes indicator. The verifier exercises the real app callbacks and channels;
|
||||
the production hook wraps their registration as described above.
|
||||
The source also registers `app-load-finished` through both `once` and `on`;
|
||||
recording its once callback twice adds a spurious event.
|
||||
|
||||
## Initial fixed-source ABBA observations
|
||||
|
||||
Verifier/source revision is `d02cc934c`; its hashes were recorded before all four
|
||||
trials. Baseline is main `180ba03bf`. The same script, runtime, artifact and
|
||||
declared actions run in the order baseline, candidate, candidate, baseline.
|
||||
|
||||
| Variant/run | IPC events | `app-load-finished` | SVG change | Pipeline wall s | Family CPU s | Peak cgroup bytes |
|
||||
| ----------- | ---------- | ------------------- | ---------- | --------------- | ------------ | ----------------- |
|
||||
| Baseline 1 | 8 | 3 | 0 → 2 | 11.084 | 6.270053 | 560,615,424 |
|
||||
| Candidate 1 | 7 | 2 | 0 → 2 | 11.135 | 6.395461 | 550,383,616 |
|
||||
| Candidate 2 | 7 | 2 | 0 → 2 | 11.898 | 6.907123 | 525,631,488 |
|
||||
| Baseline 2 | 8 | 3 | 0 → 2 | 11.469 | 6.526674 | 558,456,832 |
|
||||
|
||||
Every declared action completed, every insertion oracle passed, and no verifier
|
||||
deadline fired. Every provider returned `cleanup_failed`; the captures remain
|
||||
partial/failed, including possible dirty-editor teardown and the known Linux
|
||||
ownership gap [#4282](https://github.com/morluto/rea/issues/4282). Baseline 2 also
|
||||
reports Xvfb temporary-directory cleanup failure (payload exit 5). Its directory
|
||||
identity was not captured; no broad path-based deletion was attempted.
|
||||
|
||||
Runs are serial on CPU 10 with one-CPU quota, 8 GiB hard memory, 6 GiB early
|
||||
stop, no swap and 192 tasks. Counters cover the cgroup family at payload exit
|
||||
while the observer remains alive; they are **not final whole-scope counters**.
|
||||
Memory includes file cache, not RSS. Some scopes still contain Xvfb at that
|
||||
point; all recorded scopes were later independently confirmed inactive/dead.
|
||||
External recovery does not establish provider cleanup.
|
||||
|
||||
OS/build caches are uncontrolled; these are first/repeat fresh-process runs,
|
||||
not verified cold/warm system pairs. Two samples per variant and a cleanup-bound
|
||||
failed workflow cannot establish a speedup. Token billing, peak agent context,
|
||||
complete schema/call costs and actual MCP-wire parity are unmeasured. Fewer
|
||||
events alone do not establish lower token cost.
|
||||
|
||||
Full static checks passed (two tasks, no cache hits): 89.441 s wall,
|
||||
88.630288 family CPU s and 4,337,172,480 peak cgroup bytes, with no OOM.
|
||||
Documentation checks also passed (6 tasks plus five README consistency cases).
|
||||
The [selected JSON record](electron-ipc-listeners-2026-10-16.json) retains exact
|
||||
source/input identities, failed attempts, coverage, IPC and resource receipts.
|
||||
Historical diagnostic helper hashes were not captured and remain explicitly
|
||||
unknown; the frozen hash is not assigned to them retrospectively.
|
||||
|
||||
## Reproduction
|
||||
|
||||
Build both pinned checkouts. Under the existing resource observer and a private
|
||||
Xvfb instance, use the committed helper for each runtime root in ABBA order:
|
||||
|
||||
```sh
|
||||
node experiments/analysis-efficiency/drawio-electron-lifecycle.mjs \
|
||||
--runtime-root /absolute/pinned-checkout \
|
||||
--executable /absolute/electron-44.7.0/electron \
|
||||
--application /absolute/drawio/resources/app.asar \
|
||||
--profile-root /absolute/temporary-profiles --dismiss-error \
|
||||
--selector '.geSidebar a.geItem:visible >> nth=0'
|
||||
```
|
||||
|
||||
The helper returns failure on incomplete provider cleanup. This shared-service
|
||||
probe does not establish successful public CLI/MCP workflows. App images,
|
||||
extractions/profiles and full Result files are regenerable and excluded from Git.
|
||||
|
||||
## Review follow-up: normalization before app decorators
|
||||
|
||||
Fresh review of `f3bb9b9ed` found that translation inside a patched
|
||||
`removeListener` happened after an application's outer decorator had already
|
||||
seen the recording wrapper. Two native controls reproduced this with stable and
|
||||
replaced decorators (17 passed, two failed).
|
||||
|
||||
`c8c494b5c` delegates the original Node traversal through a private forwarding
|
||||
receiver. It shares the real emitter's live state and translates owned `on`
|
||||
entries **before** invoking the current application removal method. App methods
|
||||
and getters receive the real emitter; read-only method properties remain valid.
|
||||
Native once entries pass unchanged. The public `removeListener`/`off` patches
|
||||
are removed. Five decorator variants pass: stable, replaced, read-only, getter
|
||||
and Proxy.
|
||||
|
||||
An additional mutation case proved that reading a changed public `.listener`
|
||||
getter before delegation also changed deletion timing (22 passed, one failed).
|
||||
Final source `5a094a0df` retains canonical removal targets in the weak owner
|
||||
registry. Only unchanged data links are translated; changed getters run when
|
||||
Node performs removal, preserving the exception and state transition. All
|
||||
**23 cases** pass, including the original retention/fatal-error coverage.
|
||||
|
||||
The same frozen draw.io verifier was reused. The follow-up ABBA attempt ran
|
||||
its first baseline, then the resource launcher refused the other three requests
|
||||
because 8 GiB plus its 4 GiB host reserve was unavailable. Those are **not
|
||||
executed**, with no performance measurements. The final source was separately
|
||||
admitted and completed dialog recovery and insertion with seven IPC events;
|
||||
overall cleanup still failed, and Xvfb teardown also returned an error. No new
|
||||
completed-task speedup or cold/warm pair is claimed.
|
||||
|
||||
Final static checks passed: two uncached tasks, 135.173 s wall, 133.786166 family
|
||||
CPU s and 4,274,634,752 peak cgroup bytes, no OOM. The JSON record appends exact
|
||||
source pins, denial logs, final real-app/public cleanup diagnostics and checks
|
||||
under `review_followup`; the initial records were not overwritten.
|
||||
|
||||
## Callback invocation and remaining raw-metadata limitation
|
||||
|
||||
Source `514b73b78` invokes `handle` callbacks through captured `Reflect.apply`,
|
||||
preserving the receiver and actual arguments without reading an app-defined
|
||||
`.call` property. The added direct-call control and hook case pass; all **24
|
||||
IPC regressions** pass (3.661 s wall, 3.404 family CPU s, 318,291,968 peak cgroup
|
||||
bytes, no OOM). This is a Node boundary check, not a real Electron handle claim.
|
||||
|
||||
An initial three-case experiment incorrectly assumed native EventEmitter avoided
|
||||
callable method-property reads. Its `on` and `once` controls themselves failed;
|
||||
they do not demonstrate hook regressions. The attempted intrinsic event-call
|
||||
change was reverted and those invalid cases removed. Both failed runs remain
|
||||
in `callable_followup`; no successful result is assigned to them.
|
||||
|
||||
The same unchanged draw.io verifier at this source completes actual dialog
|
||||
recovery and shape insertion, with seven IPC events, SVG elements 0 → 2 and an
|
||||
unsaved-changes indicator. Overall provider cleanup still fails. Pipeline wall
|
||||
time is 12.610 s, family CPU 7.062834 s and peak cgroup memory 634,187,776 bytes;
|
||||
there is no paired performance or token claim. All recorded scopes were later
|
||||
independently inactive/dead, which does not establish provider cleanup.
|
||||
|
||||
Fresh review also found a distinct remaining metadata case: changing a raw
|
||||
recording wrapper's writable `.listener` property can make an app decorator
|
||||
reject removal. A production-hook/native-Node probe reproduces this (plain:
|
||||
removed; hook: decorator throws and one listener remains). Exact reproduction
|
||||
and the ownership conflict are tracked in [#4513](https://github.com/morluto/rea/issues/4513).
|
||||
No affected real app has been identified. Removing the descriptor guard alone
|
||||
does not make native removal match the mutated wrapper; temporarily rewriting
|
||||
public app metadata would add further visible mutations. This limitation is
|
||||
explicit in the observation guide and is not represented as fixed by this PR.
|
||||
|
||||
Current-source static checks also pass: two uncached tasks, 92.912 s wall,
|
||||
92.031383 family CPU s and 4,340,375,552 peak cgroup bytes, no OOM.
|
||||
|
||||
## Native single/array dispatch follow-up
|
||||
|
||||
Fresh review of `6fc2d2769` identified that the earlier native controls covered
|
||||
only one listener. Node 24.18.0 reads `.apply` during single-listener dispatch,
|
||||
but invokes each callback intrinsically during array dispatch. Native `once`
|
||||
uses `.call` for zero arguments and `.apply` otherwise. Unconditional `.apply`
|
||||
in the observation helper changed two of those paths: a multi-listener callback
|
||||
could throw before later callbacks ran, and zero-argument once read the wrong
|
||||
property. Four explicit native controls reproduce two failures (26 passed,
|
||||
two failed), rather than assuming all callable-property reads should disappear.
|
||||
|
||||
Source `e8d7e8f20` keeps one observation boundary. An `on` recording wrapper
|
||||
delegates direct calls intrinsically and forwards native `.apply` calls through
|
||||
its own nonenumerable method. Node selects the route; the hook does not inspect
|
||||
or copy listener storage. `once` preserves its native zero/nonzero-argument
|
||||
invocation. All **28 cases** pass, including the prior callback identity,
|
||||
retention, reentrant-removal and fatal-error coverage. `handle` remains intrinsic.
|
||||
|
||||
The unchanged real draw.io verifier again completes dialog recovery and shape
|
||||
insertion, with seven IPC events, SVG elements 0 → 2 and the unsaved indicator.
|
||||
Overall provider cleanup still fails; no deadline fires. Its 12.290 s pipeline
|
||||
run is a validation observation, not a paired performance comparison. Exact
|
||||
source hashes, failures, resource measurements and post-scope states are appended
|
||||
under `native_dispatch_followup`; all previous records remain unchanged.
|
||||
The separate raw metadata limitation [#4513](https://github.com/morluto/rea/issues/4513)
|
||||
remains open and is not represented as fixed.
|
||||
|
||||
Final-source static checks pass: two uncached tasks, 171.430 s wall,
|
||||
169.139239 family CPU s and 4,091,392,000 peak cgroup bytes, no OOM.
|
||||
|
||||
## Argument-list ownership follow-up
|
||||
|
||||
Review of `23700fd2c` found two related representation errors. A raw callback's
|
||||
`.apply` accepts Arguments objects, other array-like objects, null or omitted
|
||||
argument lists; the recording helper assumed an Array. Native once also passes
|
||||
its actual Arguments object to a callback-defined `.apply`, whereas the hook
|
||||
passed a rest Array. Seven explicit native controls reproduce six failures
|
||||
(29 passed, six failed of 35).
|
||||
|
||||
Source `a82d935ba` binds captured native Function apply to the method-forwarding
|
||||
function. JavaScript itself converts argument lists, treats null/undefined as
|
||||
empty and rejects invalid primitives before recording reads values. The
|
||||
array-like getter control is read exactly once. Once retains its actual
|
||||
Arguments object for invocation; recording alone takes an array slice. The
|
||||
captured slice helper is bound once, avoiding an extra helper-argument array
|
||||
on each invocation. No custom array-like parser or exception repair is added.
|
||||
|
||||
All **35 cases** pass. The same frozen real draw.io verifier again completes
|
||||
dialog recovery and shape insertion with seven IPC events; no deadline fires,
|
||||
and overall provider cleanup still fails. Exact source identities, both failed
|
||||
boundaries, intermediate/final tests, resource costs and post-scope states are
|
||||
appended under `argument_list_followup`; previous records remain unchanged.
|
||||
|
||||
Current-source static checks pass: two uncached tasks, 122.454 s wall,
|
||||
121.287057 family CPU s and 4,185,915,392 peak cgroup bytes, no OOM.
|
||||
The unchanged ASAR digest was checked again after the real-app trial.
|
||||
|
||||
## Owned metadata and successful-Evidence verifier follow-up
|
||||
|
||||
Fresh review of `41a513d99` found that `on` wrapper metadata used strict
|
||||
assignment. Native on does not write such metadata, so inherited Function or
|
||||
Object prototype setters/read-only fields could prevent registration only under
|
||||
capture. Four native controls fail before `5dcf79f29` (35 passed, four failed).
|
||||
The recording wrapper now defines its own data property directly; native once
|
||||
assignment behavior is retained. All **39 cases** pass.
|
||||
|
||||
The verifier also incorrectly treated a successful Evidence envelope as a raw
|
||||
capture. Real cleanup failures had exercised only the separate partial path.
|
||||
`4a9a01f7a` reads successful `value.normalized_result` and preserves failed
|
||||
`error.partialObservation.capture`. The new
|
||||
`experiments/analysis-efficiency/drawio-electron-lifecycle-oracles.py` exercises
|
||||
the actual verifier with controlled success, partial cleanup, action failure,
|
||||
insertion failure and absent capture. The old verifier rejects valid successful
|
||||
Evidence before producing a summary; all five corrected controls pass.
|
||||
**These are controlled reply/exit checks, not real-provider evidence.**
|
||||
|
||||
The corrected verifier was separately frozen before a real unchanged draw.io
|
||||
trial. Actual dialog recovery and shape insertion again complete with seven IPC
|
||||
events, no deadline and failed overall provider cleanup (pipeline 12.777 s).
|
||||
Success with real provider cleanup remains unverified. Earlier trials retain
|
||||
their earlier verifier hashes; the corrected hash is not assigned to them.
|
||||
Exact source pins, failed controls, resource costs and post-scope states are
|
||||
appended under `owned_metadata_and_verifier_followup` without replacing history.
|
||||
|
||||
Final-source static checks pass: two uncached tasks, 99.992 s wall,
|
||||
98.956939 family CPU s and 4,237,795,328 peak cgroup bytes, no OOM.
|
||||
|
||||
## Species-free recording and snapshot ownership
|
||||
|
||||
Fresh review of `e2cf2d89b` found that slicing a rest Array invokes application
|
||||
`Array[Symbol.species]` before dispatch. The first control reproduced failed on
|
||||
dispatch (40 passed, one failed); once dispatch already used Arguments.
|
||||
Extending the check to retrieve the retained snapshot while the throwing getter
|
||||
remains installed exposed the same representation problem in snapshot maps
|
||||
(39 passed, two failed).
|
||||
|
||||
Source `3141ac3f4` records from actual invocation frames while preserving native
|
||||
callback argument-list types: the method-based on path still passes an Array,
|
||||
and once passes Arguments. Group validation uses the existing recording loops
|
||||
without a filtered intermediate Array. Captured `Array.from` produces snapshots
|
||||
without species lookup, reading dropped-counter Maps directly rather than
|
||||
spreading them into another Array first. The initial **41 cases** pass, including both
|
||||
live snapshots under the throwing getter with zero getter reads.
|
||||
|
||||
The frozen-source real unchanged draw.io operation again completes recovery and
|
||||
insertion with seven IPC events, no deadline and failed overall cleanup
|
||||
(pipeline 12.779 s). This does not establish that draw.io customizes species.
|
||||
The corrected verifier and its five previously passing controlled oracles are
|
||||
byte-identical to `4a9a01f7a`, so those unchanged oracle sources were reused.
|
||||
Exact hashes, failures, resource receipts and scope states are appended under
|
||||
`array_species_followup`; earlier records remain unchanged. There is no new
|
||||
completed-task performance or token/context claim.
|
||||
|
||||
The native multiple-listener route was then included in the same live-species
|
||||
control: all **42 cases** pass. Only test coverage expanded; production hook
|
||||
and verifier bytes remain identical to `3141ac3f4`. Exact validation identities
|
||||
and the additional result are recorded under `all_native_dispatch_paths`.
|
||||
|
||||
A fresh-profile real negative control omits `--selector` while retaining dialog
|
||||
recovery and the same 500 ms wait. SVG elements remain **0 → 0** and unsaved
|
||||
changes remain false; insertion gives **0 → 2** and unsaved true. This supports
|
||||
the operation oracle rather than attributing startup rendering to the click.
|
||||
The control also returns seven IPC events and failed provider cleanup. These
|
||||
are different tasks, not a performance pair or a model-cell-count proof.
|
||||
|
||||
Final 42-case source validation includes two uncached static tasks passing in
|
||||
94.234 s wall, 93.308800 family CPU s and 4,406,538,240 peak cgroup bytes,
|
||||
with no OOM. These are verification costs, not an application speedup.
|
||||
|
||||
## Opaque apply inputs and iterator-free snapshots
|
||||
|
||||
Fresh review of `84d9cf5db` found two producing-boundary regressions: native
|
||||
array-like conversion replaced the argument-list object before a custom
|
||||
listener `.apply` received it, and `Array.from` snapshots consulted application
|
||||
iterators on retained arrays/Maps. Four exact-input native controls and two
|
||||
snapshot controls fail before correction (42 passed, six failed of 48).
|
||||
|
||||
Source `e442ca27f` forwards custom `.apply` the original receiver and method
|
||||
arguments without interpreting its opaque list. Custom apply may transform
|
||||
arguments or skip callback execution, so the hook emits a bounded
|
||||
`ipc-observation-gap` timeline record with the known registration channel. It
|
||||
does not fabricate a main-event invocation, argument shapes or callback result.
|
||||
The shared result projection retains explicit uncertainty and counts dropped
|
||||
gaps through existing retention. The canonical timeline enum adds that kind;
|
||||
the captured-IPC subset does not. Native apply still performs its own conversion
|
||||
before an actual callback frame is observed.
|
||||
|
||||
Snapshots now copy arrays through private null-prototype indexed views and
|
||||
counters through captured native Map traversal. Neither retained buffers nor
|
||||
counter Maps are exposed to application iterators; returned records and shape
|
||||
arrays remain independent copies. No cache, tool or normal-dispatch metadata
|
||||
is added. The raw-wrapper metadata limitation in #4513 remains unfixed.
|
||||
|
||||
The focused hook/projection/actions gate passes **68 cases** (48 + 4 + 16).
|
||||
The separate MCP/schema gate passes **23 cases**: an actual SDK client receives
|
||||
the gap alongside ordinary IPC Evidence, and Ajv2020 validates the advertised
|
||||
converted output; all canonical tool schemas also pass their existing checks.
|
||||
These tests use controlled providers and establish no real-provider success.
|
||||
The verifier and its five controlled exit/summary oracles are hash-identical to
|
||||
the earlier passing source and are reused without another redundant run.
|
||||
|
||||
## Unrelated CI baseline failure
|
||||
|
||||
CI run `38935598884` tested synthetic merge `eedae92d406015895a6d0eced5035da1b9ead07a`
|
||||
(head `84d9cf5db`, base `9d940c2f2`). Two firmware cleanup tests failed; another
|
||||
shard was cancelled by fail-fast. A fresh, unmodified detached checkout of that
|
||||
exact base reproduces the same failures: **33 passed, two failed** in
|
||||
`tests/boundary/firmware/firmwareIntegration.test.ts`. Evidence is posted on
|
||||
[the PR](https://github.com/morluto/rea/pull/4389#issuecomment-6221054273) and
|
||||
[existing #4475](https://github.com/morluto/rea/issues/4475#issuecomment-6221054775).
|
||||
This establishes that these failures predate the Electron changes; it does not
|
||||
resolve whether the firmware producer or its expectations need correction. No
|
||||
firmware code or assertions are changed here, and required CI is not bypassed.
|
||||
|
||||
The first final-source real request fails before application launch because the
|
||||
previous `/tmp` runtime is absent. It is retained as an input-resolution failure,
|
||||
not a provider measurement. The cached Electron 44.7.0 archive is verified against
|
||||
the official release SHASUMS256 and extracted into a new owned task directory;
|
||||
its executable/archive digests are pinned before the next request. No target
|
||||
source, vendor fuse or scenario success requirement is changed.
|
||||
|
||||
The recovered-runtime real operation completes all three declared actions:
|
||||
SVG elements **0 → 2**, unsaved changes true, seven IPC events, no deadline.
|
||||
Overall provider cleanup still fails. Current-source static validation passes
|
||||
two uncached tasks in **94.646 s wall, 93.878644 family CPU s and 4,300,570,624
|
||||
peak cgroup bytes**, no OOM. The initial static attempt's test-only SDK/Ajv type
|
||||
error is retained; parsing that boundary fixes it, and 12 affected client and
|
||||
projection cases pass again. `opaque_apply_and_iterator_followup` preserves all
|
||||
source pins, failures, resource receipts and independently checked scope states
|
||||
without replacing earlier measurements. Draw.io does not establish that real
|
||||
applications exercise the synthetic custom-apply/iterator cases.
|
||||
|
||||
The final documentation gate also passes six tasks and five README consistency
|
||||
cases. Source and unchanged ASAR hashes are checked again after validation.
|
||||
|
||||
## Borrowed apply receivers
|
||||
|
||||
Fresh review of `7541a900c` supplied the borrowed custom-method case
|
||||
`raw.apply.call(g, emitter, list)`: the plain emitter runs `g`, while the hook
|
||||
hard-coded its registered callback as the method receiver. The same hard-coded
|
||||
receiver also affected borrowed native apply. Both native differential controls
|
||||
fail before correction (48 passed, two failed of 50).
|
||||
|
||||
Source `da04465fe` maps only the hook wrapper itself to the original listener
|
||||
when forwarding custom apply; other method receivers pass unchanged. Native
|
||||
apply uses its actual receiver, preserving both ordinary wrapper recording and
|
||||
borrowed-call dispatch. The hook does not fabricate a registered callback
|
||||
invocation when another callable is selected. The method-forwarding boundary is
|
||||
corrected directly; no new helper, state, tool or schema is added. All **70**
|
||||
hook/projection/actions cases pass (50 + 4 + 16). Shared schema/client, projection
|
||||
and verifier/oracle sources are byte-identical to the prior passing versions,
|
||||
so their checks are reused by verified hash.
|
||||
|
||||
CI run `38943919946` is confirmed by the successful build checkout log and Git
|
||||
parents to use merge `98c14dfc01fe4698a50eedc8b1cd1ac9cd03267d`
|
||||
(head `7541a900c`, main `4838f4449`). Its fifth shard fails the same two firmware
|
||||
cleanup tests as the unmodified `9d940c2f2` base control. The relevant firmware
|
||||
source/test and package paths have no changes between these main revisions.
|
||||
The REST PR `base.sha` remains stale at `2c7583599`; it is not used as the CI
|
||||
identity. No firmware code/assertion or required-check bypass is included.
|
||||
|
||||
The frozen-source unchanged draw.io operation completes recovery/insertion
|
||||
again with seven IPC events, SVG **0 → 2**, unsaved changes true and failed
|
||||
overall provider cleanup. Pipeline: **12.038 s wall, 6.662295 family CPU s,
|
||||
598,835,200 peak cgroup bytes**. This remains a partial workflow, not a speedup
|
||||
claim. Final static checks pass two uncached tasks in **108.067 s wall,
|
||||
106.996233 family CPU s and 4,430,647,296 peak cgroup bytes**, no OOM.
|
||||
All prior measurements remain unchanged under `borrowed_apply_followup`.
|
||||
|
||||
The final documentation gate also passes six tasks and five README consistency
|
||||
cases. Current source digests are checked again after validation.
|
||||
|
||||
## Listener-owner intrinsic lifetime
|
||||
|
||||
Fresh review of `f5b489c1b` found that late application replacement of
|
||||
`Object.defineProperty` prevents the hook's new wrapper properties from being
|
||||
created, while a plain native emitter still registers/invokes its callbacks.
|
||||
Inspection of this same new registration/removal owner found its other late
|
||||
property/constructor lookups. Seven independent native controls replace
|
||||
`Object.defineProperty`, `Object.getOwnPropertyDescriptor`, `Object.create`,
|
||||
`Reflect.get`, `Reflect.set`, global `Set` or global `Proxy`; each fails before
|
||||
correction (50 passed, seven failed of 57). The controls include both on/once
|
||||
execution and complete removal, with globals restored after the scenario.
|
||||
|
||||
Source `a9c5611d0` captures the owner's descriptor/property operations and private
|
||||
constructors before application startup. The private receiver uses a direct
|
||||
null-prototype object literal instead of looking up Object.create. All **77**
|
||||
hook/projection/actions cases pass (57 + 4 + 16). Application-owned callback
|
||||
methods and actual receivers retain their existing semantics. No tool, schema,
|
||||
state, target authority or general-purpose hardening layer is introduced; this
|
||||
is not complete JavaScript introspection equivalence. Unchanged schema/client,
|
||||
projection and verifier/oracle checks are reused by verified source hashes.
|
||||
|
||||
The preceding CI run `38946503183` tests confirmed merge
|
||||
`fcd7a9d92a2e64d6eb96d4fabfed7fc7f44b0d45` (head `f5b489c1b`, main `4838f4449`).
|
||||
Its 36 jobs finish with 29 successes, the same two firmware failures causing
|
||||
three failed jobs including summaries, and four fail-fast cancellations. The
|
||||
fifth-shard log again names the two cases reproduced on untouched main. No
|
||||
firmware code/assertions or required checks are altered.
|
||||
|
||||
Frozen-source real unchanged draw.io actions complete again with seven IPC
|
||||
events, SVG **0 → 2**, unsaved changes true, no deadline and failed overall
|
||||
provider cleanup. Pipeline wall is **11.429 s**. Observed payload-exit cgroup
|
||||
counters are 6.441029 CPU s and 550,363,136 peak bytes, but the observer still
|
||||
sees one additional scope descendant: **family resource observation is
|
||||
unverified**, not a complete-family performance measurement. The scope is later
|
||||
inactive/dead after external recovery; this does not verify provider cleanup.
|
||||
No identity or cleanup cause is inferred from the remaining PID.
|
||||
|
||||
Final static checks pass two uncached tasks in **90.980 s wall, 90.119351 family
|
||||
CPU s and 4,338,749,440 peak cgroup bytes**, no OOM. Source identities, all seven
|
||||
failures and resource limitations are appended under `listener_intrinsics_followup`
|
||||
without replacing any previous measurements.
|
||||
|
||||
The final docs gate passes six tasks and five README consistency cases; source
|
||||
digests are checked again after validation.
|
||||
|
||||
## Private collection method lifetime
|
||||
|
||||
Fresh review of `e6c373d0` found that replacing `WeakMap.prototype.has` after
|
||||
hook initialization still intercepts its private wrapper registry. Inspecting
|
||||
the same owner found analogous get/set and visited-Set has/add lookups. All five
|
||||
independent native controls fail before correction (57 passed, five failed of
|
||||
62); plain EventEmitter registration, on/once calls and complete removal succeed.
|
||||
|
||||
Source `774ed6aa6` binds these private WeakMap/Set methods before application
|
||||
startup and reuses captured Set membership for event-family classification.
|
||||
One initialization-only binding helper replaces duplicated binding construction
|
||||
for existing Map traversal/argument slicing too. It adds no helper argument
|
||||
arrays per invocation, cache, schema, tool or target authority. Application-owned
|
||||
callback methods/receivers remain dynamic. All **82** hook/projection/actions
|
||||
cases pass (62 + 4 + 16). The previous seven global-binding controls also remain
|
||||
green, and unchanged schema/client/projection/verifier/oracle checks are reused
|
||||
by verified source hashes. Arbitrary introspection and #4513 remain unsupported.
|
||||
|
||||
Frozen-source unchanged draw.io actions complete again with seven IPC events,
|
||||
SVG **0 → 2**, unsaved changes true and failed overall provider cleanup. Pipeline
|
||||
wall **11.238 s**; observed payload-exit cgroup CPU **6.285321 s**, peak
|
||||
**556,285,952 bytes**. Another scope descendant remains at payload exit, so complete-family resource observation is unverified. Later external scope teardown does not prove provider cleanup.
|
||||
|
||||
Final static checks pass two uncached tasks in **92.999 s wall, 92.227652 family
|
||||
CPU s and 4,371,951,616 peak cgroup bytes**, no OOM. Preceding CI38949129899 checks
|
||||
confirmed e6c3 + main4838, repeats the same two firmware failures and finishes
|
||||
31 successful /3 failed jobs including summaries /2 fail-fast cancellations.
|
||||
Sources, failures and resource limitations are appended under
|
||||
`private_collection_methods_followup`; prior fields remain unchanged.
|
||||
|
||||
The final docs gate passes six tasks and five README consistency cases; source
|
||||
digests are verified again afterward.
|
||||
|
||||
## Unknown listener-chain ownership
|
||||
|
||||
Fresh review of `0b4f2e81` found that the bounded Boolean chain test treats a
|
||||
still-unexamined function as fresh when 17 app decorators hide an owned once
|
||||
wrapper. Two emits then produce three invocation records for one actual once
|
||||
callback. The same unknown-as-fresh error affects accessor/Proxy links. Four
|
||||
native controls fail before correction (63 passed, four failed of 67); the
|
||||
16-decorator boundary already passes. A deep ordinary on control confirms
|
||||
missing ownership cannot justify fabricated captured IPC either.
|
||||
|
||||
Source `ef46b8f0b` classifies metadata as owned, unowned or unknown. Bounded-walk
|
||||
exhaustion, accessor links and Proxies preserve native registration without
|
||||
adding another recording wrapper. Successful unknown registrations retain a
|
||||
bounded `listener-chain` gap; this is not proof of IPC delivery. An existing
|
||||
inner wrapper may still report its actual once invocation. Shared native
|
||||
data-descriptor parsing preserves accessor uncertainty at recognition/removal
|
||||
and avoids inherited descriptor-value interpretation. The superseded Boolean
|
||||
classification is removed.
|
||||
|
||||
The shared projection explains both gap boundaries and retention/coverage, and
|
||||
an actual MCP SDK client receives custom-apply and listener-chain gaps alongside
|
||||
ordinary IPC Evidence, validated by its converted advertised schema. All **96**
|
||||
hook/projection/actions/MCP cases pass (67 + 5 + 16 + 8). A test-only lint length
|
||||
failure is corrected by generating repeated fixture rows from one table without
|
||||
relaxing rules; all **13** affected client/projection cases pass again. The
|
||||
canonical schema and unchanged verifier/five controlled oracle sources retain
|
||||
their earlier passing checks by verified hashes; the changed projection/client
|
||||
are freshly tested rather than claimed unchanged.
|
||||
|
||||
Prior CI run `38951509761` uses confirmed merge
|
||||
`fa090a6bde3a5dadeb71066824477292520fb43b` (0b4f + mainf31b231a). All **36 jobs
|
||||
succeed**. The earlier unrelated firmware failures do not recur in this
|
||||
combination; their cause is not inferred or claimed fixed here. Current-source
|
||||
CI/review remain required. No firmware code/assertions were modified.
|
||||
|
||||
Frozen-source unchanged draw.io recovery/insertion again completes with seven
|
||||
IPC events, SVG **0 → 2**, unsaved true, no deadline and failed overall provider
|
||||
cleanup. Pipeline wall **11.163 s**; observed payload-exit cgroup CPU **6.203177 s**,
|
||||
peak **547,418,112 bytes**. An extra scope descendant leaves complete-family
|
||||
resource observation unverified; later inactive/dead scope after external
|
||||
recovery does not establish provider cleanup.
|
||||
|
||||
Final static checks pass two uncached tasks in **88.383 s wall, 87.726306 family
|
||||
CPU s and 4,399,632,384 peak cgroup bytes**, no OOM. All source identities, failed
|
||||
controls, corrected fixture-only lint failure and resource caveats are appended
|
||||
under `chain_ownership_followup`; historical fields are unchanged.
|
||||
|
||||
Final docs validation passes six tasks and five README consistency cases;
|
||||
current source digests are verified again afterward.
|
||||
|
||||
## Inherited listener-link coverage
|
||||
|
||||
Fresh review of `ae2cd8d4` found that a missing own descriptor is not absence:
|
||||
an app decorator can inherit its data link to an owned once wrapper. Native
|
||||
removal follows that link and removes the decorator; the hook hid it under
|
||||
another recorder, left a listener installed and produced three invocation
|
||||
records for one callback. Five native inherited-link cases fail before correction
|
||||
(68 passed, five failed of 73): data/getter/Proxy prototypes and prototype
|
||||
depths16/17. A late Object.getPrototypeOf replacement control already passes.
|
||||
|
||||
Source `e22ce9aaf` completes bounded native prototype lookup at the descriptor
|
||||
owner, capturing getPrototypeOf before startup. Data links retain their actual
|
||||
source value. A setter-only property has a known undefined read that shadows
|
||||
ancestors; a getter, Proxy or incomplete walk remains unknown. Missing metadata becomes absent only after the prototype chain ends; found
|
||||
properties retain native read/shadowing semantics. Registration and removal consume
|
||||
the same parsed descriptor, and redundant outer Proxy interpretation is removed.
|
||||
Neither existing resource bound is raised. All **102** hook/projection/actions/
|
||||
MCP cases pass (73 + 5 + 16 + 8). Projection/client are freshly tested unchanged
|
||||
sources; canonical schema and verifier/oracles retain prior checks by hash.
|
||||
|
||||
Prior CI run38955237255 tests confirmed merge9c0ceb152c902c1339806608f8b4a010c3d22fc6
|
||||
(ae2c + main8116dc06). All36 jobs succeed; current-head CI/review remain required.
|
||||
|
||||
Frozen-source unchanged draw.io recovery/insertion again completes with seven
|
||||
IPC events, SVG **0 → 2**, unsaved true and failed overall provider cleanup.
|
||||
Pipeline: **11.264 s wall /6.376574 family CPU s /557,068,288 peak cgroup bytes**.
|
||||
Payload-exit observation is verified at that phase while the observer lives;
|
||||
these are not final whole-scope counters or provider cleanup proof.
|
||||
|
||||
Final static checks pass two uncached tasks in **90.797 s wall, 90.096799 family
|
||||
CPU s and 4,335,267,840 peak cgroup bytes**, no OOM. All source identities, native
|
||||
failures and current results are appended under `inherited_listener_links_followup`;
|
||||
previous fields and earlier resource caveats remain unchanged.
|
||||
|
||||
Final docs validation passes six tasks and five README consistency cases;
|
||||
current source digests are verified again afterward.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,142 +0,0 @@
|
||||
# Native Electron once dispatch — 2026-10-16
|
||||
|
||||
#4593 was reported by review of #4562, but its source was already in main from
|
||||
#4389. The initial report was explicitly source-only; subsequent paired controls
|
||||
confirmed the bug. This change delegates `once` creation, firing and callable
|
||||
selection to the actual runtime and observes only established callback entry.
|
||||
CLI and MCP continue to share the same hook, event model, projection and retained
|
||||
Evidence. No new tool, schema, execution authority or analysis cache is introduced.
|
||||
|
||||
## Paired native controls
|
||||
|
||||
The baseline is `709b5cbdc15aa757f89c38ecd12e5a47710747a6`. Final source is
|
||||
`4ebd0f60e860daa57a7033c6e77ea7f5f4b8ac97`, including the two review-gap fixes below. Earlier source cohort
|
||||
`c0b52b5408fa97013798e6ecee885ccac08e7356` contains the fix; the final cleanup
|
||||
commit is `e60c4a1098321ed2a7f564ae35909a31d707694f`, which removes the obsolete fifth helper argument and
|
||||
unreachable copied call/apply dispatch branches after inspecting every caller.
|
||||
The pre-review gap-owner follow-up is `7f05f476c52498adba41d943ead1a86e7216ca76`. The adjacent JSON preserves
|
||||
source hashes and separate measurement cohorts, including the initial 93-row prefix.
|
||||
The final review JSONL contains 117 paired rows (39 inputs × 3 runtimes). The
|
||||
earlier 96-row JSONL remains unchanged, including its initial 93-row prefix. Both
|
||||
comparisons have identical native
|
||||
control facts in each before/after pair. Regenerable binaries, apps, profiles
|
||||
and multi-MB raw captures are excluded from Git.
|
||||
|
||||
| Actual engine | Cases | Baseline behavioral differences | Fixed differences |
|
||||
| ---------------------------------------------------------- | ----: | ------------------------------: | ----------------: |
|
||||
| Node 24.18.0 (pinned) | 39 | 4 | 0 |
|
||||
| Official Node 24.21.0 | 39 | 16 | 0 |
|
||||
| Generic Electron 44.7.0 embedded Node 24.21.0, run as Node | 39 | 16 | 0 |
|
||||
|
||||
The original 21-case reproduction found 0/9/9 differences respectively. The
|
||||
pre-review 32-case cohort found 1/13/13. The final 39-case suite adds readonly
|
||||
callback methods, emitter method invariants, native metadata writes, failure
|
||||
recovery and non-callable callback methods. The extra pinned-runtime difference is registration
|
||||
metadata ordering. On the newer runtimes, opaque callback methods can suppress
|
||||
callbacks under the old hook although native dispatch executes them. The pinned
|
||||
runtime also catches false invocation records when an opaque method legitimately
|
||||
skips the callback. The added regression fails on the baseline for that false fact.
|
||||
|
||||
These are **controlled producer cases with a minimal Electron module**, including
|
||||
the actual embedded Node binary, not a real GUI application's natural callback
|
||||
loss. Native traces, receiver checks, failures and remaining listeners are compared
|
||||
exactly. Expected property reads are derived from each runtime rather than copied
|
||||
from one Node implementation. The custom-apply guard still checks its original
|
||||
Arguments representation when the runtime actually invokes that method.
|
||||
|
||||
## Ownership and uncertainty
|
||||
|
||||
Native once wrappers keep their public callback identity and descriptor attributes.
|
||||
The registration receiver forwards methods/getters to the original emitter and
|
||||
supports readonly method descriptors. A private callable receives an actual
|
||||
Arguments frame, avoiding application Array species/iterators when recording.
|
||||
Metadata recognition and admission share one bounded descriptor lookup.
|
||||
|
||||
An application-selected opaque call/apply can bypass observation; a bounded
|
||||
`custom-call`/`custom-apply` gap replaces invented invocation facts. Opaque native
|
||||
metadata writes or registration lookups keep the exact original callback/native
|
||||
operation and emit `once-metadata` gaps. The temporary unobserved scope is restored
|
||||
even if registration throws. The 39-case suite checks this recovery, including a native alias that bypasses
|
||||
patched `on`; the once owner retains the observation gap for that path. #4513 raw
|
||||
recording-wrapper mutation remains explicitly unfixed.
|
||||
|
||||
Review found two missing failure facts: a decorator can register through an
|
||||
unhooked alias and then throw, and a runtime can read a non-callable call/apply
|
||||
property before dispatch fails. Both new regressions fail on the pre-review
|
||||
source. The once owner now finalizes its missing gap in `finally`, after restoring
|
||||
the scope; the callable metadata owner records a failed gap while preserving the
|
||||
exact non-callable value. Error identity and native callback behavior are retained.
|
||||
|
||||
Two short-lived proxies are used for an observable once registration. Metadata
|
||||
remains weakly retained, and existing event/serialization budgets remain in force.
|
||||
The added registration cost was not isolated; no speed or token improvement is
|
||||
claimed. The saved producer comparison is a correctness experiment, not a whole
|
||||
application performance benchmark. Its runner reports differences instead of
|
||||
exiting unsuccessfully for an expected bad baseline; the regression tests assert
|
||||
that fixed behavior matches native behavior and observation claims are truthful.
|
||||
|
||||
## Real application verification
|
||||
|
||||
Unchanged Joplin Desktop 3.7.21 ASAR and explicit generic Electron 44.7.0 run the
|
||||
shipped welcome note/1075×666 PNG → actual resource context menu → app bridge →
|
||||
blocked reveal workflow. The image stays visible, page errors remain empty,
|
||||
reveal events increase 0→1, and the shared retained capture contains the exact
|
||||
event. Both staged hook files are hashed against the selected source before launch.
|
||||
No synthetic application IPC channels or replacement app callbacks are added.
|
||||
|
||||
The argv shim is an explicit test adapter for the still-failing standard startup
|
||||
#2974. **Overall provider cleanup remains failed (#4282)** and the verifier exits
|
||||
nonzero. External scope teardown is not provider cleanup. The first frozen real
|
||||
pipeline takes 17.680 s; observed payload-exit CPU 16.272793 s and peak 1,395,253,248 B
|
||||
have an extra descendant, so complete-family observation is **unverified**. The
|
||||
cleanup cohort is recorded separately. The pre-review 32-case source repeats the real
|
||||
operation successfully, but overall cleanup still fails: 18.074 s pipeline, observed
|
||||
CPU 17.011774 s / peak 1,422,839,808 B; complete-family measurement remains unverified. No completed public CLI/MCP workflow,
|
||||
real Windows/macOS run, natural app callback-loss reproduction or full check:pr
|
||||
is claimed.
|
||||
|
||||
The final review source repeats the same real operation: 18.353 s pipeline,
|
||||
observed CPU 17.098599 s / peak 1,387,556,864 B; complete-family measurement remains
|
||||
unverified and overall provider cleanup fails. An earlier trial failed to initialize
|
||||
the display because the provider environment omits XAUTHORITY. That launch is
|
||||
preserved separately; the fresh final trial uses local Xvfb with `-nolisten tcp -ac`,
|
||||
not a production provider change.
|
||||
|
||||
Frozen local validation: 75 hook cases on both Node versions; 5 projection + 8 MCP
|
||||
cases on the unchanged shared contracts; static checks pass (final 118.946 s wall / 117.752622 s CPU / 4,282,826,752 B
|
||||
cgroup peak, verified payload-exit family observation). The pinned final run uses
|
||||
`test:focused`; an attempted `test:local` invocation was rejected before tests ran
|
||||
and is recorded as not executed. See JSON for exact
|
||||
commands/cohorts, failed candidate attempts, source pins and measured resources.
|
||||
Failures include the Array-species frame, readonly receiver invariants, metadata
|
||||
setter identity, on-getter ordering, a lint/interoperability correction and helper
|
||||
preparation failures. They are not relabeled as results from the final source.
|
||||
|
||||
All heavy work runs serially with CPU 10/quota 1, 8 GiB hard/6 GiB early/no swap/192 tasks.
|
||||
Counters are captured at payload exit with the observer alive, not final whole-scope
|
||||
counters; cgroup peak includes file cache. Each final Joplin run has a new private
|
||||
configuration mount. Filesystem/runtime/build caches are warm; cold-system and
|
||||
warm-repeat costs are unmeasured. Agent/billed tokens and public reply/context
|
||||
costs are unmeasured. The broad internal error capture size is not an agent-token
|
||||
measurement. All owned scopes are checked inactive/dead independently.
|
||||
|
||||
## Reproduce the producer comparison
|
||||
|
||||
Use the pinned project toolchain and explicitly provided alternate runtimes.
|
||||
The alternate Node 24.21 archive is checked against [official checksums](https://nodejs.org/download/release/v24.21.0/SHASUMS256.txt);
|
||||
its archive/binary hashes are recorded. No global toolchain is upgraded.
|
||||
|
||||
```sh
|
||||
python3 experiments/analysis-efficiency/electron-once-runtimes.py \
|
||||
--hook-root /absolute/checkout-to-measure \
|
||||
--node /absolute/pinned-node \
|
||||
--node /absolute/node24.21 \
|
||||
--electron /absolute/generic-electron44.7 \
|
||||
--output /absolute/owned-output
|
||||
```
|
||||
|
||||
Run this under the recorded resource wrapper. For a baseline comparison, use a
|
||||
clean checkout of 709b5cbd as hook-root while keeping the same current oracle/runner.
|
||||
The runner retains full JSON and prints a compact summary. The real Joplin recipe
|
||||
is in [the shell verifier record](electron-shell-sync-2026-10-16.md); select the
|
||||
current runtime-root. That workflow must remain nonzero while cleanup fails.
|
||||
@@ -1,117 +0,0 @@
|
||||
{"runtime":0,"mode":"plain","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"plain","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"plain","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"call-opaque","arguments":0,"native":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-call","error":false}]}
|
||||
{"runtime":0,"mode":"call-opaque","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"call-opaque","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-opaque","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-opaque","arguments":1,"native":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":false}]}
|
||||
{"runtime":0,"mode":"apply-opaque","arguments":3,"native":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":false}]}
|
||||
{"runtime":0,"mode":"call-readonly","arguments":0,"native":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-call","error":false}]}
|
||||
{"runtime":0,"mode":"call-readonly","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"call-readonly","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-readonly","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-readonly","arguments":1,"native":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":false}]}
|
||||
{"runtime":0,"mode":"apply-readonly","arguments":3,"native":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":false}]}
|
||||
{"runtime":0,"mode":"call-getter","arguments":0,"native":{"body_calls":0,"correct_receiver":true,"trace":["get:call","opaque:call"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:call","opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:call","opaque:call"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-call","error":false}]}
|
||||
{"runtime":0,"mode":"call-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"call-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-getter","arguments":1,"native":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":false}]}
|
||||
{"runtime":0,"mode":"apply-getter","arguments":3,"native":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":false}]}
|
||||
{"runtime":0,"mode":"call-throwing-getter","arguments":0,"native":{"body_calls":0,"correct_receiver":true,"trace":["get:call"],"error":"Error: getter:call","listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:call"],"error":"Error: getter:call","listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:call"],"error":"Error: getter:call","listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-call","error":true}]}
|
||||
{"runtime":0,"mode":"call-throwing-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"call-throwing-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-throwing-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-throwing-getter","arguments":1,"native":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":true}]}
|
||||
{"runtime":0,"mode":"apply-throwing-getter","arguments":3,"native":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":true}]}
|
||||
{"runtime":0,"mode":"call-non-callable","arguments":0,"native":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: this.listener.call is not a function","listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.call is not a function","listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: this.listener.call is not a function","listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-call","error":true}]}
|
||||
{"runtime":0,"mode":"call-non-callable","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"call-non-callable","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-non-callable","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"apply-non-callable","arguments":1,"native":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: this.listener.apply is not a function","listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.apply is not a function","listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: this.listener.apply is not a function","listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":true}]}
|
||||
{"runtime":0,"mode":"apply-non-callable","arguments":3,"native":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: this.listener.apply is not a function","listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.apply is not a function","listeners_after":0},"candidate_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: this.listener.apply is not a function","listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"custom-apply","error":true}]}
|
||||
{"runtime":0,"mode":"inherited-listener-setter","arguments":0,"native":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"baseline_hooked":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"candidate_hooked":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":0,"mode":"on-getter-listener-setter","arguments":0,"native":{"body_calls":1,"reads":1,"writes":[true],"public_identity":false,"error":null},"baseline_hooked":{"body_calls":1,"reads":1,"writes":[],"public_identity":true,"error":null},"candidate_hooked":{"body_calls":1,"reads":1,"writes":[true],"public_identity":false,"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":0,"mode":"on-getter-native-alias","arguments":0,"native":{"body_calls":1,"reads":1,"listeners_after":0},"baseline_hooked":{"body_calls":1,"reads":1,"listeners_after":0},"candidate_hooked":{"body_calls":1,"reads":1,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":0,"mode":"on-getter-native-alias-throws","arguments":0,"native":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"baseline_hooked":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"candidate_hooked":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":true}]}
|
||||
{"runtime":0,"mode":"throwing-listener-setter","arguments":0,"native":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"baseline_hooked":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"candidate_hooked":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":true},{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":0,"mode":"readonly-emitter-methods","arguments":0,"native":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"baseline_hooked":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"candidate_hooked":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"plain","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"plain","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"plain","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-opaque","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-opaque","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-opaque","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-opaque","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-opaque","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-opaque","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-readonly","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-readonly","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-readonly","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-readonly","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-readonly","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-readonly","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:call","opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-throwing-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:call"],"error":"Error: getter:call","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-throwing-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-throwing-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-throwing-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-throwing-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-throwing-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-non-callable","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.call is not a function","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-non-callable","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"call-non-callable","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-non-callable","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-non-callable","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.apply is not a function","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"apply-non-callable","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.apply is not a function","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"inherited-listener-setter","arguments":0,"native":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"baseline_hooked":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"candidate_hooked":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":1,"mode":"on-getter-listener-setter","arguments":0,"native":{"body_calls":1,"reads":1,"writes":[true],"public_identity":false,"error":null},"baseline_hooked":{"body_calls":1,"reads":1,"writes":[],"public_identity":true,"error":null},"candidate_hooked":{"body_calls":1,"reads":1,"writes":[true],"public_identity":false,"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":1,"mode":"on-getter-native-alias","arguments":0,"native":{"body_calls":1,"reads":1,"listeners_after":0},"baseline_hooked":{"body_calls":1,"reads":1,"listeners_after":0},"candidate_hooked":{"body_calls":1,"reads":1,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":1,"mode":"on-getter-native-alias-throws","arguments":0,"native":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"baseline_hooked":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"candidate_hooked":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":true}]}
|
||||
{"runtime":1,"mode":"throwing-listener-setter","arguments":0,"native":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"baseline_hooked":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"candidate_hooked":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":true},{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":1,"mode":"readonly-emitter-methods","arguments":0,"native":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"baseline_hooked":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"candidate_hooked":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"plain","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"plain","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"plain","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-opaque","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-opaque","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-opaque","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-opaque","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-opaque","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-opaque","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-readonly","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-readonly","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-readonly","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-readonly","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-readonly","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-readonly","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:call","opaque:call"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply","opaque:apply"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-throwing-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:call"],"error":"Error: getter:call","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-throwing-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-throwing-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-throwing-getter","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-throwing-getter","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-throwing-getter","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":["get:apply"],"error":"Error: getter:apply","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-non-callable","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.call is not a function","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-non-callable","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"call-non-callable","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-non-callable","arguments":0,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:0"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-non-callable","arguments":1,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.apply is not a function","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:1"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"apply-non-callable","arguments":3,"native":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_hooked":{"body_calls":0,"correct_receiver":true,"trace":[],"error":"TypeError: listener.apply is not a function","listeners_after":0},"candidate_hooked":{"body_calls":1,"correct_receiver":true,"trace":["body:3"],"error":null,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":true}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"inherited-listener-setter","arguments":0,"native":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"baseline_hooked":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"candidate_hooked":{"body_calls":1,"writes":[true],"public_identity":false,"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":2,"mode":"on-getter-listener-setter","arguments":0,"native":{"body_calls":1,"reads":1,"writes":[true],"public_identity":false,"error":null},"baseline_hooked":{"body_calls":1,"reads":1,"writes":[],"public_identity":true,"error":null},"candidate_hooked":{"body_calls":1,"reads":1,"writes":[true],"public_identity":false,"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":2,"mode":"on-getter-native-alias","arguments":0,"native":{"body_calls":1,"reads":1,"listeners_after":0},"baseline_hooked":{"body_calls":1,"reads":1,"listeners_after":0},"candidate_hooked":{"body_calls":1,"reads":1,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":false}]}
|
||||
{"runtime":2,"mode":"on-getter-native-alias-throws","arguments":0,"native":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"baseline_hooked":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"candidate_hooked":{"body_calls":1,"same_error":true,"public_identity":true,"listeners_after":0},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":true}]}
|
||||
{"runtime":2,"mode":"throwing-listener-setter","arguments":0,"native":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"baseline_hooked":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"candidate_hooked":{"body_calls":1,"writes":[true],"error":"Error: metadata-write","listeners_after":1},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"ipc-observation-gap","event":"once-metadata","error":true},{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
{"runtime":2,"mode":"readonly-emitter-methods","arguments":0,"native":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"baseline_hooked":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"candidate_hooked":{"body_calls":1,"seen":["on:true","removeListener:true"],"error":null},"baseline_observation":[{"kind":"main-event-invocation","event":null,"error":false}],"candidate_observation":[{"kind":"main-event-invocation","event":null,"error":false}]}
|
||||
Loaded 100 of 1734 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user