Compare commits

..
Author SHA1 Message Date
Kaoru0822andClaude Opus 5.5 b6d8bb65d3 docs(readme): add responsible-use guidance and reframe the introduction
Reframe the tagline and opening paragraph around security research,
interoperability and authorized analysis. Add a "Responsible use"
section before Quick start that lists unsupported uses and the user's
legal responsibilities, replace the Notes example prompt with a
release-versus-debug crash investigation, and point the Disclaimer at
the new section while keeping the cryptocurrency statement.

Apply the same changes to all 18 translated READMEs, with anchors
matching each translated heading.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 06:03:22 +00:00
1053 changed files with 39096 additions and 129893 deletions
@@ -2,7 +2,7 @@
name: reverse-engineer-anything
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA. Use shipped-artifact or requested runtime evidence to explain features, compare versions, decompile code, or guide a reconstruction. Skip REA for ordinary source-repository architecture analysis.
metadata:
version: "41"
version: "39"
---
# REA
@@ -61,41 +61,12 @@ explicit path or endpoint and do not need it.
consult the NativeAOT workflow in `references/native-and-artifacts.md` for
optional metadata recovery and its supported host/layout boundary.
- User-owned browser page already open: `list_browser_targets`.
- Fiddler Everywhere traffic or a native `.saz` capture: read the
[Fiddler workflow](references/runtime-observation.md#fiddler-everywhere-traffic-debugging).
Inspect saved SAZ with `inspect_web_network_capture` and `format: "saz"`;
connect Everywhere's separate MCP server for live traffic.
- Retained HAR/SAZ/native mitmproxy/aioquic qlog capture: `inspect_web_network_capture`. Select
- Retained HAR/native mitmproxy capture: `inspect_web_network_capture`. Select
original record ordinals when useful; inspect producer fields and byte/number
sidecars without fetching recorded URLs or claiming live attribution. See
[historical captures](https://github.com/morluto/rea/blob/main/docs/web-network-captures.md) for the exact upstream
profile and credential exclusions. Qlog support starts with aioquic 1.5.0
JSON 0.3; stream coverage and endpoint loss declarations do not recover bodies
or establish network loss. Prefer detail summary, then kind qlog trace/stream
pages; select one trace, stream ID and direction for contribution/range pages.
Facts retain all-recorded-events-before-selection scope. Other qlog layouts
and PCAP correlation are unsupported.
profile and credential exclusions.
- User-owned Electron runtime already open: `list_electron_targets`.
- Recorded packet captures: `inspect_packet_capture` with selected TShark fields,
display filters and decode-as rules. Requires Linux, util-linux prlimit and `REA_TSHARK_COMMAND`; see
[capture guide](https://github.com/morluto/rea/blob/main/docs/packet-captures.md).
Packet limits count input packets before filtering. Output defaults to 50 matching
frames; use `match_offset` / `match_limit` for later pages, or explicit null
limit for complete matching output. Preserve the source digest across pages.
This does not perform live capture.
For address/DNS/SNI/protocol summaries use `inspect_pcap_capture` with MCP
detail summary, then retained kind pcap pages. Requires Wireshark 4.x tshark
and capinfos, with Linux prlimit or Windows Job Objects; see
[packet summaries](https://github.com/morluto/rea/blob/main/docs/pcap-analysis.md).
Select an exact DNS question for address pages; page exhaustion does not prove
network completeness. This reads recordings and does not acquire traffic.
- Recorded logic/signal traces: `decode_signal_recording` with explicit decoder,
channel and protocol settings. On Linux with util-linux prlimit, supply sigrok-cli 0.7.2 through
`REA_SIGROK_COMMAND`; see [recording guide](https://github.com/morluto/rea/blob/main/docs/signal-recordings.md).
Output defaults to 50 literal lines; select annotation classes and page with
`line_offset` / `line_limit`, or explicit null for all remaining output.
Window counts are display lines, not annotations or samples. Preserve source digests across pages.
This reads existing files; it does not acquire hardware signals.
- Explicit local WebAssembly artifact: `inspect_wasm_artifact`. Supply WABT 1.0.42
through `REA_WABT_BIN_DIRECTORY`; retain exact byte/tool identity and decoded WAT.
Select JavaScript glue and candidate paths explicitly and preserve URL/path
@@ -104,11 +75,7 @@ explicit path or endpoint and do not need it.
- Explicit local EVM bytecode carrier: `inspect_evm_interface` with caller-selected
`raw` or `hex` encoding. Preserve carrier/decoded digests and treat selectors,
argument strings and mutability as inferred candidates; this performs no chain
lookup or target execution. For the complete inferred interface without hex or
duplicate stdout, discover support and select `detail: "summary"`; complete
Evidence stays retained under its original identity. Use the returned
`parent_evidence_id` for exact function or `bytecode_hex`/stdout/stderr pages.
Candidate coverage does not establish interface completeness. See the
lookup or target execution. See the
[EVM bytecode guide](https://github.com/morluto/rea/blob/main/docs/evm-bytecode.md).
- Embedded Go compiler, module or build-setting metadata: `inspect_go_binary`
with the explicit local file. This built-in target-free inspection requires no
@@ -116,15 +83,6 @@ explicit path or endpoint and do not need it.
absent metadata does not prove a binary is not Go, and unparsed text records
remain explicit. See the
[Go binary guide](https://github.com/morluto/rea/blob/main/docs/go-binaries.md).
- Explicit local SQLite database snapshot: `inspect_sqlite_database`. Inspect
with Node.js 24.x >=24.15 or 26+ providing native SQLite limits. Read schema
first (compact inventory by default), or select an exact ordinary table
and `columns` when rows are needed. Defaults are selected-table schema and
20 rows; request `schema_scope: "database"` for the complete stored schema. Preserve both database and existing sibling WAL identity; row samples
report truncation and have unspecified order. Use a quiescent snapshot rather
than assuming a live database/WAL pair was copied atomically. See the
[SQLite guide](https://github.com/morluto/rea/blob/main/docs/sqlite-databases.md).
- Explicit Linux ELF file for offline layout, symbols, relocations or static
mitigation evidence: `inspect_binary_layout`. This target-free operation uses
caller-supplied pwntools without opening a disassembler database. Preserve its
@@ -45,8 +45,8 @@ rea setup --client codex --dry-run --json
Use the current supported client's ID: `claude_code`, `claude_desktop`, `codex`,
`cursor`, `gemini_cli`, `windsurf`, `devin`, `opencode`, `antigravity`,
`copilot_cli`, `commandcode`, `qwen_code`, `vscode`, `trae`, `grok_build`, `omp`, `pi`,
`hermes`, `qoder`, `zcode`, `dsh`, or `grok_bot`. If unknown, inspect `doctor --json` before choosing a
`copilot_cli`, `commandcode`, `qwen_code`, `vscode`, `grok_build`, `omp`, `pi`,
`hermes`, `dsh`, or `grok_bot`. If unknown, inspect `doctor --json` before choosing a
scope. `grok_bot` uses a chat registration step rather than local `mcp.json`.
For unsupported clients, use version-pinned manual stdio registration or CLI.
@@ -11,19 +11,6 @@ returned inline. When complete `inspect_binary_layout` or
`inspect_analysis_view` for a summary, one section/symbol/module, or a stable
page instead of repeating the producer.
Completed `inspect_artifact` inventory also supports a summary and
`view: {kind: "inventory", collection: "occurrences", logical_paths: ["package.json", "main.js"]}`.
Omit `logical_paths` to page all available occurrences; `[]` selects none.
Other inventory collections are `nodes`, `edges` and
`integrity_contradictions`. Keep `source_complete` separate from page exhaustion:
a missing match in partial source Evidence does not establish absence. Use the
returned parent Evidence ID for subsequent views and export before closing the
session when the source must survive it.
When `tools/list` advertises `inspect_artifact.detail`, request `"summary"` to
retain its complete source and receive that view immediately. Without that
advertised choice, keep the existing complete call. CLI inspection returns
portable complete Evidence; save it before projecting a selected inline view.
Use `record_unknown` to track unresolved questions in the user's investigation
and name the authority or environment still required. Supply supporting and
contradicting evidence IDs. It updates the session registry directly.
@@ -11,21 +11,6 @@ unparsed module-text line. A missing record is an unknown, not proof of a
non-Go binary; observed metadata does not authenticate its claims. Function,
source and type recovery remain a separate native-analysis question.
## SQLite snapshots
Use `inspect_sqlite_database` with an explicit local database snapshot for its
schema and optional rows from one exact ordinary table. It requires Node.js
24.x >=24.15 or 26+ with the native `DatabaseSync.limits` API. It also consumes the
existing sibling `-wal`; retain both original digests when citing its result.
Default output is a compact inventory; a selected table expands only its own
schema and samples 20 rows. Select `columns` to avoid irrelevant or large cells,
and request `schema_scope: "database"` only for complete schema details.
Choose `row_limit` when a finite sample is useful and keep truncation and
unspecified row order explicit. Virtual tables, shadow tables and views are
schema facts, not row-read targets. REA inspects private copies and leaves
the source files untouched; obtain a coherent quiescent database/WAL snapshot
before inspection. See [SQLite snapshots](https://github.com/morluto/rea/blob/main/docs/sqlite-databases.md).
## Recorded Linux crashes
Use `inspect_recorded_crash` with an explicit Linux x86-64 ELF core path to
@@ -51,20 +36,6 @@ retained, call `inspect_analysis_view` for a summary, mitigations or linkage
facet, one section or symbol, or a stable page. Do not re-run the decoder to
read a single object.
## Offline WASM
Use `inspect_wasm_artifact` with caller-supplied WABT for selected local bytes.
For counts, validation and WAT identity, select `detail: "summary"` on the first
MCP call. The complete original Evidence stays retained; use
`normalized_result.parent_evidence_id` for exact exports or text pages. Omitted
or complete detail keeps the existing complete result.
For a completed result, use `inspect_analysis_view` with its reported retained
reference for a summary or `view: {kind: "wasm", facet: "exports", offset: 0, limit: 32}`.
Facets also include sections, imports, candidates, glue, WAT, headers, details
and tool profile. Text offsets count UTF-16 code units; follow `next_offset`.
The complete source remains retained after an oversized MCP reply. No target
execution or network acquisition is implied, and WAT is decoded representation.
## Native targets
After `open_binary`, use focused search, procedure, or function tools directly.
@@ -135,18 +106,6 @@ assembly. Keep managed/native boundaries and unavailable reconstruction facts
explicit. A bring-your-own reconstruction oracle is separate from the canonical
parser and must not become an implicit setup dependency.
For identity/classification questions, `inspect_managed_artifact` can explicitly
select `detail: "summary"` on the first MCP call. It retains complete metadata
and returns a linked overview with full classification/evidence, nullable
module/MVID, frameworks, metadata coverage/issues/limitations and returned-row
counts. Default complete requests remain unchanged. Read original rows with
`inspect_analysis_view`, source `normalized_result.parent_evidence_id`, and
`view: {kind: "managed", collection: "attributes", offset: 0, limit: 16}`.
Collections are `references`, `resources` and `attributes`. Paging does not
repeat parsing. Returned-row exhaustion
does not prove complete metadata or absence under partial/unavailable coverage;
preserve build-local tokens and their artifact/MVID scope.
### .NET NativeAOT
NativeAOT binaries contain native machine code, so ordinary CIL decompilers
@@ -162,15 +121,15 @@ them. For packaged apps, inventory/extract with REA's artifact tools and retain
the exact contained image identity. PDB, ELF debug, or dSYM sidecars are
additional evidence only when the provider accepts and matches them.
REA has a built-in read-only snapshot parser for x64 PE targets with .NET 8 RTR
9.1 metadata. An optional headless Ghidra adapter adds database annotations and
broader metadata recovery on Linux; it requires an explicitly configured
NativeAOT JAR. These are separate routes. See the
[NativeAOT guide](https://github.com/morluto/rea/blob/main/docs/ghidra-nativeaot.md)
for setup, supported layouts, and host restrictions. Preserve binary identity
and distinguish derived metadata from Ghidra database observations. Recovered
types and native pseudocode are not original C# source. Windows Ghidra P0 has
no database mutation authority.
For deeper type recovery, the optional third-party
[Ghidra NativeAOT analyzer](https://github.com/Washi1337/ghidra-nativeaot)
rehydrates ReadyToRun metadata and can recover method tables, type relationships,
frozen objects, and strings. This is a Ghidra extension with its own install and
interactive workflow; it is not currently part of REA's managed parser or
headless Ghidra bridge. Treat its annotations as analysis evidence, retain the
binary identity, and do not present recovered types as original source. Header
discovery may require a symbol or analyst identification of the ReadyToRun
header, depending on the binary and analyzer version.
## Packages and extraction
@@ -194,9 +153,8 @@ every executable in the bundle. It also lists missing or weak loads and earlier
`architecture`. System paths stay undetermined because the dyld shared cache
provides them.
Use `extract_artifact` when materialized files are needed. It extracts the active
target and accepts optional `integrity_policy`; see the [MCP contracts](https://github.com/morluto/rea/blob/main/docs/mcp-contracts.md).
It materializes all regular files into a fresh temporary directory chosen by
Use `extract_artifact` when materialized files are needed. It takes no arguments
and materializes all regular files into a fresh temporary directory chosen by
REA. Symlinks and encrypted entries are inventory facts, not extractable files.
The result reports the materialized directory; callers do not choose the
destination. No separate permission grant is needed.
@@ -26,18 +26,3 @@ passive browser/Electron Evidence exist. Prefer captured-source digest identity;
report path/digest disagreement as a mismatch and preserve ambiguity. Explicit
path mappings are inference inputs and never broaden filesystem or CDP authority.
A bundle observed at runtime does not prove every contained module executed.
## Fiddler Everywhere traffic debugging
For large saved captures, request `detail: "summary"`, then page retained Evidence
with `inspect_analysis_view` and `view: {kind: "capture", detail: "preview", offset: 0, limit: 20}`.
Select complete record pages only for needed headers, metadata or payloads; views
read the historical parent without repeating capture decoding.
Inspect native `.saz` snapshots with `inspect_web_network_capture` and
`format: "saz"`; encrypted archives are unsupported. For live
traffic analysis, connect Everywhere's separate MCP server and use its
advertised session tools with an explicit `sessionsSource` (`LiveTraffic` or
`AgentCalls`). Preserve existing sessions and filters when inspecting a
recorded run. See the [capture and MCP guide](https://github.com/morluto/rea/blob/main/docs/web-network-captures.md)
for the workflow and Telerik's public setup and traffic-debugging skills.
-3
View File
@@ -3,6 +3,3 @@
# Windows command fixtures retain their native line endings.
*.cmd text eol=crlf
# Preserve whitespace in original upstream licensing texts.
licenses/npm-runtime-notices.txt whitespace=-blank-at-eol
-3
View File
@@ -1,8 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Contribution scope and integration requirements
url: https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope
about: Check supported capabilities, excluded workflows, and the fail-closed integration rule before proposing a feature.
- name: REA Documentation
url: https://github.com/morluto/rea#readme
about: Read the README and AGENTS.md for usage guides and configuration details.
+13 -55
View File
@@ -1,5 +1,5 @@
name: Design discussion
description: Discuss an REA architecture, provider, contract, or scope decision
description: Resolve an REA architecture, provider, or contract question before implementation
title: "[Design] "
labels:
- enhancement
@@ -9,12 +9,7 @@ body:
attributes:
value: |
Use this for a substantial provider, public/persisted contract, or
authority-boundary decision. One question and a short explanation are
enough to start. Choose "Not sure yet" where needed; maintainers can help
with technical details, alternatives, and verification.
Read the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope).
Unresolved boundaries block integration, not opening a discussion.
authority-boundary decision. Keep one decision per discussion.
- type: checkboxes
id: before-submitting
@@ -23,16 +18,14 @@ body:
options:
- label: I searched the open and closed issues and pull requests for a related discussion.
required: true
- label: I understand the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope) must be reviewed before integration; open questions are welcome here.
required: true
- label: This discussion does not include credentials, private samples, or sensitive target data.
- label: I removed credentials, tokens, private paths, and sensitive target data.
required: true
- type: textarea
id: decision
attributes:
label: Decision needed
description: What would you like maintainers to help decide? A short question is enough.
description: State the exact question maintainers need to resolve.
placeholder: Should REA ... or ...?
validations:
required: true
@@ -41,57 +34,23 @@ body:
id: context-evidence
attributes:
label: Context and evidence
description: Explain the problem or motivation. If you have evidence, distinguish observed behavior from ideas or guesses.
validations:
required: true
- type: dropdown
id: target-interaction
attributes:
label: Expected interaction with targets
description: >-
Select all known effects, including upstream tool behavior. Add "Not sure
yet" if anything is unclear. Use "No target interaction" only on its own.
These selections help discussion and do not establish scope approval.
multiple: true
options:
- Read existing files or captured data
- Launch or attach to a process
- Inject instrumentation or run scripts/code
- Change process memory or registers
- Write or change files/configuration
- Contact network services
- Recover protected code or work around protections
- No target interaction (documentation or usability only)
- Not sure yet
description: Explain why the decision is needed now. Separate observed behavior, derived evidence, and inference.
validations:
required: true
- type: textarea
id: boundary-invariants
attributes:
label: Boundary details (optional)
description: >-
If known, clarify target selection, selected effects, provider boundaries,
non-goals, or evidence invariants. Leave blank if you need help identifying
them. Do not include private samples or proof-of-authorization documents.
label: Boundary and invariants
description: Identify the owning layer, provider/bridge boundary, artifact or evidence invariants, and any process or authorization constraints.
validations:
required: true
- type: textarea
id: options
attributes:
label: Options and tradeoffs
description: Optional approaches or tradeoffs. One idea is enough; maintainers can help compare alternatives.
- type: dropdown
id: verification-readiness
attributes:
label: Verification available so far
description: Pick the closest match. An idea without samples or test results is welcome.
options:
- Idea only; I need help defining checks
- I can suggest a sample or manual check
- I have a prototype or observed results
- Not sure yet
description: Compare a small number of viable approaches, including platform, compatibility, safety, evidence, and maintenance costs.
validations:
required: true
@@ -99,10 +58,9 @@ body:
id: success-criteria
attributes:
label: Success criteria and open questions
description: >-
Optional expected output, sample, possible check, or unresolved question.
A complete test plan is not required to start; maintainers and implementers
will resolve material verification gaps before integration.
description: State what outcome would settle the decision and list only unresolved questions that could change the choice.
validations:
required: true
- type: textarea
id: references
+11 -64
View File
@@ -8,13 +8,9 @@ body:
- type: markdown
attributes:
value: |
Describe one problem and the outcome you would like. Short answers are
welcome. Choose "Not sure yet" wherever needed; you do not need code, a
finished design, or a complete test plan to propose an idea.
Read the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope).
Maintainers can help resolve scope and technical questions. Unresolved
boundaries block integration, not opening a request for discussion.
Keep one primary capability or workflow outcome per request. For a
substantial provider, public contract, or architecture change, explain
the decision maintainers need to make before implementation.
- type: checkboxes
id: before-submitting
@@ -23,9 +19,7 @@ body:
options:
- label: I searched the open and closed issues and pull requests for a related proposal.
required: true
- label: I understand the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope) must be reviewed before integration; open questions are welcome here.
required: true
- label: This request does not include credentials, private samples, or sensitive target data.
- label: I removed credentials, tokens, private paths, and sensitive target data.
required: true
- type: dropdown
@@ -42,7 +36,6 @@ body:
- MCP or agent integration
- Documentation
- Other
- Not sure yet
validations:
required: true
@@ -50,7 +43,7 @@ body:
id: current-limitation
attributes:
label: Current limitation
description: What are you trying to understand or do, and what is difficult today? A short example is enough.
description: What user or agent workflow is blocked, ambiguous, or unnecessarily difficult today?
validations:
required: true
@@ -58,69 +51,23 @@ body:
id: use-cases
attributes:
label: Use cases
description: Optional additional examples of applications, targets, or callers. Leave blank if covered above.
description: Give concrete applications, targets, callers, or investigation workflows. Explain why current tools are insufficient.
validations:
required: true
- type: textarea
id: desired-outcome
attributes:
label: Desired outcome and success criteria
description: What would a useful result look like? Describe the output or behavior you want; implementation details are optional.
placeholder: For a selected APK, show whether it is packed and include the detection evidence.
validations:
required: true
- type: dropdown
id: target-interaction
attributes:
label: Expected interaction with targets
description: >-
Select all known effects, including upstream tool behavior. Add "Not sure
yet" if anything is unclear. Use "No target interaction" only on its own.
These selections help discussion and do not establish scope approval.
multiple: true
options:
- Read existing files or captured data
- Launch or attach to a process
- Inject instrumentation or run scripts/code
- Change process memory or registers
- Write or change files/configuration
- Contact network services
- Recover protected code or work around protections
- No target interaction (documentation or usability only)
- Not sure yet
description: Describe observable behavior, inputs, outputs, evidence, and compatibility criteria that would make this useful.
validations:
required: true
- type: textarea
id: boundaries
attributes:
label: Target and scope details (optional)
description: >-
If known, name the target/platform, clarify selected effects, or list a
non-goal or scope question. You can leave this blank; maintainers can help.
Do not include private samples or proof-of-authorization documents.
- type: dropdown
id: verification-readiness
attributes:
label: Verification available so far
description: Pick the closest match. An idea without samples or test results is welcome.
options:
- Idea only; I need help defining checks
- I can suggest a sample or manual check
- I have a prototype or observed results
- Not sure yet
validations:
required: true
- type: textarea
id: verification
attributes:
label: Verification details (optional)
description: >-
Share an expected output, a possible check, or existing results if you have
them. Self-owned or appropriately licensed samples can help, but are not
required to open a request. Do not attach private or sensitive data.
label: Authority boundaries and non-goals
description: Call out process execution, target mutation, provider licensing, evidence provenance, supported platforms, and work that should remain out of scope.
- type: textarea
id: alternatives
@@ -11,7 +11,7 @@ runs:
id: plan
shell: bash
env:
BUILD_CACHE_PREFIX: rea-portable-build-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc', '.nvmrc', 'package-lock.json') }}
BUILD_CACHE_PREFIX: rea-portable-build-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc') }}
run: |
npm run --silent test:prepare -- --dry=json |
node --input-type=module -e '
@@ -25,7 +25,6 @@ runs:
}).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.save != 'true'
@@ -33,11 +32,9 @@ runs:
with:
path: .turbo/cache/
key: ${{ steps.plan.outputs.key }}
restore-keys: ${{ steps.plan.outputs.prefix }}
- name: Restore and save portable build outputs
if: inputs.save == 'true'
uses: actions/cache@v4
with:
path: .turbo/cache/
key: ${{ steps.plan.outputs.key }}
restore-keys: ${{ steps.plan.outputs.prefix }}
+3 -29
View File
@@ -19,39 +19,17 @@ describe the use case and observable outcome. -->
<!-- Explain the chosen approach, why it fits REA's architecture, and what is
intentionally not included. -->
Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope).
Unresolved scope, authority, side effects, or required verification block
integration. Link the required maintainer scope decision for new providers or
capabilities involving target execution, injection, mutation, or protection
recovery; ordinary fixes within existing boundaries may state "not applicable".
Draft PRs may leave the scope decision pending and the final review checklist
unchecked. Maintainers can help resolve open questions.
## Contract and boundary impact
<!-- Short answers are welcome. Complete applicable lines; mark unresolved facts as "unknown".
Use "none" or "not applicable" only when established. -->
<!-- Complete the applicable lines; use "none" or "not applicable" explicitly. -->
- Semantic owner and earliest changed stage:
- Contribution scope fit and linked maintainer decision:
- CLI and MCP/tool-catalog contract:
- Provider, bridge, target-format, or platform compatibility:
- Evidence, artifact, provenance, or reconstruction contract:
- Target selection, authority, upstream behavior, and cleanup details (if applicable):
- Process execution, authorization, cleanup, or containment impact:
- Generated metadata (`docs/public/product-catalog.json`), package, or installation impact (CI generates and validates ignored catalogs and `skills/`; edit authored instructions in `.agents/skills/reverse-engineer-anything/` and never commit build outputs):
Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.
- [ ] Read existing files or captured data.
- [ ] Launch or attach to a process.
- [ ] Inject instrumentation or run scripts/code.
- [ ] Change process memory, registers, files, or configuration.
- [ ] Contact network services.
- [ ] Recover protected code or work around protections.
- [ ] Documentation or usability only; no target interaction.
- [ ] Not sure yet; investigation or maintainer guidance needed.
## Evidence and regression coverage
<!-- State whether evidence is executed, source-derived, or proposed. For fixes,
@@ -90,13 +68,9 @@ limits, security/privacy/containment implications, and meaningful proof gaps. --
- Package or release metadata impact:
- Security, privacy, process, or containment review:
## Before merge
<!-- Draft PRs may leave pending items unchecked. Resolve material scope and
authority questions before integration. -->
## Review checklist
- [ ] This PR addresses a concrete problem or an agreed enhancement.
- [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
- [ ] The PR has one focused outcome and the title follows `type(scope): outcome`.
- [ ] Related issue is linked, or the reason for not linking one is stated above.
- [ ] Tests cover changed observable behavior and meaningful failure paths.
+34 -59
View File
@@ -77,7 +77,7 @@ jobs:
static:
name: Static checks
needs: changes
if: ${{ !cancelled() }}
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Require successful change classification
@@ -94,20 +94,8 @@ jobs:
run: npm run check:ci
- if: needs.changes.outputs.code == 'true'
run: npm run verify:test-discovery
- name: Check LLDB producer retention and launch contracts
if: needs.changes.outputs.code == 'true'
run: npm run test:python
- if: needs.changes.outputs.code != 'true'
run: npm run format:check
- name: Upload complete static diagnostics
if: always() && needs.changes.outputs.code == 'true'
uses: actions/upload-artifact@v4
with:
name: static-check-reports
path: .cache/static-checks/
include-hidden-files: true
if-no-files-found: ignore
retention-days: 7
test-shard:
name: Test shard (${{ matrix.shard }})
@@ -117,7 +105,7 @@ jobs:
strategy:
fail-fast: false
matrix:
shard: [1/6, 2/6, 3/6, 4/6, 5/6, 6/6]
shard: [1/4, 2/4, 3/4, 4/4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@@ -180,7 +168,7 @@ jobs:
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: test-timings
name: test-results
run-id: ${{ steps.history.outputs.run-id }}
github-token: ${{ github.token }}
path: .cache/ci-test-history
@@ -209,21 +197,20 @@ jobs:
if-no-files-found: error
retention-days: 7
sqlite-runtime:
needs: [changes, build]
if: needs.changes.outputs.code == 'true'
uses: ./.github/workflows/sqlite-runtime.yml
test:
name: Test (coverage + timing)
needs: [changes, test-shard]
if: ${{ !cancelled() }}
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Require successful change classification
- name: Require successful test shards
env:
CHANGES_RESULT: ${{ needs.changes.result }}
run: test "${CHANGES_RESULT}" = "success"
CODE_REQUIRED: ${{ needs.changes.outputs.code }}
SHARD_RESULT: ${{ needs.test-shard.result }}
run: |
test "${CHANGES_RESULT}" = "success"
test "${CODE_REQUIRED}" != "true" || test "${SHARD_RESULT}" = "success"
- uses: actions/checkout@v4
if: needs.changes.outputs.code == 'true' && success()
- uses: actions/setup-node@v4
@@ -240,7 +227,6 @@ jobs:
pattern: vitest-report-*
merge-multiple: true
- name: Merge coverage, JUnit, and timing reports
id: merge
if: needs.changes.outputs.code == 'true' && success()
run: >-
npm run test:ci:merge --
@@ -254,13 +240,27 @@ jobs:
--outputFile.junit=test-results.xml
--outputFile.json=test-results.json
- name: Summarize slowest test files
if: needs.changes.outputs.code == 'true' && !cancelled() && hashFiles('test-results.json') != ''
env:
SHARD_RESULT: ${{ needs.test-shard.result }}
MERGE_RESULT: ${{ steps.merge.outcome }}
run: node scripts/ci/test-report.mjs
if: needs.changes.outputs.code == 'true' && success()
shell: bash
run: |
node <<'NODE' >> "${GITHUB_STEP_SUMMARY}"
const report = JSON.parse(require("node:fs").readFileSync("test-results.json", "utf8"));
const files = (report.testResults ?? [])
.map((result) => ({
name: result.name,
duration: Math.max(0, (result.endTime ?? result.startTime) - result.startTime),
}))
.sort((left, right) => right.duration - left.duration)
.slice(0, 20);
console.log("## Slowest deterministic test files\n");
console.log("| File | Duration (ms) |");
console.log("| --- | ---: |");
for (const file of files) {
console.log(`| \`${file.name}\` | ${file.duration} |`);
}
NODE
- uses: actions/upload-artifact@v4
if: needs.changes.outputs.code == 'true' && !cancelled() && hashFiles('test-results.json') != ''
if: needs.changes.outputs.code == 'true' && always()
with:
name: test-results
path: |
@@ -269,21 +269,6 @@ jobs:
coverage/
if-no-files-found: error
retention-days: 30
- name: Publish successful timing history
if: needs.changes.outputs.code == 'true' && success() && needs.test-shard.result == 'success'
uses: actions/upload-artifact@v4
with:
name: test-timings
path: .cache/ci-test-history/test-results.json
include-hidden-files: true
if-no-files-found: error
retention-days: 30
- name: Require successful test shards
if: ${{ !cancelled() }}
env:
CODE_REQUIRED: ${{ needs.changes.outputs.code }}
SHARD_RESULT: ${{ needs.test-shard.result }}
run: test "${CODE_REQUIRED}" != "true" || test "${SHARD_RESULT}" = "success"
conformance-fixtures:
name: Source-built conformance fixtures
@@ -387,7 +372,7 @@ jobs:
apple-artifacts:
name: Real Apple artifact CLI/MCP E2E
needs: [changes, build]
needs: changes
if: needs.changes.outputs.apple == 'true'
runs-on: macos-15
timeout-minutes: 15
@@ -398,10 +383,6 @@ jobs:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- uses: actions/download-artifact@v4
with:
name: rea-build-cache
path: .turbo/cache/
- name: Verify Apple artifact formats and metadata
env:
REA_ARTIFACT_NODE_COMPILE_CACHE: ${{ runner.temp }}/rea-artifact-node-cache
@@ -464,7 +445,7 @@ jobs:
windows-curated:
name: Windows capability and package lane
needs: [changes, build, windows-native-build]
needs: [changes, windows-native-build]
if: needs.changes.outputs.package == 'true'
runs-on: windows-latest
timeout-minutes: 25
@@ -475,11 +456,8 @@ jobs:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- uses: actions/download-artifact@v4
with:
name: rea-build-cache
path: .turbo/cache/
- run: npm run build:cached
- run: npm run typecheck
- uses: actions/download-artifact@v4
with:
name: windows-native-controls
@@ -509,7 +487,6 @@ jobs:
tests/boundary/providers/native/artifactProvider.extractionCompleteness.test.ts
tests/boundary/filesystem/setupUnavailableProvider.test.ts
tests/boundary/filesystem/windowsNpxRegistration.test.ts
tests/acceptance/setup/homeDirectoryFallback.test.ts
tests/boundary/filesystem/webScriptManifestPaths.test.ts
tests/boundary/process/ProcessEvidence.host.test.ts
tests/acceptance/webModuleCli.test.ts
@@ -519,7 +496,6 @@ jobs:
tests/boundary/filesystem/javascript-applications/javascriptArtifactReconstruction.test.ts
tests/conformance/providers/ghidra/windowsCapabilities.test.ts
src/ghidra/GhidraInstallation.test.ts
tests/boundary/filesystem/ghidraJavaProbe.test.ts
tests/boundary/providers/ghidra/ghidraTransport.test.ts
tests/boundary/providers/ghidra/ghidraTargetSnapshot.test.ts
tests/boundary/providers/ghidra/ghidraLauncher.test.ts
@@ -657,7 +633,7 @@ jobs:
required:
name: CI required
if: ${{ !cancelled() }}
if: ${{ always() }}
needs:
[
changes,
@@ -665,7 +641,6 @@ jobs:
static,
build,
test-shard,
sqlite-runtime,
test,
conformance-fixtures,
windows-native-build,
-58
View File
@@ -1,58 +0,0 @@
name: Real packet capture
on:
workflow_dispatch:
pull_request:
paths:
- "tests/boundary/captures/**"
- "tests/boundary/cli/captureCleanup.test.ts"
- "tests/boundary/mcp/packetCaptureMcp.test.ts"
- "src/captures/**"
- "src/pcap/**"
- "src/domain/pcap/**"
- "src/domain/analysisView/pcapCaptureView.ts"
- "src/application/pcap/**"
- "src/contracts/pcap/**"
- "src/server/registerPcapTools.ts"
- "tests/boundary/pcap/**"
- "src/domain/captures/**"
- "src/application/captures/**"
- "src/contracts/captures/**"
- "src/composition/captures.ts"
- "src/cli/captureCommands.ts"
- "src/server/registerCaptureTools.ts"
- "src/server/createServer.ts"
- "src/server/sessionAvailabilityPolicy.ts"
- "src/application/CapabilityInventory.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/process/**"
- "src/artifacts/readStableArtifact.ts"
- "scripts/verify-packet-capture.mjs"
- ".github/workflows/real-packet-capture.yml"
- "package*.json"
- ".nvmrc"
permissions:
contents: read
concurrency:
group: real-packet-capture-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
tshark:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- 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 -- 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
REA_CAPINFOS_COMMAND: /usr/bin/capinfos
@@ -1,50 +0,0 @@
name: Real signal recording
on:
workflow_dispatch:
pull_request:
paths:
- "tests/boundary/signals/**"
- "tests/boundary/cli/signalCleanup.test.ts"
- "tests/boundary/mcp/signalRecordingMcp.test.ts"
- "src/signals/**"
- "src/domain/signals/**"
- "src/application/signals/**"
- "src/contracts/signals/**"
- "src/composition/signals.ts"
- "src/cli/signalCommands.ts"
- "src/server/registerSignalTools.ts"
- "src/server/createServer.ts"
- "src/server/sessionAvailabilityPolicy.ts"
- "src/application/CapabilityInventory.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/process/**"
- "src/artifacts/readStableArtifact.ts"
- "scripts/verify-signal-recording.mjs"
- ".github/workflows/real-signal-recording.yml"
- "package*.json"
- ".nvmrc"
permissions:
contents: read
concurrency:
group: real-signal-recording-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
sigrok:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- run: sudo apt-get update && sudo apt-get install -y sigrok-cli util-linux python3
- run: npm ci
- run: npm run build:cached
- run: npm run test:focused -- src/process/LinuxResourceLimits.test.ts src/domain/signals/annotationTextWindow.test.ts tests/boundary/signals/recordingProvider.test.ts tests/boundary/signals/recordingDescriptorCleanup.test.ts tests/boundary/signals/resourceLimits.test.ts tests/boundary/mcp/signalRecordingMcp.test.ts tests/boundary/cli/signalCleanup.test.ts
- run: node scripts/verify-signal-recording.mjs
env:
REA_SIGROK_COMMAND: /usr/bin/sigrok-cli
-37
View File
@@ -1,37 +0,0 @@
name: SQLite runtime compatibility
on:
workflow_call:
permissions:
contents: read
env:
HUSKY: "0"
jobs:
sqlite:
name: SQLite runtime compatibility (Node ${{ matrix.node }})
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
# Exercise unavailable-runtime diagnostics, the first supported release,
# and new patches on both supported lines without hand-editing versions.
# The repository-pinned Node 24 version also runs the complete test suite.
node: ["22.x", "24.15.0", "24.x", "26.x"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
check-latest: true
cache: npm
- run: npm ci
- uses: actions/download-artifact@v4
with:
name: rea-test-runtime
path: .
- name: Verify SQLite discovery, inspection and cleanup
run: npm run test:sqlite:run
-1
View File
@@ -47,7 +47,6 @@ Thumbs.db
# Local reference sources and analysis artifacts
/_reference/
/experiments/analysis-efficiency/results/
# Generated website download
/website/public/examples/notes-example.zip
+1
View File
@@ -1,4 +1,5 @@
{
"_comment": "Test files remain included so the gate measures duplication across both src/ and tests/. The 3.0% limit leaves headroom for ordinary changes while keeping duplication visible.",
"threshold": 3.0,
"reporters": ["consoleFull"],
"ignore": [
-29
View File
@@ -4,8 +4,6 @@
REA is a local-only reverse-engineering tool with shared CLI/MCP workflows. Distinguish observations, derivations, inferences, and unknowns; preserve Evidence provenance and session semantics through both adapters. Provider support and setup live in [README.md](README.md#choosing-a-deep-analysis-provider) and its linked guides.
Follow the [contribution scope and fail-closed integration rule](CONTRIBUTING.md#contribution-scope). Do not integrate capabilities while material scope, authority, side-effect, or required verification questions remain unresolved. For new providers or capabilities involving target execution, injection, mutation, or protection recovery, seek the required maintainer scope decision before substantial implementation for integration. Welcome early proposals, small exploratory prototypes, and draft PRs that help resolve questions; they do not authorize integration.
Ghidra uses ephemeral databases without modifying executable bytes or controlling a GUI; Windows Ghidra P0 has no mutation authority. IDA analysis is read-only; never save or close an attached GUI database.
Configuration changes must be additive and idempotent, with backups. Installers must not install or upgrade unrelated software, including Homebrew, Node.js, npm, Java, or Ghidra. Ghidra and IDA are bring-your-own. `rea setup` must show its planned changes and require approval before writing files or installing Hopper.
@@ -24,37 +22,10 @@ Assess brittleness in touched code during implementation, debugging, review, and
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.
When addressing a review thread, inspect the producing boundary and affected consumers for brittleness. Complete directly related refactoring in the same change. Before resolving the thread, explain the root cause, structural fix, validation, and any remaining cleanup.
Parse unknown boundary values and model expected failures with the tagged error algebra and `Result`. Preserve partial facts and meaningful failure reasons. Keep identity and lookup values separate from display formatting; preserve source values and explicit unknowns when normalization loses information. Absolute paths, file URLs, and HTTP paths have different semantics.
Validate advertised JSON Schemas after SDK conversion against their declared dialect and actual clients. Bind handlers to named contracts with exact types; catalog ordering must never select an operation or schema.
## Performance
Design analysis workflows and agent interfaces for efficiency from the first
implementation. Correctness, useful answers, Evidence provenance, caller choices,
compatibility and safe resource bounds remain required.
Optimize in this order:
1. Agent tokens and context. Return the smallest sufficient answer with
necessary provenance, coverage and limitations. Use task selection,
summaries, paging and retained Evidence where supported; honor requested
detail and keep complete Evidence accessible. Count the whole task,
including schemas, extra calls and retries.
2. Analysis time. Reuse validated results and shared work. Cache keys must
cover result-affecting inputs; define invalidation and lifetime. Validate
freshness before reporting cached live state as current.
3. CPU and memory. Avoid unnecessary work and copies; bound concurrency,
retained state and serialization growth.
For changes affecting these costs, measure representative completed tasks and
compare equivalent workflows before and after where available. Report token
usage, elapsed time, CPU time and peak process-family memory. Separate cold
and warm runs, label estimates, and state unmeasured costs. Fewer bytes alone
do not establish fewer tokens or faster analysis.
## Development
Use [.nvmrc](.nvmrc) and `package.json#packageManager` for the pinned toolchain. Cursor Cloud may place older Node.js first on `PATH`; environment setup installs the pinned toolchain under `/usr/local/bin`.
-104
View File
@@ -17,108 +17,8 @@ targets; optional adapter failures must preserve successful peers. Run
`npm run verify:test-discovery` after adding or moving tests. Resolved import
boundaries are checked by `npm run verify:module-boundaries`, included in lint.
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.
When adding or changing an MCP tool, follow the [tool design guide](docs/tool-design.md) and preserve the canonical contracts and generated catalog.
## Contribution scope
REA focuses on software structure, runtime behavior, and evidence through
general-purpose reverse-engineering workflows. Evaluate a proposal by its actual
capabilities, side effects, defaults, and complete workflow. A tool name or a
reference to vulnerability research, malware analysis, or CTFs does not determine
whether it belongs in REA.
Supported contributions include format inspection, ordinary archive and standard
compression extraction, disassembly, decompilation, cross-references, general
static deobfuscation, vulnerability analysis, and evidence reporting. Static
protection detection is distinct from defeating that protection. Security fixes
and isolated regression tests remain in scope.
Runtime investigation needs explicit boundaries. Launching or attaching to a
process, injecting instrumentation, running scripts, and changing memory or
registers require review of target selection, execution and mutation authority,
provenance, resource limits, cancellation, and cleanup. General Frida or debugger
support is not inherently read-only, and existing support does not authorize
every workflow built on it. General-purpose interfaces are not classified as
dedicated bypass workflows solely because caller-provided code could be misused;
their execution and mutation authority must still be reviewed.
REA does not integrate or officially distribute:
- Purpose-built workflows to defeat commercial packing or code-virtualization
protections and automatically recover protected code.
- Anti-debugging or anti-instrumentation evasion, or DRM, license, anti-cheat, or
access-control bypass workflows.
- Exploit or attack-payload automation, credential theft, covert persistence,
unauthorized access, or bulk attack workflows.
These boundaries apply to first-party providers, adapters, plugins, bundled
scripts, defaults, examples, and documentation. Moving a capability into an
optional dependency or plugin does not exempt it. Review what the integration
exposes, including upstream defaults and raw-command or script execution paths.
Ordinary extraction and general static deobfuscation are not excluded merely
because the input is packed or obfuscated; assess added bypass or execution
behavior separately.
This is a product and maintenance boundary, not a judgment about a contributor's
intentions or a declaration that all excluded research is unlawful. Contributors
must have the rights and authorization needed for their work. A local-only design
or an "authorized use only" disclaimer does not establish containment or settle
legal and scope questions.
### Fail-closed integration
If scope fit, target or authorization boundaries, side effects, or the verification
needed to establish those boundaries remain materially unresolved, **do not merge,
enable, or include the capability in official packages or distributions**. Keep
the proposal pending, narrow it, or decline it. Record unknowns explicitly; do not
turn them into "none" or assumed safety. Passing CI, completed implementation,
upstream popularity, or silence from maintainers is not scope approval.
For a new provider or a capability involving target execution, injection,
mutation, or protection recovery, seek an explicit maintainer scope decision in
the linked issue or design discussion before substantial implementation intended
for integration. Small exploratory prototypes and draft PRs may help inform that
decision; they do not authorize integration. The decision must cover the final
proposed behavior; a scope expansion needs a new decision. Routine fixes and
documentation changes within existing boundaries do not need a separate advance
decision, but must not silently expand those boundaries.
### Starting a proposal
To open a feature request or design discussion, describe the problem and desired
outcome or decision. Short answers and the forms' "Not sure yet" options are
welcome. You do not need code, a complete design or test plan, legal analysis, or
private proof-of-authorization documents to start a discussion. Share what you
know and leave optional details blank when you need help.
Form selections guide triage; they are not proof of authorization or scope
approval. Unselected effects must not be treated as established absence.
Maintainers and implementers work together to resolve the following before
integration:
- The concrete analyst question, requested inputs and outputs, and why existing
REA operations are insufficient.
- Why the workflow fits this scope, its non-goals, and any protection recovery,
bypass, or attack automation it would expose.
- The selected targets and every execution, injection, mutation, network, or
persistence effect, including behavior inherited from upstream tools.
- How the boundaries and outcome will be verified with self-owned or appropriately
licensed samples; identify real CLI/MCP and provider coverage, cleanup and
resource checks, and remaining unknowns. Do not publish private binaries,
credentials, or sensitive target data; follow [SECURITY.md](SECURITY.md) for
private vulnerability reports.
Mixed proposals should separate acceptable analysis capabilities from excluded
workflows so each can be decided independently. An issue may discuss unresolved
questions; opening an issue or PR does not authorize integration. This is a
maintainer integration gate, not a per-call confirmation requirement or a sandbox
guarantee.
## Development setup
Use the development toolchain pinned in `.nvmrc` and
@@ -187,10 +87,6 @@ CI diagnosis. Packaging/setup/distribution changes additionally require
`npm run verify:package` and `npm pack --dry-run`; provider changes require the
matching real-provider lane. State which host/provider workflows ran.
`check:pr` reuses build and static-check outputs while executing the test suite
fresh, including the fast Python producer checks. `docs:check` also runs the
onboarding example consistency suite for README-only changes.
Pre-commit formats and lints staged files; pre-push runs `check:fast`.
### Generated files and command ownership
-136
View File
@@ -1,136 +0,0 @@
# Disclaimer
## Responsible use
REA is built for lawful analysis: security research, malware and incident
analysis, vulnerability research and coordinated disclosure, CTFs and education,
interoperability, software preservation, and debugging or auditing software you
own or are authorized to examine.
The REA project does not support, and will not help with:
- circumventing DRM, license checks, anti-cheat systems or other technical
protection measures;
- developing game cheats or tampering with online services;
- bypassing authentication, bot protection or access controls on systems you are
not authorized to test;
- copying proprietary software or reproducing its protected code and assets;
- evading the usage policies or safety measures of AI model providers;
- reselling or sharing AI accounts or API access.
You are responsible for obtaining any required authorization and for complying
with applicable laws, license agreements and terms of service. Reverse
engineering may be restricted in your jurisdiction or by the license of the
software you analyze.
Requests for help with the uses above will be closed without response in issues
and discussions, and may result in removal from the REA community.
## User responsibility
Do not use REA for unauthorized access or exploitation, credential theft,
malicious deployment of malware, unlawful collection or disclosure of data,
unauthorized service disruption, or unlawful circumvention of access controls or
licensing restrictions. Legitimate security research and malware analysis must
remain within the rights and permissions applicable to the work.
You are responsible for your use of REA, including commands, configurations,
scripts, and actions you direct an AI agent to perform. Establish the legal
authority and scope required for the targets, accounts, devices, software, data,
and operations involved. Comply with applicable laws, contracts,
intellectual-property rights, privacy obligations, and tool licenses. Public
availability of software, possession of a file, or access to a debugging
endpoint does not by itself establish permission for every operation.
## Runtime, network, and device operations
Some REA workflows execute or observe programs, attach to runtime or browser
endpoints, capture network traffic, interact with applications, or operate on
connected devices. These actions can affect application state, files, accounts,
devices, and services. Authorization to inspect an artifact does not necessarily
authorize execution, interception, device changes, or interaction with another
party's system.
Review the operations you request, including agent-generated plans and scripts,
and use an appropriate environment for untrusted targets. You are responsible
for protecting credentials, personal data, captured traffic, and investigation
artifacts, and for obtaining any permission required to collect, retain,
process, or share them. Local operation does not establish authorization or
guarantee that executed targets and third-party tools have no external effects.
## Analysis results and generated output
Decompilation, reconstruction, heuristics, and AI-assisted analysis may be
incomplete or incorrect. Results do not guarantee accuracy, completeness,
security, compatibility, or legal compliance. Review the underlying evidence and
verify consequential conclusions before relying on them.
Obtaining source-like output or an analysis report does not grant rights to the
original program, its data, or the generated output. Check the target's rights
and the producing tool's applicable terms before publishing, sharing, or using
results in another product or service.
## Third-party tools and licenses
Third-party components and analysis tools retain their own licenses, copyright
notices, and usage conditions. Consult
[Third-party notices](THIRD_PARTY_NOTICES.md) for their roles, licensing
records, and preserved upstream texts.
You must legally obtain IDA Pro and Hex-Rays decompilers, Hopper, JEB, and any
other proprietary tools, together with the rights required for your use. REA
provides no commercial-tool license, key, or activation entitlement. Permitted
trials and demos remain subject to vendor terms. An open-source bridge or
accessible API does not grant additional user, machine, feature, automation,
hosting, or output-sharing rights. Cracked copies, stolen keys, unauthorized key
sharing, and bypassing license restrictions are not authorized by REA.
## Disclaimer of warranty
REA is provided **AS IS**, without express or implied warranties, including
merchantability, fitness for a particular purpose, and noninfringement, as set
out in the [MIT License](LICENSE). You assume the risks of using the software
and deciding whether it is suitable for your task. No project description,
example, analysis result, or third-party integration guarantees a particular
outcome or establishes that your intended use is lawful or safe.
## Limitation of liability
The warranty and liability provisions of the [MIT License](LICENSE) govern REA's
authors and copyright holders, subject to applicable law. That license disclaims
liability for claims, damages, and other liability arising from or in connection
with the software or its use, whether in contract, tort, or otherwise. This
document does not expand those provisions or override rights and obligations
that cannot be excluded under applicable law.
## Disclaimer of endorsement
References to third-party projects, contributors, products, services, and
trademarks identify their work and REA's integrations. Credits and thanks do not
imply affiliation, sponsorship, approval, or endorsement by the named parties,
including the National Security Agency and commercial tool vendors.
Redistribution, bundling, or hosting by a third party does not by itself imply
affiliation with or endorsement by the REA project.
## Relationship to software licenses
This document explains REA's intended use, user responsibilities, and community
support boundaries. It does not amend the MIT license, impose additional
copyright-license conditions, replace upstream licenses, or grant rights to
third-party software or targets. The applicable software licenses and agreements
retain their own terms.
## Versions, distribution channels, and platforms
The project's position on lawful use and non-endorsement of illegal or
unauthorized activity covers all REA versions, distribution forms, and
platforms. This includes historical releases and Git commits, npm packages,
bundled or separately distributed REA skills, source checkouts, release
archives, and redistributed copies, regardless of installation method, agent
client, operating system, or platform. Using an older version or another
distribution channel does not imply project endorsement or remove obligations
under applicable law or to respect third-party rights.
Each copy remains subject to the licenses accompanying that copy. This statement
does not retroactively amend existing license grants, add license conditions, or
expand historical warranty or liability exclusions.
+27 -32
View File
@@ -6,7 +6,7 @@
### One MCP for reverse engineering across binaries, applications, and runtime behavior.
**See a feature you like. Understand how it works, down to the binary level.**
**Understand how software works, down to the binary level — for security research, interoperability, and software you're authorized to analyze.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
See a feature in an app that you want in your own product? Ask your agent to investigate it with REA. It can inspect the app without its source code, explain how the feature works, show the evidence, and build a version for your project.
REA helps security researchers, malware analysts, CTF players and developers understand compiled software through their agents. Point your agent at a binary, application or capture you're authorized to analyze; REA inspects it without source code, explains its behavior, and shows the evidence behind each conclusion.
REA connects your agent to tools for inspecting native binaries, JavaScript and Electron apps, .NET assemblies, and websites. You can also use the same tools from your terminal. Analysis runs locally, and results include the evidence and limitations behind each conclusion.
@@ -55,6 +55,23 @@ Setup registers REA with your agent and installs matching workflow instructions.
> **[Visit the REA website](https://rea.tools/)** for setup instructions, illustrated guides, and real case studies.
## Responsible use
REA is built for lawful analysis: security research, malware and incident analysis, vulnerability research and coordinated disclosure, CTFs and education, interoperability, software preservation, and debugging or auditing software you own or are authorized to examine.
The REA project does not support, and will not help with:
- circumventing DRM, license checks, anti-cheat systems or other technical protection measures;
- developing game cheats or tampering with online services;
- bypassing authentication, bot protection or access controls on systems you are not authorized to test;
- copying proprietary software or reproducing its protected code and assets;
- evading the usage policies or safety measures of AI model providers;
- reselling or sharing AI accounts or API access.
You are responsible for obtaining any required authorization and for complying with applicable laws, license agreements and terms of service. Reverse engineering may be restricted in your jurisdiction or by the license of the software you analyze.
Requests for help with the uses above will be closed without response in issues and discussions, and may result in removal from the REA community.
## Quick start
### Set up your agent
@@ -77,11 +94,11 @@ manual MCP registration.
### Ask your agent
```text
Understand how search works in the Notes app, show me the evidence, and build a
similar feature for my project.
My app's release build crashes on startup but the debug build doesn't.
Inspect ./build/MyApp, find where the two builds diverge, and show me the evidence.
```
Replace Notes with your target app and the feature you want to understand.
Point your agent at a target you're authorized to analyze and describe what you want to understand.
### Use the terminal
@@ -157,21 +174,16 @@ Additional tools and host support depend on the target:
| Go binaries | Embedded compiler version, modules, replacements and build settings | Built-in static ELF/PE/thin Mach-O inspection; no Go installation required |
| WASM artifact | Validation, sections, exact import/export WAT forms and decoded WAT | Caller-supplied WABT 1.0.42; `inspect_wasm_artifact` |
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
| SQLite databases | Tables, columns, indexes, views, triggers and selected ordinary-table rows | Local database/WAL snapshot; Node.js 24.x >=24.15 or 26+ with native SQLite limits |
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; [application analysis](https://rea.tools/guides/javascript/) |
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](https://rea.tools/guides/browser/) |
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR or Fiddler Everywhere SAZ; mitmdump on Linux for native mitmproxy; [capture guide](docs/web-network-captures.md) |
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR; mitmdump on Linux for native mitmproxy captures; [capture guide](docs/web-network-captures.md) |
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | None (static only); [managed-code guide](docs/managed-code-analysis.md) |
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
| Android devices | Devices, packages, processes, logs, dumps, screen captures, and APK/file transfers | Caller-supplied adb (emulator or hardware); [ADB guide](docs/adb-device-analysis.md) |
| JEB projects | Engine-backed project units, artifact digests and type/method pseudo-code | A caller-started JEB client serving MCP, selected with REA_JEB_MCP_URL; [JEB guide](docs/jeb-analysis.md) |
| Android resources | Decoded manifest, string tables, locales and version facts | Caller-supplied Apktool launcher; [resource guide](docs/apktool-resource-analysis.md) |
| Flutter apps | Dart snapshot hash, per-ABI library digests and engine build provenance | None (static APK parsing); [Flutter guide](docs/flutter-analysis.md) |
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
| Recorded packets | Selected fields, repeated values, filters and decode-as rules | Linux: TShark 4.x + prlimit; [capture guide](docs/packet-captures.md) |
| Packet summaries | Endpoints, DNS, TLS SNI, protocol distribution and HTTP requests | Caller-supplied tshark and capinfos (Linux-verified); [pcap guide](docs/pcap-analysis.md) |
| Recorded logic signals | Decoder annotations, sample ranges and diagnostics | Linux: sigrok-cli 0.7.2 + prlimit; [signal recordings](docs/signal-recordings.md) |
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
| Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
@@ -183,7 +195,7 @@ using your user permissions; each runtime guide describes its effects.
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), and
[IDA guide](docs/ida-provider.md), 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
@@ -322,7 +334,7 @@ Report vulnerabilities through [SECURITY.md](SECURITY.md).
## Star history
🎉 **170,000 GitHub stars — thank you!**
🎉 **110,000 GitHub stars — thank you!**
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
@@ -336,13 +348,9 @@ Thanks to everyone using REA, reporting bugs, requesting features, testing build
## Disclaimer
See [DISCLAIMER.md](DISCLAIMER.md) for responsible-use guidance.
See [Responsible use](#responsible-use).
The project's position on illegal or unauthorized use covers all REA versions,
distribution channels, and platforms; each copy retains its applicable licenses.
REA is for lawful research, education, interoperability, software preservation,
and analysis of software you own or are authorized to examine.
REA is an open-source software project. We have not issued or endorsed any cryptocurrency or token. Tokens using the REA name are not affiliated with the project.
## Contributing
@@ -357,16 +365,3 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
## License
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see
[Third-party notices](THIRD_PARTY_NOTICES.md) for the dependency inventory,
preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable
licenses. REA grants no tool license, key, or activation entitlement. Trials and
demos remain subject to vendor terms, including user, feature, automation, and
output sharing restrictions. Cracked copies, stolen keys, unauthorized key
sharing, and bypassing license restrictions are not authorized. This guidance
does not amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### خادم MCP واحد للهندسة العكسية للملفات الثنائية والتطبيقات والسلوك أثناء التشغيل.
**وجدت ميزة تعجبك؟ افهم طريقة عملها حتى مستوى الشيفرة الثنائية.**
**افهم طريقة عمل البرمجيات حتى مستوى الشيفرة الثنائية — لأبحاث الأمن، وقابلية التشغيل البيني، والبرمجيات المصرّح لك بتحليلها.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
هل وجدت في تطبيق ميزة تريد إضافتها إلى منتجك؟ اطلب من وكيلك استقصاءها باستخدام REA. يستطيع فحص التطبيق من دون شيفرته المصدرية، وشرح طريقة عمل الميزة وعرض الأدلة، ثم بناء نسخة تناسب مشروعك.
يساعد REA الباحثين الأمنيين ومحللي البرمجيات الخبيثة ولاعبي مسابقات CTF والمطورين على فهم البرمجيات المُصرَّفة عبر وكلائهم. وجّه وكيلك إلى ملف ثنائي أو تطبيق أو تسجيل مصرّح لك بتحليله؛ فيفحصه REA من دون الشيفرة المصدرية، ويشرح سلوكه، ويعرض الأدلة التي يستند إليها كل استنتاج.
يربط REA وكيلك بأدوات لفحص الملفات الثنائية للشيفرة الأصلية، وتطبيقات JavaScript وElectron، وتجميعات .NET، والمواقع. يمكنك أيضًا استخدام الأدوات نفسها من الطرفية. يجري التحليل محليًا، وتتضمن النتائج الأدلة والقيود التي تستند إليها كل خلاصة.
@@ -55,6 +55,23 @@
> **[زر موقع REA](https://rea.tools/ar/)** للاطلاع على تعليمات الإعداد والأدلة المصوّرة ودراسات الحالة الفعلية.
## الاستخدام المسؤول
صُمّم REA للتحليل المشروع: أبحاث الأمن، وتحليل البرمجيات الخبيثة والحوادث، وأبحاث الثغرات والإفصاح المنسّق، ومسابقات CTF والتعليم، وقابلية التشغيل البيني، وحفظ البرمجيات، وتصحيح أخطاء البرمجيات أو تدقيقها إذا كنت تملكها أو كان مصرّحًا لك بفحصها.
لا يدعم مشروع REA ما يلي، ولن يساعد فيه:
- التحايل على إدارة الحقوق الرقمية (DRM) أو فحوص التراخيص أو أنظمة مكافحة الغش أو غيرها من تدابير الحماية التقنية؛
- تطوير أدوات الغش في الألعاب أو العبث بالخدمات عبر الإنترنت؛
- تجاوز المصادقة أو الحماية من الروبوتات أو ضوابط الوصول في أنظمة غير مصرّح لك باختبارها؛
- نسخ البرمجيات المملوكة أو إعادة إنتاج شيفرتها وأصولها المحمية؛
- التهرّب من سياسات الاستخدام أو تدابير السلامة لدى مزوّدي نماذج الذكاء الاصطناعي؛
- إعادة بيع حسابات الذكاء الاصطناعي أو الوصول إلى واجهات API أو مشاركتها.
أنت مسؤول عن الحصول على أي تفويض مطلوب والالتزام بالقوانين واتفاقيات الترخيص وشروط الخدمة المعمول بها. وقد تكون الهندسة العكسية مقيّدة في نطاق ولايتك القضائية أو بموجب ترخيص البرنامج الذي تحلّله.
ستُغلق طلبات المساعدة في الاستخدامات المذكورة أعلاه في issues والنقاشات من دون رد، وقد تؤدي إلى الإزالة من مجتمع REA.
## البدء السريع
### إعداد وكيلك
@@ -72,10 +89,11 @@ npx rea-agents setup
### اطلب من وكيلك
```text
استقصِ طريقة عمل البحث في تطبيق Notes، واعرض الأدلة، ثم ابنِ ميزة مشابهة لمشروعي.
تتعطّل نسخة الإصدار (release) من تطبيقي عند بدء التشغيل، لكن نسخة التصحيح (debug) لا تتعطّل.
افحص ./build/MyApp، وحدّد موضع اختلاف النسختين، واعرض لي الأدلة.
```
استبدل Notes بالتطبيق المستهدف وحدّد الميزة التي تريد فهمها.
وجّه وكيلك إلى هدف مصرّح لك بتحليله، وصِف ما تريد فهمه.
### استخدام الطرفية
@@ -139,16 +157,12 @@ npx rea-agents@latest setup
| JavaScript / Electron | الوحدات، وعمليات الاستيراد، وخرائط المصدر، والمسارات، وIPC، وعلاقات إضافات الشيفرة الأصلية | Node.js وnpm؛ [تحليل التطبيقات](https://rea.tools/ar/guides/javascript/) |
| المواقع | بنية الصفحة، والسكربتات، وملاحظات الشبكة، ولقطات الشاشة المطلوبة | متصفح من عائلة Chrome؛ [تحليل المتصفح](https://rea.tools/ar/guides/browser/) |
| تسجيلات الشبكة المحفوظة | الطلبات، والاستجابات، ومحتويات الحمولة المتاحة، ومواضعها في المصدر | HAR؛ وmitmdump على Linux لتسجيلات mitmproxy بصيغتها الأصلية؛ [دليل تسجيلات الشبكة](docs/web-network-captures.md) |
| التقاط الحزم | نقاط النهاية وDNS وTLS SNI وتوزيع البروتوكولات وطلبات HTTP | tshark وcapinfos يوفّرهما المُستدعي؛ [دليل pcap](docs/pcap-analysis.md) |
| تجميعات .NET | البيانات الوصفية، وتعليمات CIL، واعتماديات الشيفرة الأصلية المعلنة، ومقارنات البناء | فحص ثابت؛ [دليل الشيفرة المُدارة](docs/managed-code-analysis.md) |
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS/Windows x64؛ [دليل Android](docs/android-analysis.md) |
| أجهزة Android | الأجهزة والحزم والعمليات والسجلات والدامبات ولقطات الشاشة ونقل APK/الملفات | adb يوفّره المُستدعي (محاكي أو جهاز)؛ [دليل ADB](docs/adb-device-analysis.md) |
| مشاريع JEB | وحدات المشروع من المحرك وبصمات المصنّفات والكود الزائف للأنواع/الدوال | عميل JEB يبدأه المُستدعي ويقدّم MCP، ويُختار عبر REA_JEB_MCP_URL؛ [دليل JEB](docs/jeb-analysis.md) |
| موارد Android | البيان المفكوك الترميز وجداول السلاسل واللغات وحقائق الإصدار | مُشغّل Apktool يوفّره المُستدعي؛ [دليل الموارد](docs/apktool-resource-analysis.md) |
| تطبيقات Flutter | بصمة لقطة Dart وهشوش المكتبات لكل ABI وأصل بناء المحرك | لا شيء (تحليل APK ساكن)؛ [دليل Flutter](docs/flutter-analysis.md) |
| البرامج الثابتة | المناطق، ونتائج الاستخراج، وما يُمرّر إلى تحليل الشيفرة الأصلية | Binwalk / Unblob على Linux؛ [دليل البرامج الثابتة](docs/firmware-analysis.md) |
| الحزم المسجلة | حقول مختارة وقيم متكررة ومرشحات وقواعد فك الترميز | Linux: TShark 4.x + prlimit; [دليل التقاط الحزم](docs/packet-captures.md) |
| الإشارات المنطقية المسجلة | تعليقات مفكك الترميز ونطاقات العينات ومعلومات التشخيص | Linux: sigrok-cli 0.7.2 + prlimit; [دليل الإشارات](docs/signal-recordings.md) |
| الحزم والموارد | قوائم الملفات، والبصمات، وملفات plist، وبنية حزم Apple، والموارد المستخرجة | [دليل تحليل الملفات وJavaScript](docs/javascript-artifact-reconstruction.md)، [تطبيقات Apple](docs/apple-application-analysis.md) |
| سلوك العمليات | مخرجات الطرفية، والتفاعلات، وملاحظات الخروج ونظام الملفات، ومقارنات التشغيل | Linux/macOS مع PTY أصلي؛ [تسجيل سلوك العمليات](docs/process-capture.md) |
@@ -264,7 +278,7 @@ npx rea-agents@latest setup
## سجل النجوم
🎉 **170,000 نجمة على GitHub — شكرًا لكم!**
🎉 **110,000 نجمة على GitHub — شكرًا لكم!**
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
@@ -278,13 +292,7 @@ npx rea-agents@latest setup
## إخلاء المسؤولية
راجع [DISCLAIMER.md](DISCLAIMER.md) للحصول على إرشادات الاستخدام المسؤول.
REA مخصص للبحث والتعليم والتشغيل البيني وحفظ البرمجيات بشكل قانوني، ولتحليل البرمجيات التي تملكها أو لديك تفويض لفحصها.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
راجع [الاستخدام المسؤول](#الاستخدام-المسؤول).
## المساهمة
@@ -295,15 +303,3 @@ applicable licenses.
## الترخيص
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### Ein MCP für das Reverse Engineering von Binärdateien, Anwendungen und Laufzeitverhalten.
**Eine Funktion gefällt dir? Verstehe, wie sie funktioniert – bis hinunter auf die Binärebene.**
**Verstehe, wie Software funktioniert, bis hinunter auf die Binärebene – für Sicherheitsforschung, Interoperabilität und Software, die du analysieren darfst.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Du hast in einer App eine Funktion entdeckt, die du in dein eigenes Produkt übernehmen möchtest? Lass deinen Agenten sie mit REA untersuchen. Er kann die App ohne ihren Quellcode analysieren, die Funktionsweise erklären, Belege zeigen und eine passende Umsetzung für dein Projekt entwickeln.
REA hilft Sicherheitsforschern, Malware-Analysten, CTF-Spielern und Entwicklern, kompilierte Software mithilfe ihrer Agenten zu verstehen. Richte deinen Agenten auf eine Binärdatei, eine Anwendung oder eine Aufzeichnung, die du analysieren darfst; REA untersucht sie ohne Quellcode, erklärt ihr Verhalten und zeigt die Belege hinter jeder Schlussfolgerung.
REA verbindet deinen Agenten mit Werkzeugen zum Untersuchen nativer Binärdateien, von JavaScript- und Electron-Apps, .NET-Assemblies und Websites. Dieselben Werkzeuge kannst du auch im Terminal nutzen. Die Analyse läuft lokal; die Ergebnisse enthalten die Belege und Einschränkungen hinter jeder Schlussfolgerung.
@@ -55,6 +55,23 @@ Die Einrichtung registriert REA bei deinem Agenten und installiert passende Work
> **[Besuche die REA-Website](https://rea.tools/de/)** für Einrichtungshinweise, bebilderte Anleitungen und echte Fallstudien.
## Verantwortungsvolle Nutzung
REA ist für rechtmäßige Analysen gedacht: Sicherheitsforschung, Malware- und Vorfallsanalyse, Schwachstellenforschung und koordinierte Offenlegung, CTFs und Lehre, Interoperabilität, Softwarebewahrung sowie das Debuggen oder Prüfen von Software, die dir gehört oder die du untersuchen darfst.
Das REA-Projekt unterstützt Folgendes nicht und hilft auch nicht dabei:
- DRM, Lizenzprüfungen, Anti-Cheat-Systeme oder andere technische Schutzmaßnahmen zu umgehen;
- Cheats für Spiele zu entwickeln oder Onlinedienste zu manipulieren;
- Authentifizierung, Bot-Schutz oder Zugriffskontrollen auf Systemen zu umgehen, die du nicht testen darfst;
- proprietäre Software zu kopieren oder ihren geschützten Code und ihre geschützten Assets zu reproduzieren;
- die Nutzungsrichtlinien oder Sicherheitsmaßnahmen von KI-Modellanbietern zu unterlaufen;
- KI-Konten oder API-Zugänge weiterzuverkaufen oder zu teilen.
Du bist dafür verantwortlich, erforderliche Genehmigungen einzuholen und geltendes Recht, Lizenzvereinbarungen und Nutzungsbedingungen einzuhalten. Reverse Engineering kann in deiner Rechtsordnung oder durch die Lizenz der analysierten Software eingeschränkt sein.
Anfragen nach Hilfe bei den oben genannten Zwecken werden in Issues und Diskussionen ohne Antwort geschlossen und können zum Ausschluss aus der REA-Community führen.
## Schnellstart
### Deinen Agenten einrichten
@@ -72,10 +89,11 @@ Die Einrichtung unterstützt Claude Code, Codex, Cursor, Gemini CLI, Grok Build
### Deinen Agenten fragen
```text
Untersuche, wie die Suche in der Notes-App funktioniert, zeige mir die Belege und entwickle eine ähnliche Funktion für mein Projekt.
Der Release-Build meiner App stürzt beim Start ab, der Debug-Build aber nicht.
Untersuche ./build/MyApp, finde heraus, wo die beiden Builds voneinander abweichen, und zeige mir die Belege.
```
Ersetze Notes durch deine Ziel-App und benenne die Funktion, die du verstehen möchtest.
Richte deinen Agenten auf ein Ziel, das du analysieren darfst, und beschreibe, was du verstehen möchtest.
### Das Terminal verwenden
@@ -139,16 +157,12 @@ REA benötigt Node.js 22.x (>=22.19), 24.x (>=24.11) oder 26+ sowie npm. Zusätz
| JavaScript / Electron | Module, Imports, Source Maps, Routen, IPC und Beziehungen zu nativen Add-ons | Node.js und npm; [Anwendungsanalyse](https://rea.tools/de/guides/javascript/) |
| Websites | Seitenstruktur, Skripte, Netzwerkbeobachtungen und angeforderte Screenshots | Ein Browser aus der Chrome-Familie; [Browseranalyse](https://rea.tools/de/guides/browser/) |
| Gespeicherte Netzwerkaufzeichnungen | Anfragen, Antworten, zugängliche Nutzdaten und Quellpositionen | HAR; mitmdump unter Linux für Aufzeichnungen im nativen mitmproxy-Format; [Leitfaden zu Netzwerkaufzeichnungen](docs/web-network-captures.md) |
| Paketerfassungen | Endpunkte, DNS, TLS SNI, Protokollverteilung und HTTP-Anfragen | Vom Aufrufer bereitgestellte tshark- und capinfos-Binaries; [pcap-Leitfaden](docs/pcap-analysis.md) |
| .NET-Assemblies | Metadaten, CIL-Anweisungen, deklarierte native Abhängigkeiten und Build-Vergleiche | Statische Untersuchung; [Leitfaden für verwalteten Code](docs/managed-code-analysis.md) |
| Android-APKs | Manifest-Deklarationen, Klassen, dekompilierte Methoden und Verweise | JADX ohne grafische Oberfläche und ein vollständiges JDK unter Linux/macOS/Windows x64; [Android-Leitfaden](docs/android-analysis.md) |
| Android-Geräte | Geräte, Pakete, Prozesse, Logs, Dumps, Bildschirmaufnahmen sowie APK- und Dateiübertragungen | Vom Aufrufer bereitgestelltes adb (Emulator oder Gerät); [ADB-Leitfaden](docs/adb-device-analysis.md) |
| JEB-Projekte | Engine-gestützte Projekteinheiten, Artefakt-Prüfsummen und Pseudokode von Typen/Methoden | Ein vom Aufrufer gestarteter JEB-Client mit MCP, ausgewählt über REA_JEB_MCP_URL; [JEB-Leitfaden](docs/jeb-analysis.md) |
| Android-Ressourcen | Dekodiertes Manifest, String-Tabellen, Sprachen und Versionsfakten | Vom Aufrufer bereitgestellter Apktool-Starter; [Ressourcen-Leitfaden](docs/apktool-resource-analysis.md) |
| Flutter-Apps | Dart-Snapshot-Hash, Per-ABI-Bibliotheksprüfsummen und Engine-Build-Provenienz | Keine (statische APK-Analyse); [Flutter-Leitfaden](docs/flutter-analysis.md) |
| Firmware | Bereiche, Extraktionsergebnisse und Übergaben an die native Analyse | Binwalk / Unblob unter Linux; [Firmware-Leitfaden](docs/firmware-analysis.md) |
| Aufgezeichnete Pakete | Ausgewählte Felder, wiederholte Werte, Filter und Decode-as-Regeln | Linux: TShark 4.x + prlimit; [Mitschnitt-Anleitung](docs/packet-captures.md) |
| Aufgezeichnete Logiksignale | Decoder-Anmerkungen, Sample-Bereiche und Diagnosen | Linux: sigrok-cli 0.7.2 + prlimit; [Signalaufzeichnungen](docs/signal-recordings.md) |
| Pakete und Ressourcen | Dateiinventare, Hashwerte, plists, Aufbau von Apple-Bundles und extrahierte Ressourcen | [Artefakt- und JavaScript-Leitfaden](docs/javascript-artifact-reconstruction.md), [Apple-Anwendungen](docs/apple-application-analysis.md) |
| Prozessverhalten | Terminalausgabe, Interaktionen, Beobachtungen zu Prozessende und Dateisystem sowie Laufvergleiche | Linux/macOS mit nativer PTY; [Prozessaufzeichnung](docs/process-capture.md) |
@@ -262,7 +276,7 @@ Melde Sicherheitslücken gemäß [SECURITY.md](SECURITY.md).
## Sternverlauf
🎉 **170.000 GitHub-Sterne – vielen Dank!**
🎉 **110.000 GitHub-Sterne – vielen Dank!**
Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds testen und Fehlerbehebungen beitragen.
@@ -276,13 +290,7 @@ Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds
## Haftungsausschluss
Hinweise zur verantwortungsvollen Nutzung findest du in [DISCLAIMER.md](DISCLAIMER.md).
REA dient der rechtmäßigen Forschung, Bildung, Interoperabilität, Softwareerhaltung und Analyse von Software, die dir gehört oder die du mit entsprechender Genehmigung untersuchen darfst.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
Siehe [Verantwortungsvolle Nutzung](#verantwortungsvolle-nutzung).
## Mitwirken
@@ -293,15 +301,3 @@ Die Entwicklungsumgebung und Prüfungen beschreibt [CONTRIBUTING.md](CONTRIBUTIN
## Lizenz
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### Un solo MCP para la ingeniería inversa de binarios, aplicaciones y comportamiento en ejecución.
**¿Ves una función que te gusta? Entiende cómo funciona, hasta el nivel binario.**
**Entiende cómo funciona el software, hasta el nivel binario — para la investigación de seguridad, la interoperabilidad y el software que tienes autorización para analizar.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
¿Has visto una función en una aplicación que quieres incorporar a tu producto? Pide a tu agente que la investigue con REA. Puede inspeccionar la aplicación sin su código fuente, explicar cómo funciona la función, mostrar las pruebas y crear una versión para tu proyecto.
REA ayuda a investigadores de seguridad, analistas de malware, participantes en CTF y desarrolladores a entender software compilado a través de sus agentes. Dirige a tu agente a un binario, una aplicación o una captura que tengas autorización para analizar; REA lo inspecciona sin código fuente, explica su comportamiento y muestra las pruebas en las que se basa cada conclusión.
REA conecta tu agente con herramientas para inspeccionar binarios nativos, aplicaciones JavaScript y Electron, ensamblados .NET y sitios web. También puedes usar las mismas herramientas desde la terminal. El análisis se ejecuta localmente y los resultados incluyen las pruebas y limitaciones que sustentan cada conclusión.
@@ -55,6 +55,23 @@ La configuración registra REA en tu agente e instala las instrucciones de traba
> **[Visita el sitio web de REA](https://rea.tools/es/)** para encontrar instrucciones de configuración, guías ilustradas y casos reales.
## Uso responsable
REA está pensado para el análisis lícito: investigación de seguridad, análisis de malware e incidentes, investigación de vulnerabilidades y divulgación coordinada, CTF y educación, interoperabilidad, preservación de software, y depuración o auditoría de software que te pertenece o que tienes autorización para examinar.
El proyecto REA no respalda lo siguiente ni ayudará con ello:
- eludir DRM, comprobaciones de licencia, sistemas antitrampas u otras medidas técnicas de protección;
- desarrollar trampas para juegos o manipular servicios en línea;
- eludir la autenticación, la protección contra bots o los controles de acceso en sistemas que no tienes autorización para probar;
- copiar software propietario o reproducir su código y sus recursos protegidos;
- evadir las políticas de uso o las medidas de seguridad de los proveedores de modelos de IA;
- revender o compartir cuentas de IA o acceso a API.
Eres responsable de obtener las autorizaciones necesarias y de cumplir las leyes, los acuerdos de licencia y las condiciones de servicio aplicables. La ingeniería inversa puede estar restringida en tu jurisdicción o por la licencia del software que analizas.
Las solicitudes de ayuda para los usos anteriores se cerrarán sin respuesta en las issues y las discusiones, y pueden dar lugar a la expulsión de la comunidad de REA.
## Inicio rápido
### Configura tu agente
@@ -72,10 +89,11 @@ La configuración admite Claude Code, Codex, Cursor, Gemini CLI, Grok Build y [o
### Pregunta a tu agente
```text
Investiga cómo funciona la búsqueda en la aplicación Notes, muéstrame las pruebas y crea una función similar para mi proyecto.
La compilación de release de mi aplicación se bloquea al iniciarse, pero la de depuración no.
Inspecciona ./build/MyApp, encuentra dónde divergen las dos compilaciones y muéstrame las pruebas.
```
Sustituye Notes por la aplicación objetivo y especifica la función que quieres entender.
Dirige a tu agente a un objetivo que tengas autorización para analizar y describe lo que quieres entender.
### Usa la terminal
@@ -139,16 +157,12 @@ REA requiere Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, además de npm. Las h
| JavaScript / Electron | Módulos, importaciones, mapas de código fuente, rutas, IPC y relaciones con complementos nativos | Node.js y npm; [análisis de aplicaciones](https://rea.tools/es/guides/javascript/) |
| Sitios web | Estructura de la página, scripts, observaciones de red y capturas de pantalla solicitadas | Un navegador de la familia Chrome; [análisis del navegador](https://rea.tools/es/guides/browser/) |
| Capturas de red guardadas | Solicitudes, respuestas, contenido accesible de las cargas útiles y ubicaciones de origen | HAR; mitmdump en Linux para capturas en formato nativo de mitmproxy; [guía de capturas](docs/web-network-captures.md) |
| Capturas de paquetes | Endpoints, DNS, TLS SNI, distribución de protocolos y solicitudes HTTP | tshark y capinfos suministrados por el autor de la llamada; [guía pcap](docs/pcap-analysis.md) |
| Ensamblados .NET | Metadatos, instrucciones CIL, dependencias nativas declaradas y comparaciones de compilaciones | Inspección estática; [guía de código administrado](docs/managed-code-analysis.md) |
| APK de Android | Declaraciones del manifiesto, clases, métodos descompilados y referencias | JADX sin interfaz gráfica y un JDK completo en Linux/macOS/Windows x64; [guía de Android](docs/android-analysis.md) |
| Dispositivos Android | Dispositivos, paquetes, procesos, registros, volcados, capturas de pantalla y transferencias de APK/archivos | adb suministrado por el autor de la llamada (emulador o dispositivo); [guía de ADB](docs/adb-device-analysis.md) |
| Proyectos JEB | Unidades de proyecto del motor, resúmenes de artefactos y pseudocódigo de tipos/métodos | Un cliente JEB iniciado por el autor de la llamada que sirve MCP, seleccionado con REA_JEB_MCP_URL; [guía de JEB](docs/jeb-analysis.md) |
| Recursos de Android | Manifiesto decodificado, tablas de cadenas, idiomas y datos de versión | Lanzador de Apktool suministrado por el autor de la llamada; [guía de recursos](docs/apktool-resource-analysis.md) |
| Aplicaciones Flutter | Hash de snapshot de Dart, resúmenes de bibliotecas por ABI y procedencia de compilación del motor | Ninguna (análisis APK estático); [guía de Flutter](docs/flutter-analysis.md) |
| Firmware | Regiones, resultados de extracción y derivaciones al análisis nativo | Binwalk / Unblob en Linux; [guía de firmware](docs/firmware-analysis.md) |
| Paquetes grabados | Campos seleccionados, valores repetidos, filtros y reglas de decodificación | Linux: TShark 4.x + prlimit; [guía de capturas](docs/packet-captures.md) |
| Señales lógicas grabadas | Anotaciones del decodificador, rangos de muestras y diagnósticos | Linux: sigrok-cli 0.7.2 + prlimit; [guía de señales](docs/signal-recordings.md) |
| Paquetes y recursos | Inventarios de archivos, resúmenes criptográficos, plists, estructura de paquetes de Apple y recursos extraídos | [Guía de artefactos y JavaScript](docs/javascript-artifact-reconstruction.md), [aplicaciones de Apple](docs/apple-application-analysis.md) |
| Comportamiento de procesos | Salida de la terminal, interacciones, observaciones de salida y del sistema de archivos, y comparaciones entre ejecuciones | Linux/macOS con una PTY nativa; [captura de procesos](docs/process-capture.md) |
@@ -262,7 +276,7 @@ Informa de vulnerabilidades siguiendo [SECURITY.md](SECURITY.md).
## Historial de estrellas
🎉 **170.000 estrellas en GitHub: ¡gracias!**
🎉 **110.000 estrellas en GitHub: ¡gracias!**
Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban compilaciones y contribuyen con correcciones.
@@ -276,13 +290,7 @@ Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban co
## Aviso legal
Consulta [DISCLAIMER.md](DISCLAIMER.md) para obtener orientación sobre el uso responsable.
REA está destinado a la investigación, la educación, la interoperabilidad, la preservación de software y el análisis de software propio o autorizado, dentro de la ley.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
Consulta [Uso responsable](#uso-responsable).
## Contribuir
@@ -293,15 +301,3 @@ Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para preparar el entorno de desarrol
## Licencia
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+41 -45
View File
@@ -6,7 +6,7 @@
### یک MCP برای مهندسی معکوس فایل‌های باینری، برنامه‌ها و رفتار زمان اجرا.
**قابلیتی دیده‌اید که دوستش دارید؟ سازوکارش را تا سطح باینری درک کنید.**
**سازوکار نرم‌افزار را تا سطح باینری درک کنید — برای پژوهش امنیتی، تعامل‌پذیری و نرم‌افزارهایی که مجوز تحلیلشان را دارید.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -39,7 +39,7 @@
<div dir="rtl">
قابلیتی در یک برنامه دیده‌اید که می‌خواهید در محصول خودتان داشته باشید؟ از ایجنت خود بخواهید با REA آن را بررسی کند. ایجنت می‌تواند بدون دسترسی به کد منبع برنامه، نحوهٔ کار قابلیت را بررسی و توضیح دهد، شواهد را نشان دهد و نسخه‌ای مشابه برای پروژهٔ شما بسازد.
REA به پژوهشگران امنیتی، تحلیلگران بدافزار، شرکت‌کنندگان CTF و توسعه‌دهندگان کمک می‌کند تا نرم‌افزارهای کامپایل‌شده را از طریق ایجنت‌هایشان درک کنند. ایجنت خود را به سراغ فایل باینری، برنامه یا داده‌های ضبط‌شده‌ای بفرستید که مجوز تحلیلشان را دارید؛ REA آن را بدون کد منبع بررسی می‌کند، رفتارش را توضیح می‌دهد و شواهد پشت هر نتیجه‌گیری را نشان می‌دهد.
REA ایجنت شما را به ابزارهایی برای بررسی باینری‌های بومی، برنامه‌های JavaScript و Electron، اسمبلی‌های .NET و وب‌سایت‌ها متصل می‌کند. همین ابزارها از ترمینال نیز قابل استفاده‌اند. تحلیل به‌صورت محلی انجام می‌شود و نتایج شامل شواهد و محدودیت‌های پشت هر نتیجه‌گیری هستند.
@@ -47,6 +47,23 @@ REA ایجنت شما را به ابزارهایی برای بررسی باین
> برای دستورالعمل‌های راه‌اندازی، راهنماهای تصویری و مطالعات موردی واقعی، **[به وب‌سایت REA مراجعه کنید](https://rea.tools/fa/)**.
## استفادهٔ مسئولانه
REA برای تحلیل قانونی ساخته شده است: پژوهش امنیتی، تحلیل بدافزار و رخدادهای امنیتی، پژوهش آسیب‌پذیری و افشای هماهنگ، CTF و آموزش، تعامل‌پذیری، حفظ نرم‌افزار، و اشکال‌زدایی یا ممیزی نرم‌افزاری که مالک آن هستید یا مجوز بررسی‌اش را دارید.
پروژهٔ REA از موارد زیر پشتیبانی نمی‌کند و در آن‌ها کمکی نخواهد کرد:
- دور زدن DRM، بررسی‌های لایسنس، سامانه‌های ضدتقلب یا دیگر تدابیر حفاظت فنی؛
- ساخت ابزار تقلب برای بازی‌ها یا دست‌کاری سرویس‌های آنلاین؛
- دور زدن احراز هویت، محافظت در برابر ربات‌ها یا کنترل‌های دسترسی در سامانه‌هایی که مجوز آزمودنشان را ندارید؛
- کپی‌کردن نرم‌افزارهای انحصاری یا بازتولید کد و دارایی‌های محافظت‌شدهٔ آن‌ها؛
- گریز از سیاست‌های استفاده یا تدابیر ایمنی ارائه‌دهندگان مدل‌های هوش مصنوعی؛
- فروش مجدد یا اشتراک‌گذاری حساب‌های هوش مصنوعی یا دسترسی API.
مسئولیت دریافت مجوزهای لازم و رعایت قوانین، توافق‌نامه‌های لایسنس و شرایط خدمات مربوط بر عهدهٔ شماست. مهندسی معکوس ممکن است در حوزهٔ قضایی شما یا طبق لایسنس نرم‌افزاری که تحلیل می‌کنید محدود باشد.
درخواست‌های کمک برای موارد بالا در issueها و بحث‌ها بدون پاسخ بسته می‌شوند و ممکن است به حذف از جامعهٔ REA منجر شوند.
## شروع سریع
### ایجنت خود را راه‌اندازی کنید
@@ -64,10 +81,11 @@ npx rea-agents setup
### از ایجنت خود بپرسید
```text
بررسی کن جست‌وجو در برنامهٔ Notes چگونه کار می‌کند، شواهدش را نشان بده و قابلیتی مشابه برای پروژهٔ من بساز.
نسخهٔ release برنامهٔ من هنگام اجرا کرش می‌کند، اما نسخهٔ debug نه.
فایل ./build/MyApp را بررسی کن، جایی را که این دو build از هم جدا می‌شوند پیدا کن و شواهدش را نشان بده.
```
به‌جای Notes، نام برنامهٔ هدف و قابلیتی را قرار دهید که می‌خواهید درک کنید.
ایجنت خود را به سراغ هدفی بفرستید که مجوز تحلیلش را دارید و توضیح دهید چه چیزی را می‌خواهید درک کنید.
### استفاده از ترمینال
@@ -122,27 +140,23 @@ npx rea-agents@latest setup
REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، به‌همراه npm نیاز دارد. ابزارهای اضافی و پشتیبانی سیستم میزبان به نوع هدف بستگی دارند:
| هدف | خروجی REA | پیش‌نیازها و راهنما |
| ---------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| باینری‌های بومی | شبه‌کد، اسمبلی، رشته‌ها، نمادها، فراخوانی‌ها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](https://rea.tools/fa/guides/native/) |
| ساختار ELF آفلاین | بخش‌ها، سگمنت‌ها، نمادها و relocationهای اصلی و گزینه‌های احتمالی کاهش آسیب‌پذیری ایستا | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](docs/binary-diagnostics.md) |
| بایت‌کد EVM | selectorهای dispatch، offsetهای بایتی، آرگومان‌های استنباط‌شده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](docs/evm-bytecode.md) |
| کرش‌های ثبت‌شدهٔ لینوکس | یادداشت‌های خام، رجیسترها/سیگنال‌های تمام threadهای ثبت‌شده و گزینه‌های احتمالی نگاشت | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ GDB/pwndbg اختیاری؛ [کرش‌های ثبت‌شده](docs/recorded-crashes.md) |
| JavaScript / Electron | ماژول‌ها، importها، source mapها، مسیرها، IPC و ارتباط افزونه‌های بومی | Node.js و npm؛ [تحلیل برنامه](https://rea.tools/fa/guides/javascript/) |
| وب‌سایت‌ها | ساختار صفحه، اسکریپت‌ها، مشاهدات شبکه و اسکرین‌شات‌های درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](https://rea.tools/fa/guides/browser/) |
| داده‌های ضبط‌شدهٔ شبکه | درخواست‌ها، پاسخ‌ها، payloadهای آشکارشده و مکان آن‌ها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبط‌های بومی mitmproxy؛ [راهنمای ضبط شبکه](docs/web-network-captures.md) |
| اسمبلی‌های .NET | فراداده، دستورالعمل‌های CIL، وابستگی‌های بومی اعلام‌شده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریت‌شده](docs/managed-code-analysis.md) |
| فایل‌های APK اندروید | تعاریف Manifest، کلاس‌ها، متدهای دیکامپایل‌شده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS/Windows x64؛ [راهنمای اندروید](docs/android-analysis.md) |
| دستگاه‌های اندروید | دستگاه‌ها، بسته‌ها، فرایندها، لاگ‌ها، دامپ‌ها، اسکرین‌شات‌ها و انتقال APK/فایل | adb تأمین‌شده توسط فراخوان‌کننده (شبیه‌ساز یا دستگاه)؛ [راهنمای ADB](docs/adb-device-analysis.md) |
| پروژه‌های JEB | واحدهای پروژه از موتور، هش‌های مصنوع و شبه‌کدِ نوع/متد | یک کلاینت JEB که توسط فراخوان‌کننده اجرا شده و MCP ارائه می‌دهد و با REA_JEB_MCP_URL انتخاب می‌شود؛ [راهنمای JEB](docs/jeb-analysis.md) |
| منابع اندروید | مانیفست رمزگشایی‌شده، جداول رشته‌ها، زبان‌ها و اطلاعات نسخه | راه‌انداز Apktool تأمین‌شده توسط فراخوان‌کننده؛ [راهنمای منابع](docs/apktool-resource-analysis.md) |
| برنامه‌های فلاتر | هش اسنپ‌شات دارت، هش کتابخانه‌ها به تفکیک ABI و اصالت بیلد موتور | هیچ (تحلیل ایستا APK)؛ [راهنمای فلاتر](docs/flutter-analysis.md) |
| Firmware | ناحیه‌ها، نتایج استخراج و تحویل به ابزارهای تحلیل بومی | Binwalk / Unblob در لینوکس؛ [راهنمای Firmware](docs/firmware-analysis.md) |
| بسته‌های ضبط‌شده | فیلدهای منتخب، مقادیر تکراری، فیلترها و قواعد رمزگشایی | Linux: TShark 4.x + prlimit; [راهنمای ضبط بسته](docs/packet-captures.md) |
| ضبط بسته‌ها | نقاط پایانی، DNS، TLS SNI، توزیع پروتکل و درخواست‌های HTTP | tshark و capinfos تأمین‌شده توسط فراخوان‌کننده؛ [راهنمای pcap](docs/pcap-analysis.md) |
| سیگنال‌های منطقی ضبط‌شده | توضیحات رمزگشا، بازه‌های نمونه و اطلاعات عیب‌یابی | Linux: sigrok-cli 0.7.2 + prlimit; [راهنمای سیگنال‌ها](docs/signal-recordings.md) |
| بسته‌ها و منابع | فهرست فایل‌ها، digestها، فایل‌های plist، ساختار bundle اپل و منابع استخراج‌شده | [راهنمای آرتیفکت و JavaScript](docs/javascript-artifact-reconstruction.md)، [برنامه‌های اپل](docs/apple-application-analysis.md) |
| رفتار فرایند | خروجی ترمینال، تعاملات، وضعیت خروج، مشاهدات سیستم فایل و مقایسهٔ اجراها | Linux/macOS با PTY بومی؛ [ضبط فرایند](docs/process-capture.md) |
| هدف | خروجی REA | پیش‌نیازها و راهنما |
| --------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| باینری‌های بومی | شبه‌کد، اسمبلی، رشته‌ها، نمادها، فراخوانی‌ها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](https://rea.tools/fa/guides/native/) |
| ساختار ELF آفلاین | بخش‌ها، سگمنت‌ها، نمادها و relocationهای اصلی و گزینه‌های احتمالی کاهش آسیب‌پذیری ایستا | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](docs/binary-diagnostics.md) |
| بایت‌کد EVM | selectorهای dispatch، offsetهای بایتی، آرگومان‌های استنباط‌شده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](docs/evm-bytecode.md) |
| کرش‌های ثبت‌شدهٔ لینوکس | یادداشت‌های خام، رجیسترها/سیگنال‌های تمام threadهای ثبت‌شده و گزینه‌های احتمالی نگاشت | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ GDB/pwndbg اختیاری؛ [کرش‌های ثبت‌شده](docs/recorded-crashes.md) |
| JavaScript / Electron | ماژول‌ها، importها، source mapها، مسیرها، IPC و ارتباط افزونه‌های بومی | Node.js و npm؛ [تحلیل برنامه](https://rea.tools/fa/guides/javascript/) |
| وب‌سایت‌ها | ساختار صفحه، اسکریپت‌ها، مشاهدات شبکه و اسکرین‌شات‌های درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](https://rea.tools/fa/guides/browser/) |
| داده‌های ضبط‌شدهٔ شبکه | درخواست‌ها، پاسخ‌ها، payloadهای آشکارشده و مکان آن‌ها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبط‌های بومی mitmproxy؛ [راهنمای ضبط شبکه](docs/web-network-captures.md) |
| اسمبلی‌های .NET | فراداده، دستورالعمل‌های CIL، وابستگی‌های بومی اعلام‌شده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریت‌شده](docs/managed-code-analysis.md) |
| فایل‌های APK اندروید | تعاریف Manifest، کلاس‌ها، متدهای دیکامپایل‌شده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS/Windows x64؛ [راهنمای اندروید](docs/android-analysis.md) |
| دستگاه‌های اندروید | دستگاه‌ها، بسته‌ها، فرایندها، لاگ‌ها، دامپ‌ها، اسکرین‌شات‌ها و انتقال APK/فایل | adb تأمین‌شده توسط فراخوان‌کننده (شبیه‌ساز یا دستگاه)؛ [راهنمای ADB](docs/adb-device-analysis.md) |
| پروژه‌های JEB | واحدهای پروژه از موتور، هش‌های مصنوع و شبه‌کدِ نوع/متد | یک کلاینت JEB که توسط فراخوان‌کننده اجرا شده و MCP ارائه می‌دهد و با REA_JEB_MCP_URL انتخاب می‌شود؛ [راهنمای JEB](docs/jeb-analysis.md) |
| منابع اندروید | مانیفست رمزگشایی‌شده، جداول رشته‌ها، زبان‌ها و اطلاعات نسخه | راه‌انداز Apktool تأمین‌شده توسط فراخوان‌کننده؛ [راهنمای منابع](docs/apktool-resource-analysis.md) |
| Firmware | ناحیه‌ها، نتایج استخراج و تحویل به ابزارهای تحلیل بومی | Binwalk / Unblob در لینوکس؛ [راهنمای Firmware](docs/firmware-analysis.md) |
| بسته‌ها و منابع | فهرست فایل‌ها، digestها، فایل‌های plist، ساختار bundle اپل و منابع استخراج‌شده | [راهنمای آرتیفکت و JavaScript](docs/javascript-artifact-reconstruction.md)، [برنامه‌های اپل](docs/apple-application-analysis.md) |
| رفتار فرایند | خروجی ترمینال، تعاملات، وضعیت خروج، مشاهدات سیستم فایل و مقایسهٔ اجراها | Linux/macOS با PTY بومی؛ [ضبط فرایند](docs/process-capture.md) |
بررسی ایستای JavaScript و .NET فایل‌های ارائه‌شده را بدون اجرای برنامه می‌خواند. ضبط زمان اجرا، هدف انتخاب‌شده را با مجوزهای کاربری شما اجرا می‌کند یا با آن تعامل دارد؛ آثار این عملیات در راهنمای مربوط به هر نوع ضبط توضیح داده شده‌اند.
@@ -247,7 +261,7 @@ npx rea-agents@latest setup
## تاریخچهٔ ستاره‌ها
🎉 **۱۷۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
🎉 **۱۱۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
از همهٔ کسانی که از REA استفاده می‌کنند، خطاها را گزارش می‌دهند، قابلیت‌های جدید پیشنهاد می‌کنند، buildها را آزمایش می‌کنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
@@ -255,13 +269,7 @@ npx rea-agents@latest setup
## سلب مسئولیت
برای راهنمای استفادهٔ مسئولانه، [DISCLAIMER.md](DISCLAIMER.md) را ببینید.
REA برای پژوهش، آموزش، تعامل‌پذیری، حفظ نرم‌افزار و تحلیل نرم‌افزارهایی است که مالک آن‌ها هستید یا اجازهٔ بررسی آن‌ها را دارید، در چارچوب قانون.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
به [استفادهٔ مسئولانه](#استفادهٔ-مسئولانه) مراجعه کنید.
## مشارکت
@@ -273,16 +281,4 @@ applicable licenses.
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
</div>
+24 -29
View File
@@ -6,7 +6,7 @@
### Un seul MCP pour la rétro-ingénierie des binaires, des applications et du comportement à l'exécution.
**Repérez une fonctionnalité qui vous plaît. Comprenez son fonctionnement, jusqu'au niveau du binaire.**
**Comprenez le fonctionnement des logiciels, jusqu'au niveau du binaire — pour la recherche en sécurité, l'interopérabilité et les logiciels que vous êtes autorisé à analyser.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Vous avez repéré dans une application une fonctionnalité que vous aimeriez avoir dans votre propre produit ? Demandez à votre agent de l'étudier avec REA. Il peut inspecter l'application sans son code source, expliquer le fonctionnement de la fonctionnalité, présenter les preuves et en construire une version pour votre projet.
REA aide les chercheurs en sécurité, les analystes de logiciels malveillants, les joueurs de CTF et les développeurs à comprendre des logiciels compilés grâce à leurs agents. Confiez à votre agent un binaire, une application ou une capture que vous êtes autorisé à analyser ; REA l'inspecte sans code source, explique son comportement et présente les preuves sur lesquelles repose chaque conclusion.
REA connecte votre agent à des outils d'inspection de binaires natifs, d'applications JavaScript et Electron, d'assemblys .NET et de sites web. Les mêmes outils sont aussi disponibles depuis votre terminal. L'analyse s'exécute localement, et chaque conclusion s'accompagne des preuves et des limites sur lesquelles elle repose.
@@ -55,6 +55,23 @@ Setup enregistre REA auprès de votre agent et installe les instructions de work
> **[Visitez le site web de REA](https://rea.tools/fr/)** pour les instructions d'installation, des guides illustrés et des études de cas réelles.
## Utilisation responsable
REA est conçu pour l'analyse licite : recherche en sécurité, analyse de logiciels malveillants et d'incidents, recherche de vulnérabilités et divulgation coordonnée, CTF et enseignement, interopérabilité, préservation des logiciels, ainsi que débogage ou audit de logiciels qui vous appartiennent ou que vous êtes autorisé à examiner.
Le projet REA ne soutient pas les usages suivants et n'y apportera aucune aide :
- contourner des DRM, des vérifications de licence, des systèmes anti-triche ou d'autres mesures techniques de protection ;
- développer des triches pour des jeux ou altérer des services en ligne ;
- contourner l'authentification, la protection contre les bots ou les contrôles d'accès de systèmes que vous n'êtes pas autorisé à tester ;
- copier des logiciels propriétaires ou reproduire leur code et leurs ressources protégés ;
- échapper aux politiques d'utilisation ou aux mesures de sécurité des fournisseurs de modèles d'IA ;
- revendre ou partager des comptes d'IA ou des accès à des API.
Il vous appartient d'obtenir toute autorisation nécessaire et de respecter les lois, les contrats de licence et les conditions d'utilisation applicables. La rétro-ingénierie peut être restreinte dans votre juridiction ou par la licence du logiciel que vous analysez.
Les demandes d'aide pour les usages ci-dessus seront fermées sans réponse dans les issues et les discussions, et peuvent entraîner l'exclusion de la communauté REA.
## Démarrage rapide
### Configurer votre agent
@@ -72,11 +89,11 @@ Setup prend en charge Claude Code, Codex, Cursor, Gemini CLI, Grok Build et [d'a
### Interroger votre agent
```text
Comprends comment fonctionne la recherche dans l'app Notes, montre-moi les preuves
et construis une fonctionnalité similaire pour mon projet.
La version release de mon app plante au démarrage, mais pas la version debug.
Inspecte ./build/MyApp, trouve où les deux builds divergent et montre-moi les preuves.
```
Remplacez Notes par votre application cible et la fonctionnalité que vous voulez comprendre.
Confiez à votre agent une cible que vous êtes autorisé à analyser et décrivez ce que vous voulez comprendre.
### Utiliser le terminal
@@ -143,16 +160,12 @@ REA nécessite Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, ainsi que npm. Les
| JavaScript / Electron | Modules, imports, source maps, routes, IPC et relations avec les modules natifs | Node.js et npm ; [analyse d'applications](https://rea.tools/fr/guides/javascript/) |
| Sites web | Structure des pages, scripts, observations réseau et captures d'écran demandées | Un navigateur de la famille Chrome ; [analyse du navigateur](https://rea.tools/fr/guides/browser/) |
| Captures réseau enregistrées | Requêtes, réponses, payloads exposés et emplacements dans le code source | HAR ; mitmdump sous Linux pour les captures mitmproxy natives ; [guide des captures](docs/web-network-captures.md) |
| Captures de paquets | Points de terminaison, DNS, TLS SNI, distribution des protocoles et requêtes HTTP | tshark et capinfos fournis par l'appelant ; [guide pcap](docs/pcap-analysis.md) |
| Assemblys .NET | Métadonnées, instructions CIL, dépendances natives déclarées et comparaisons de builds | Inspection statique ; [guide du code managé](docs/managed-code-analysis.md) |
| APK Android | Déclarations du manifeste, classes, méthodes décompilées et références | JADX headless et un JDK complet sous Linux/macOS/Windows x64 ; [guide Android](docs/android-analysis.md) |
| Appareils Android | Appareils, paquets, processus, journaux, dumps, captures d'écran et transferts d'APK/fichiers | adb fourni par l'appelant (émulateur ou appareil) ; [guide ADB](docs/adb-device-analysis.md) |
| Projets JEB | Unités de projet fournies par le moteur, condensés d'artefacts et pseudo-code de types/méthodes | Un client JEB démarré par l'appelant servant MCP, sélectionné via REA_JEB_MCP_URL ; [guide JEB](docs/jeb-analysis.md) |
| Ressources Android | Manifeste décodé, tables de chaînes, langues et faits de version | Lanceur Apktool fourni par l'appelant ; [guide des ressources](docs/apktool-resource-analysis.md) |
| Applications Flutter | Empreinte de snapshot Dart, condensés de bibliothèques par ABI et provenance de build du moteur | Aucune (analyse APK statique) ; [guide Flutter](docs/flutter-analysis.md) |
| Firmware | Régions, résultats d'extraction et passage de relais vers l'analyse native | Binwalk / Unblob sous Linux ; [guide firmware](docs/firmware-analysis.md) |
| Paquets enregistrés | Champs sélectionnés, valeurs répétées, filtres et règles de décodage | Linux: TShark 4.x + prlimit; [guide des captures](docs/packet-captures.md) |
| Signaux logiques enregistrés | Annotations du décodeur, plages d’échantillons et diagnostics | Linux: sigrok-cli 0.7.2 + prlimit; [guide des signaux](docs/signal-recordings.md) |
| Paquets et ressources | Inventaires de fichiers, empreintes, plists, anatomie des bundles Apple et ressources extraites | [Guide artefacts et JavaScript](docs/javascript-artifact-reconstruction.md), [applications Apple](docs/apple-application-analysis.md) |
| Comportement des processus | Sortie du terminal, interactions, code de sortie, observations du système de fichiers et comparaisons | Linux/macOS avec un PTY natif ; [capture de processus](docs/process-capture.md) |
@@ -266,7 +279,7 @@ Signalez les vulnérabilités via [SECURITY.md](SECURITY.md).
## Historique des étoiles
🎉 **170 000 étoiles GitHub — merci !**
🎉 **110 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.
@@ -280,13 +293,7 @@ Merci à toutes les personnes qui utilisent REA, signalent des bugs, proposent d
## Avertissement
Consultez [DISCLAIMER.md](DISCLAIMER.md) pour les consignes d'utilisation responsable.
REA est destiné à la recherche, à l’éducation, à l’interopérabilité, à la préservation logicielle et à l’analyse de logiciels que vous possédez ou êtes autorisé à examiner, dans le respect de la loi.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
Voir [Utilisation responsable](#utilisation-responsable).
## Contribuer
@@ -297,15 +304,3 @@ Consultez [CONTRIBUTING.md](CONTRIBUTING.md) pour l'environnement de développem
## Licence
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+25 -27
View File
@@ -6,7 +6,7 @@
### Satu MCP untuk rekayasa balik pada berbagai biner, aplikasi, dan perilaku saat runtime.
**Melihat fitur yang Anda sukai. Pahami cara kerjanya hingga ke tingkat biner.**
**Pahami cara kerja perangkat lunak hingga ke tingkat biner — untuk riset keamanan, interoperabilitas, dan perangkat lunak yang diizinkan untuk Anda analisis.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Melihat fitur dalam suatu aplikasi yang ingin Anda hadirkan di produk sendiri? Minta agen Anda menyelidikinya menggunakan REA. REA dapat memeriksa aplikasi tanpa kode sumbernya, menjelaskan cara kerja fitur tersebut, menunjukkan bukti, dan membangun versi untuk proyek Anda.
REA membantu peneliti keamanan, analis malware, pemain CTF, dan pengembang memahami perangkat lunak terkompilasi melalui agen mereka. Arahkan agen Anda ke biner, aplikasi, atau rekaman yang diizinkan untuk Anda analisis; REA memeriksanya tanpa kode sumber, menjelaskan perilakunya, dan menunjukkan bukti di balik setiap kesimpulan.
REA menghubungkan agen Anda dengan berbagai alat untuk memeriksa biner native, aplikasi JavaScript dan Electron, assembly .NET, serta situs web. Anda juga dapat menggunakan alat yang sama dari terminal. Analisis dijalankan secara lokal, dan hasilnya mencakup bukti serta keterbatasan yang mendasari setiap kesimpulan.
@@ -55,6 +55,23 @@ Proses penyiapan mendaftarkan REA ke agen Anda dan memasang instruksi alur kerja
> **[Kunjungi situs web REA](https://rea.tools/id/)** untuk mendapatkan petunjuk penyiapan, panduan bergambar, dan studi kasus nyata.
## Penggunaan yang Bertanggung Jawab
REA dibuat untuk analisis yang sah: riset keamanan, analisis malware dan insiden, riset kerentanan dan pengungkapan terkoordinasi, CTF dan pendidikan, interoperabilitas, pelestarian perangkat lunak, serta debugging atau audit perangkat lunak yang Anda miliki atau yang diizinkan untuk Anda periksa.
Proyek REA tidak mendukung, dan tidak akan membantu, hal-hal berikut:
- mengakali DRM, pemeriksaan lisensi, sistem anti-cheat, atau langkah perlindungan teknis lainnya;
- mengembangkan cheat game atau memanipulasi layanan online;
- melewati autentikasi, perlindungan bot, atau kontrol akses pada sistem yang tidak diizinkan untuk Anda uji;
- menyalin perangkat lunak berpemilik atau mereproduksi kode dan aset yang dilindunginya;
- menghindari kebijakan penggunaan atau langkah keamanan penyedia model AI;
- menjual kembali atau membagikan akun AI atau akses API.
Anda bertanggung jawab untuk memperoleh otorisasi yang diperlukan dan mematuhi hukum, perjanjian lisensi, serta ketentuan layanan yang berlaku. Rekayasa balik mungkin dibatasi di yurisdiksi Anda atau oleh lisensi perangkat lunak yang Anda analisis.
Permintaan bantuan untuk penggunaan di atas akan ditutup tanpa tanggapan di issue dan diskusi, dan dapat berujung pada pengeluaran dari komunitas REA.
## Mulai Cepat
### Siapkan agen Anda
@@ -72,10 +89,11 @@ Penyiapan mendukung Claude Code, Codex, Cursor, Gemini CLI, Grok Build, dan [age
### Minta agen Anda
```text
Pahami cara kerja pencarian di aplikasi Notes, tunjukkan buktinya, dan buat fitur serupa untuk proyek saya.
Build rilis aplikasi saya crash saat dijalankan, tetapi build debug tidak.
Periksa ./build/MyApp, temukan titik perbedaan kedua build, dan tunjukkan buktinya.
```
Ganti Notes dengan aplikasi target dan fitur yang ingin Anda pahami.
Arahkan agen Anda ke target yang diizinkan untuk Anda analisis dan jelaskan apa yang ingin Anda pahami.
### Gunakan terminal
@@ -146,16 +164,12 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
| JavaScript / Electron | Modul, impor, source map, rute, IPC, dan hubungan add-on native | Node.js dan npm; [analisis aplikasi](https://rea.tools/id/guides/javascript/) |
| Situs web | Struktur halaman, skrip, pengamatan jaringan, dan tangkapan layar yang diminta | Peramban berbasis Chrome; [analisis peramban](https://rea.tools/id/guides/browser/) |
| Rekaman jaringan tersimpan | Permintaan, respons, payload yang terekspos, dan lokasi sumber | HAR; mitmdump di Linux untuk rekaman native mitmproxy; [panduan rekaman](docs/web-network-captures.md) |
| Capturan paket | Endpoint, DNS, TLS SNI, distribusi protokol, dan permintaan HTTP | tshark dan capinfos buatan pemanggil; [panduan pcap](docs/pcap-analysis.md) |
| Assembly .NET | Metadata, instruksi CIL, dependensi native yang dideklarasikan, dan perbandingan build | Tidak ada (hanya analisis statis); [panduan kode terkelola](docs/managed-code-analysis.md) |
| APK Android | Deklarasi manifest, kelas, metode hasil dekompilasi, dan referensi | JADX mode headless dan JDK lengkap di Linux/macOS/Windows x64; [panduan Android](docs/android-analysis.md) |
| Perangkat Android | Perangkat, paket, proses, log, dump, tangkapan layar, serta transfer APK/berkas | adb buatan pemanggil (emulator atau perangkat); [panduan ADB](docs/adb-device-analysis.md) |
| Proyek JEB | Unit proyek bertenaga mesin, hash artefak, dan pseudokode tipe/metode | Klien JEB yang dijalankan pemanggil dan menyajikan MCP, dipilih dengan REA_JEB_MCP_URL; [panduan JEB](docs/jeb-analysis.md) |
| Resource Android | Manifest terdekode, tabel string, lokal, dan fakta versi | Peluncur Apktool buatan pemanggil; [panduan resource](docs/apktool-resource-analysis.md) |
| Aplikasi Flutter | Hash snapshot Dart, hash pustaka per ABI, dan asal build engine | Tidak ada (parsing APK statis); [panduan Flutter](docs/flutter-analysis.md) |
| Firmware | Wilayah, hasil ekstraksi, dan pengalihan ke analisis native | Binwalk / Unblob di Linux; [panduan firmware](docs/firmware-analysis.md) |
| Paket rekaman | Kolom terpilih, nilai berulang, filter, dan aturan decode-as | Linux: TShark 4.x + prlimit; [panduan tangkapan](docs/packet-captures.md) |
| Sinyal logika terekam | Anotasi dekoder, rentang sampel, dan diagnostik | Linux: sigrok-cli 0.7.2 + prlimit; [panduan sinyal](docs/signal-recordings.md) |
| Paket dan sumber daya | Inventaris berkas, digest, plist, struktur paket Apple, dan sumber daya yang diekstrak | [Panduan artefak dan JavaScript](docs/javascript-artifact-reconstruction.md), [aplikasi Apple](docs/apple-application-analysis.md) |
| Perilaku proses | Keluaran terminal, interaksi, pengamatan proses keluar dan sistem berkas, serta perbandingan eksekusi | Linux/macOS dengan PTY native; [perekaman proses](docs/process-capture.md) |
@@ -287,7 +301,7 @@ Laporkan kerentanan melalui [SECURITY.md](SECURITY.md).
## Riwayat Bintang
🎉 **170.000 bintang GitHub, terima kasih!**
🎉 **110.000 bintang GitHub, terima kasih!**
Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fitur, menguji build, dan berkontribusi dalam perbaikan.
@@ -301,13 +315,9 @@ Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fi
## Penafian
Lihat [DISCLAIMER.md](DISCLAIMER.md) untuk panduan penggunaan yang bertanggung jawab.
Lihat [Penggunaan yang Bertanggung Jawab](#penggunaan-yang-bertanggung-jawab).
REA ditujukan untuk penelitian, pendidikan, interoperabilitas, pelestarian perangkat lunak, dan analisis perangkat lunak yang Anda miliki atau diizinkan untuk Anda periksa, sesuai hukum.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
REA adalah proyek perangkat lunak sumber terbuka. Kami tidak menerbitkan atau mendukung mata uang kripto maupun token apa pun. Token yang menggunakan nama REA tidak berafiliasi dengan proyek ini.
## Kontribusi
@@ -318,15 +328,3 @@ Lihat [CONTRIBUTING.md](CONTRIBUTING.md) untuk penyiapan pengembangan dan pemeri
## Lisensi
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+25 -28
View File
@@ -6,7 +6,7 @@
### Un unico MCP per l'ingegneria inversa su binari, applicazioni e comportamento a runtime.
**Vedi una funzionalità che ti piace. Capisci come funziona, fino al livello binario.**
**Capisci come funziona il software, fino al livello binario — per la ricerca sulla sicurezza, l'interoperabilità e il software che sei autorizzato ad analizzare.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Hai visto una funzionalità in un'app che vorresti nel tuo prodotto? Chiedi al tuo agente di analizzarla con REA. Può ispezionare l'app senza il suo codice sorgente, spiegare come funziona la funzionalità, mostrare le prove e realizzare una versione per il tuo progetto.
REA aiuta ricercatori di sicurezza, analisti di malware, giocatori di CTF e sviluppatori a capire il software compilato attraverso i loro agenti. Indirizza il tuo agente verso un binario, un'applicazione o un'acquisizione che sei autorizzato ad analizzare; REA lo ispeziona senza codice sorgente, ne spiega il comportamento e mostra le prove alla base di ogni conclusione.
REA collega il tuo agente a strumenti per ispezionare binari nativi, app JavaScript ed Electron, assembly .NET e siti web. Puoi usare gli stessi strumenti anche dal terminale. L'analisi viene eseguita localmente e i risultati includono le prove e i limiti dietro ogni conclusione.
@@ -55,6 +55,23 @@ La configurazione registra REA con il tuo agente e installa le istruzioni di wor
> **[Visita il sito web di REA](https://rea.tools/it/)** per istruzioni di configurazione, guide illustrate e veri casi studio.
## Uso responsabile
REA è pensato per l'analisi lecita: ricerca sulla sicurezza, analisi di malware e incidenti, ricerca di vulnerabilità e divulgazione coordinata, CTF e formazione, interoperabilità, conservazione del software, e debugging o audit di software che possiedi o che sei autorizzato a esaminare.
Il progetto REA non supporta i seguenti usi e non fornirà aiuto per:
- aggirare DRM, controlli di licenza, sistemi anti-cheat o altre misure tecniche di protezione;
- sviluppare cheat per videogiochi o manomettere servizi online;
- eludere autenticazione, protezioni anti-bot o controlli di accesso su sistemi che non sei autorizzato a testare;
- copiare software proprietario o riprodurne il codice e gli asset protetti;
- eludere le politiche d'uso o le misure di sicurezza dei fornitori di modelli di IA;
- rivendere o condividere account di IA o accessi API.
Sei responsabile di ottenere le eventuali autorizzazioni richieste e di rispettare le leggi, i contratti di licenza e i termini di servizio applicabili. L'ingegneria inversa può essere limitata nella tua giurisdizione o dalla licenza del software che analizzi.
Le richieste di aiuto per gli usi sopra elencati verranno chiuse senza risposta nelle issue e nelle discussioni e possono comportare l'allontanamento dalla community di REA.
## Avvio rapido
### Configura il tuo agente
@@ -72,11 +89,11 @@ La configurazione supporta Claude Code, Codex, Cursor, Gemini CLI, Grok Build e
### Chiedi al tuo agente
```text
Spiega come funziona la ricerca nell'app Note, mostrami le prove e realizza
una funzionalità simile per il mio progetto.
La build di release della mia app va in crash all'avvio, ma la build di debug no.
Ispeziona ./build/MyApp, trova dove le due build divergono e mostrami le prove.
```
Sostituisci Note con la tua app di destinazione e la funzionalità che vuoi capire.
Indirizza il tuo agente verso un obiettivo che sei autorizzato ad analizzare e descrivi cosa vuoi capire.
### Usa il terminale
@@ -143,16 +160,12 @@ REA richiede Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, oltre a npm. Strument
| JavaScript / Electron | Moduli, import, source map, route, IPC e relazioni con add-on nativi | Node.js e npm; [analisi delle applicazioni](https://rea.tools/it/guides/javascript/) |
| Siti web | Struttura della pagina, script, osservazioni di rete e screenshot richiesti | Un browser della famiglia Chrome; [analisi browser](https://rea.tools/it/guides/browser/) |
| Acquisizioni di rete salvate | Richieste, risposte, payload esposti e posizioni sorgente | HAR; mitmdump su Linux per acquisizioni mitmproxy native; [guida alle acquisizioni](docs/web-network-captures.md) |
| Captured di pacchetti | Endpoint, DNS, TLS SNI, distribuzione dei protocolli e richieste HTTP | tshark e capinfos forniti dal chiamante; [guida pcap](docs/pcap-analysis.md) |
| Assembly .NET | Metadati, istruzioni CIL, dipendenze native dichiarate e confronti di build | Nessuno (solo statico); [guida managed-code](docs/managed-code-analysis.md) |
| APK Android | Dichiarazioni manifest, classi, metodi decompilati e riferimenti | JADX headless e un JDK completo su Linux/macOS/Windows x64; [guida Android](docs/android-analysis.md) |
| Dispositivi Android | Dispositivi, pacchetti, processi, log, dump, screenshot e trasferimenti APK/file | adb fornito dal chiamante (emulatore o hardware); [guida ADB](docs/adb-device-analysis.md) |
| Progetti JEB | Unità di progetto dal motore, digest degli artifact e pseudocodice di tipi/metodi | Client JEB avviato dal chiamante via MCP, selezionato con REA_JEB_MCP_URL; [guida JEB](docs/jeb-analysis.md) |
| Risorse Android | Manifest decodificato, tabelle stringhe, lingue e dati di versione | Launcher Apktool fornito dal chiamante; [guida alle risorse](docs/apktool-resource-analysis.md) |
| App Flutter | Hash dello snapshot Dart, digest delle librerie per ABI e provenienza della build del motore | Nessuno (analisi APK statica); [guida Flutter](docs/flutter-analysis.md) |
| Firmware | Regioni, risultati di estrazione e passaggi all'analisi nativa | Binwalk / Unblob su Linux; [guida firmware](docs/firmware-analysis.md) |
| Pacchetti registrati | Campi selezionati, valori ripetuti, filtri e regole di decodifica | Linux: TShark 4.x + prlimit; [guida alle catture](docs/packet-captures.md) |
| Segnali logici registrati | Annotazioni del decoder, intervalli di campioni e diagnostica | Linux: sigrok-cli 0.7.2 + prlimit; [guida ai segnali](docs/signal-recordings.md) |
| Pacchetti e risorse | Inventari file, digest, plist, anatomia dei bundle Apple e risorse estratte | [Guida artifact e JavaScript](docs/javascript-artifact-reconstruction.md), [Applicazioni Apple](docs/apple-application-analysis.md) |
| Comportamento dei processi | Output del terminale, interazioni, osservazioni su uscita e filesystem ed confronti di esecuzione | Linux/macOS con un PTY nativo; [cattura dei processi](docs/process-capture.md) |
@@ -266,7 +279,7 @@ Segnala vulnerabilità tramite [SECURITY.md](SECURITY.md).
## Cronologia delle stelle
🎉 **170.000 stelle su GitHub — grazie!**
🎉 **110.000 stelle su GitHub — grazie!**
Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, testano le build e contribuiscono con correzioni.
@@ -280,13 +293,9 @@ Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, te
## Disclaimer
Consulta [DISCLAIMER.md](DISCLAIMER.md) per le indicazioni sull'uso responsabile.
Vedi [Uso responsabile](#uso-responsabile).
REA è destinato alla ricerca, alla formazione, all’interoperabilità, alla conservazione del software e all’analisi di software di tua proprietà o che sei autorizzato a esaminare, nel rispetto della legge.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
REA è un progetto software open-source. Non abbiamo emesso né approvato alcuna criptovaluta o token. I token che usano il nome REA non sono affiliati al progetto.
## Contributing
@@ -297,15 +306,3 @@ Vedi [CONTRIBUTING.md](CONTRIBUTING.md) per la configurazione di sviluppo e i co
## License
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### バイナリ、アプリケーション、実行時の動作を、ひとつの MCP でリバースエンジニアリング。
**気に入った機能を見つけたら、その仕組みをバイナリのレベルまで理解する。**
**ソフトウェアの仕組みを、バイナリのレベルまで理解する。セキュリティ研究、相互運用性、そして分析を許可されたソフトウェアのために。**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
アプリに、自分の製品にも取り入れたい機能を見つけましたか?エージェントに REA で調査を依頼してください。ソースコードがなくてもアプリを調べ、機能の仕組みを説明し、根拠を示したうえで、あなたのプロジェクト向けに実装できます。
REA は、セキュリティ研究者、マルウェアアナリスト、CTF プレイヤー、開発者が、エージェントを通じてコンパイル済みソフトウェアを理解できるよう支援します。分析を許可されたバイナリ、アプリケーション、キャプチャをエージェントに指定してください。REA はソースコードなしでそれを調べ、動作を説明し、各結論の根拠を示します。
REA はエージェントを分析ツールにつなぎ、ネイティブバイナリ、JavaScript や Electron のアプリ、.NET アセンブリ、ウェブサイトを調べられるようにします。同じツールをターミナルからも使えます。分析はローカルで実行され、結果には各結論を裏付ける根拠と制限事項が含まれます。
@@ -55,6 +55,23 @@ REA はエージェントを分析ツールにつなぎ、ネイティブバイ
> **[REA のウェブサイト](https://rea.tools/ja/)**で、セットアップ手順、図解ガイド、実際の事例を確認できます。
## 責任ある利用
REA は合法的な分析のために作られています。対象は、セキュリティ研究、マルウェアやインシデントの分析、脆弱性研究と協調的な開示、CTF と教育、相互運用性、ソフトウェアの保存、そして自分が所有するソフトウェアや調査を許可されたソフトウェアのデバッグや監査です。
REA プロジェクトは、次の用途を支持せず、その手助けも行いません。
- DRM、ライセンスチェック、アンチチートシステム、その他の技術的保護手段の回避
- ゲームのチート開発やオンラインサービスの改ざん
- テストを許可されていないシステムにおける認証、ボット対策、アクセス制御の回避
- プロプライエタリソフトウェアの複製や、その保護されたコードやアセットの再現
- AI モデル提供者の利用ポリシーや安全対策のすり抜け
- AI アカウントや API アクセスの転売・共有
必要な許可を得て、適用される法律、ライセンス契約、利用規約に従う責任は利用者にあります。リバースエンジニアリングは、お住まいの法域や、分析するソフトウェアのライセンスによって制限されている場合があります。
上記の用途に関する支援の依頼は、issue やディスカッションで返答なしにクローズされ、REA コミュニティからの除外につながる場合があります。
## クイックスタート
### エージェントを設定する
@@ -72,10 +89,11 @@ npx rea-agents setup
### エージェントに依頼する
```text
Notes アプリの検索機能の仕組みを調べ、根拠を示して、私のプロジェクトにも同様の機能を実装してください。
私のアプリのリリースビルドは起動時にクラッシュしますが、デバッグビルドではクラッシュしません。
./build/MyApp を調べて、2 つのビルドがどこで分岐するかを見つけ、根拠を示してください。
```
Notes を対象のアプリに置き換え、理解したい機能を指定してください。
分析を許可された対象をエージェントに指定し、理解したい内容を説明してください。
### ターミナルを使う
@@ -139,16 +157,12 @@ REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm
| JavaScript / Electron | モジュール、インポート、ソースマップ、ルート、IPC、ネイティブアドオンの関係 | Node.js と npm;[アプリケーション分析](https://rea.tools/ja/guides/javascript/) |
| ウェブサイト | ページ構造、スクリプト、ネットワークの観測結果、依頼されたスクリーンショット | Chrome 系ブラウザー;[ブラウザー分析](https://rea.tools/ja/guides/browser/) |
| 保存済みのネットワークキャプチャ | リクエスト、レスポンス、取得可能なペイロード、ソース内の位置 | HAR;mitmproxy ネイティブ形式のキャプチャには Linux 上の mitmdump;[キャプチャガイド](docs/web-network-captures.md) |
| パケットキャプチャ | エンドポイント、DNS、TLS SNI、プロトコル分布、HTTPリクエスト | 呼び出し側が用意した tshark と capinfos;[pcapガイド](docs/pcap-analysis.md) |
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](docs/managed-code-analysis.md) |
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS/Windows x64 上のヘッドレス JADX と完全な JDK;[Android ガイド](docs/android-analysis.md) |
| Android デバイス | デバイス、パッケージ、プロセス、ログ、ダンプ、スクリーンキャプチャ、APK/ファイル転送 | 呼び出し側が用意した adb(エミュレーターまたは実機);[ADB ガイド](docs/adb-device-analysis.md) |
| JEBプロジェクト | エンジンによるプロジェクトユニット、アーティファクトのダイジェスト、型/メソッドの擬似コード | 呼び出し側が起動し MCP を提供する JEB クライアント(REA_JEB_MCP_URL で選択);[JEB ガイド](docs/jeb-analysis.md) |
| Android リソース | デコードされたマニフェスト、文字列テーブル、ロケール、バージョン情報 | 呼び出し側が用意した Apktool ランチャー;[リソースガイド](docs/apktool-resource-analysis.md) |
| Flutter アプリ | Dart スナップショットハッシュ、ABI ごとのライブラリダイジェスト、エンジンビルドの来歴 | 不要(静的 APK 解析);[Flutter ガイド](docs/flutter-analysis.md) |
| ファームウェア | 領域、抽出結果、ネイティブ分析への引き継ぎ | Linux 上の Binwalk / Unblob;[ファームウェアガイド](docs/firmware-analysis.md) |
| 記録済みパケット | 選択フィールド、繰り返し値、フィルター、デコード指定 | Linux: TShark 4.x + prlimit; [キャプチャガイド](docs/packet-captures.md) |
| 記録済みロジック信号 | デコーダ注釈、サンプル範囲、診断情報 | Linux: sigrok-cli 0.7.2 + prlimit; [信号記録ガイド](docs/signal-recordings.md) |
| パッケージとリソース | ファイル一覧、ダイジェスト、plist、Apple バンドルの構造、抽出されたリソース | [アーティファクトと JavaScript のガイド](docs/javascript-artifact-reconstruction.md)、[Apple アプリケーション](docs/apple-application-analysis.md) |
| プロセスの動作 | ターミナル出力、対話、終了とファイルシステムの観測結果、実行の比較 | ネイティブ PTY を備えた Linux/macOS;[プロセスキャプチャ](docs/process-capture.md) |
@@ -264,7 +278,7 @@ npx rea-agents@latest setup
## スター履歴
🎉 **GitHub スター 170,000 件、ありがとうございます!**
🎉 **GitHub スター 110,000 件、ありがとうございます!**
REA の利用、バグ報告、機能の要望、ビルドのテスト、修正への貢献に感謝します。
@@ -278,13 +292,7 @@ REA の利用、バグ報告、機能の要望、ビルドのテスト、修正
## 免責事項
責任ある利用については [DISCLAIMER.md](DISCLAIMER.md) を参照してください。
REA は、法令に従った研究、教育、相互運用性の確保、ソフトウェアの保存、および所有するソフトウェアや調査を許可されたソフトウェアの解析を目的としています。
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
[責任ある利用](#責任ある利用)を参照してください。
## 貢献する
@@ -295,15 +303,3 @@ REA への貢献を歓迎します![issue を作成](https://github.com/morlut
## ライセンス
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### 하나의 MCP로 바이너리, 애플리케이션, 런타임 동작을 리버스 엔지니어링합니다.
**마음에 드는 기능을 발견했다면, 바이너리 수준까지 작동 원리를 이해하세요.**
**소프트웨어의 작동 원리를 바이너리 수준까지 이해하세요 — 보안 연구, 상호 운용성, 그리고 분석 권한이 있는 소프트웨어를 위해.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
앱에서 내 제품에도 넣고 싶은 기능을 발견했나요? 에이전트에게 REA로 조사해 달라고 요청하세요. 소스 코드가 없어도 앱을 검사하고, 기능의 작동 원리를 설명하고, 근거를 보여 주고, 프로젝트에 맞는 기능을 구현할 수 있습니다.
REA는 보안 연구자, 악성코드 분석가, CTF 참가자, 개발자가 에이전트를 통해 컴파일된 소프트웨어를 이해하도록 돕습니다. 분석 권한이 있는 바이너리, 애플리케이션 또는 캡처를 에이전트에게 지정하세요. REA는 소스 코드 없이 이를 검사하고, 동작을 설명하고, 각 결론의 근거를 보여 줍니다.
REA는 에이전트를 분석 도구에 연결해 네이티브 바이너리, JavaScript와 Electron 앱, .NET 어셈블리, 웹사이트를 검사할 수 있게 합니다. 터미널에서도 같은 도구를 사용할 수 있습니다. 분석은 로컬에서 실행되며, 결과에는 각 결론의 근거와 한계가 포함됩니다.
@@ -55,6 +55,23 @@ REA는 에이전트를 분석 도구에 연결해 네이티브 바이너리, Jav
> **[REA 웹사이트](https://rea.tools/ko/)**에서 설정 방법, 그림으로 설명한 가이드, 실제 사례를 확인하세요.
## 책임 있는 사용
REA는 합법적인 분석을 위해 만들어졌습니다. 보안 연구, 악성코드 및 침해 사고 분석, 취약점 연구와 조율된 공개, CTF와 교육, 상호 운용성, 소프트웨어 보존, 그리고 직접 소유하거나 조사 권한이 있는 소프트웨어의 디버깅 및 감사가 여기에 해당합니다.
REA 프로젝트는 다음 용도를 지원하지 않으며, 이에 대한 도움도 제공하지 않습니다.
- DRM, 라이선스 검사, 안티치트 시스템 또는 기타 기술적 보호 조치 우회
- 게임 치트 개발 또는 온라인 서비스 변조
- 테스트 권한이 없는 시스템의 인증, 봇 방지 또는 접근 제어 우회
- 독점 소프트웨어 복제 또는 보호된 코드와 에셋 재현
- AI 모델 제공업체의 사용 정책이나 안전 조치 회피
- AI 계정 또는 API 접근 권한 재판매나 공유
필요한 권한을 얻고 관련 법률, 라이선스 계약, 서비스 약관을 준수할 책임은 사용자에게 있습니다. 리버스 엔지니어링은 사용자의 관할권이나 분석하는 소프트웨어의 라이선스에 따라 제한될 수 있습니다.
위 용도에 대한 도움 요청은 issue와 토론에서 답변 없이 종료되며, REA 커뮤니티에서 제외될 수 있습니다.
## 빠른 시작
### 에이전트 설정
@@ -72,10 +89,11 @@ npx rea-agents setup
### 에이전트에게 요청
```text
Notes 앱의 검색 기능이 어떻게 작동하는지 조사하고, 근거를 보여 준 다음, 내 프로젝트에 비슷한 기능을 구현해 줘.
내 앱의 릴리스 빌드는 시작할 때 크래시가 나지만 디버그 빌드는 그렇지 않아.
./build/MyApp을 검사해서 두 빌드가 어디서 갈라지는지 찾고 근거를 보여 줘.
```
Notes를 대상 앱으로 바꾸고 이해하고 싶은 기능을 지정하세요.
분석 권한이 있는 대상을 에이전트에게 지정하고 이해하고 싶은 내용을 설명하세요.
### 터미널 사용
@@ -139,16 +157,12 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
| JavaScript / Electron | 모듈, 임포트, 소스 맵, 라우트, IPC, 네이티브 애드온 관계 | Node.js와 npm; [애플리케이션 분석](https://rea.tools/ko/guides/javascript/) |
| 웹사이트 | 페이지 구조, 스크립트, 네트워크 관찰 결과, 요청한 스크린샷 | Chrome 계열 브라우저; [브라우저 분석](https://rea.tools/ko/guides/browser/) |
| 저장된 네트워크 캡처 | 요청, 응답, 접근 가능한 페이로드, 소스 위치 | HAR; mitmproxy 네이티브 캡처에는 Linux의 mitmdump; [캡처 가이드](docs/web-network-captures.md) |
| 패킷 캡처 | 엔드포인트, DNS, TLS SNI, 프로토콜 분포, HTTP 요청 | 호출자 제공 tshark 및 capinfos; [pcap 가이드](docs/pcap-analysis.md) |
| .NET 어셈블리 | 메타데이터, CIL 명령, 선언된 네이티브 의존성, 빌드 비교 | 정적 검사; [관리 코드 가이드](docs/managed-code-analysis.md) |
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS/Windows x64의 헤드리스 JADX와 전체 JDK; [Android 가이드](docs/android-analysis.md) |
| Android 기기 | 기기, 패키지, 프로세스, 로그, 덤프, 화면 캡처, APK/파일 전송 | 호출자 제공 adb(에뮬레이터 또는 실제 기기); [ADB 가이드](docs/adb-device-analysis.md) |
| JEB 프로젝트 | 엔진 기반 프로젝트 유닛, 아티팩트 해시, 타입/메서드 의사코드 | 호출자가 시작하고 MCP를 제공하는 JEB 클라이언트(REA_JEB_MCP_URL로 선택); [JEB 가이드](docs/jeb-analysis.md) |
| Android 리소스 | 디코딩된 매니페스트, 문자열 테이블, 로캘, 버전 정보 | 호출자 제공 Apktool 런처; [리소스 가이드](docs/apktool-resource-analysis.md) |
| Flutter 앱 | Dart 스냅샷 해시, ABI별 라이브러리 해시, 엔진 빌드 출처 | 없음 (정적 APK 파싱); [Flutter 가이드](docs/flutter-analysis.md) |
| 펌웨어 | 영역, 추출 결과, 네이티브 분석으로 전달할 정보 | Linux의 Binwalk / Unblob; [펌웨어 가이드](docs/firmware-analysis.md) |
| 기록된 패킷 | 선택 필드, 반복 값, 필터 및 디코딩 규칙 | Linux: TShark 4.x + prlimit; [캡처 가이드](docs/packet-captures.md) |
| 기록된 논리 신호 | 디코더 주석, 샘플 범위, 진단 정보 | Linux: sigrok-cli 0.7.2 + prlimit; [신호 기록 가이드](docs/signal-recordings.md) |
| 패키지 및 리소스 | 파일 목록, 다이제스트, plist, Apple 번들 구조, 추출한 리소스 | [아티팩트 및 JavaScript 가이드](docs/javascript-artifact-reconstruction.md), [Apple 애플리케이션](docs/apple-application-analysis.md) |
| 프로세스 동작 | 터미널 출력, 상호작용, 종료 및 파일 시스템 관찰 결과, 실행 비교 | 네이티브 PTY를 지원하는 Linux/macOS; [프로세스 캡처](docs/process-capture.md) |
@@ -264,7 +278,7 @@ npx rea-agents@latest setup
## 스타 기록
🎉 **GitHub 스타 170,000개, 감사합니다!**
🎉 **GitHub 스타 110,000개, 감사합니다!**
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
@@ -278,13 +292,7 @@ REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를
## 면책 조항
책임 있는 사용에 관한 안내는 [DISCLAIMER.md](DISCLAIMER.md)를 참고하세요.
REA는 법을 준수하는 연구, 교육, 상호운용성 확보, 소프트웨어 보존, 그리고 본인이 소유하거나 조사 권한을 가진 소프트웨어의 분석을 위한 도구입니다.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
[책임 있는 사용](#책임-있는-사용)을 참고하세요.
## 기여
@@ -295,15 +303,3 @@ REA에 도움을 보태 주세요! [issue를 등록](https://github.com/morluto/
## 라이선스
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### Jeden serwer MCP do inżynierii wstecznej plików binarnych, aplikacji i zachowania w czasie wykonywania.
**Widzisz funkcję, która Ci się podoba? Dowiedz się, jak działa, aż do poziomu kodu binarnego.**
**Zrozum, jak działa oprogramowanie, aż do poziomu kodu binarnego — na potrzeby badań nad bezpieczeństwem, interoperacyjności i oprogramowania, do którego analizy masz uprawnienia.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Widzisz w aplikacji funkcję, którą chcesz mieć we własnym produkcie? Poproś swojego agenta, aby zbadał ją za pomocą REA. Może przeanalizować aplikację bez jej kodu źródłowego, wyjaśnić działanie funkcji, pokazać dowody i stworzyć jej wersję dla Twojego projektu.
REA pomaga badaczom bezpieczeństwa, analitykom złośliwego oprogramowania, uczestnikom CTF i programistom zrozumieć skompilowane oprogramowanie za pośrednictwem ich agentów. Wskaż agentowi plik binarny, aplikację lub przechwycenie ruchu, do których analizy masz uprawnienia; REA zbada wskazany cel bez kodu źródłowego, wyjaśni jego działanie i pokaże dowody stojące za każdym wnioskiem.
REA łączy Twojego agenta z narzędziami do analizy natywnych plików binarnych, aplikacji JavaScript i Electron, zestawów .NET oraz stron internetowych. Z tych samych narzędzi możesz korzystać w terminalu. Analiza odbywa się lokalnie, a wyniki zawierają dowody i ograniczenia stojące za każdym wnioskiem.
@@ -55,6 +55,23 @@ Konfigurator rejestruje REA w Twoim agencie i instaluje pasujące instrukcje pra
> **[Odwiedź stronę REA](https://rea.tools/pl/)**, aby znaleźć instrukcje konfiguracji, ilustrowane przewodniki i rzeczywiste studia przypadków.
## Odpowiedzialne korzystanie
REA powstało z myślą o analizie zgodnej z prawem: badaniach nad bezpieczeństwem, analizie złośliwego oprogramowania i incydentów, badaniu podatności i skoordynowanym ujawnianiu, CTF i edukacji, interoperacyjności, zachowywaniu oprogramowania oraz debugowaniu lub audytowaniu oprogramowania, które należy do Ciebie lub do którego badania masz uprawnienia.
Projekt REA nie wspiera następujących działań i nie będzie w nich pomagać:
- obchodzenia DRM, kontroli licencji, systemów anti-cheat ani innych technicznych środków ochrony;
- tworzenia cheatów do gier ani ingerowania w usługi online;
- obchodzenia uwierzytelniania, ochrony przed botami lub kontroli dostępu w systemach, do których testowania nie masz uprawnień;
- kopiowania oprogramowania własnościowego ani odtwarzania jego chronionego kodu i zasobów;
- omijania zasad użytkowania lub zabezpieczeń dostawców modeli AI;
- odsprzedawania lub udostępniania kont AI albo dostępu do API.
Odpowiadasz za uzyskanie wymaganych zezwoleń oraz przestrzeganie obowiązującego prawa, umów licencyjnych i warunków korzystania z usług. Inżynieria wsteczna może być ograniczona w Twojej jurysdykcji lub przez licencję analizowanego oprogramowania.
Prośby o pomoc w powyższych działaniach będą zamykane bez odpowiedzi w zgłoszeniach i dyskusjach i mogą skutkować usunięciem ze społeczności REA.
## Szybki start
### Skonfiguruj agenta
@@ -72,10 +89,11 @@ Konfigurator obsługuje Claude Code, Codex, Cursor, Gemini CLI, Grok Build i [in
### Zapytaj agenta
```text
Sprawdź, jak działa wyszukiwanie w aplikacji Notes, pokaż mi dowody i stwórz podobną funkcję dla mojego projektu.
Wersja release mojej aplikacji ulega awarii przy uruchomieniu, a wersja debug nie.
Zbadaj ./build/MyApp, znajdź miejsce, w którym obie kompilacje się rozchodzą, i pokaż mi dowody.
```
Zastąp Notes wybraną aplikacją i wskaż funkcję, którą chcesz zrozumieć.
Wskaż agentowi cel, do którego analizy masz uprawnienia, i opisz, co chcesz zrozumieć.
### Korzystaj z terminala
@@ -139,16 +157,12 @@ REA wymaga Node.js 22.x (>=22.19), 24.x (>=24.11) lub 26+ oraz npm. Dodatkowe na
| JavaScript / Electron | Moduły, importy, mapy źródeł, trasy, IPC i powiązania z natywnymi dodatkami | Node.js i npm; [analiza aplikacji](https://rea.tools/pl/guides/javascript/) |
| Strony internetowe | Struktura strony, skrypty, obserwacje sieciowe i zamówione zrzuty ekranu | Przeglądarka z rodziny Chrome; [analiza w przeglądarce](https://rea.tools/pl/guides/browser/) |
| Zapisane przechwycenia ruchu sieciowego | Żądania, odpowiedzi, dostępne dane przesyłane i lokalizacje źródłowe | HAR; mitmdump w systemie Linux dla natywnych przechwyceń mitmproxy; [przewodnik przechwytywania](docs/web-network-captures.md) |
| Przechwytywanie pakietów | Punkty końcowe, DNS, TLS SNI, dystrybucja protokołów i żądania HTTP | Dostarczone przez wywołującego tshark i capinfos; [przewodnik pcap](docs/pcap-analysis.md) |
| Zestawy .NET | Metadane, instrukcje CIL, zadeklarowane zależności natywne i porównania kompilacji | Analiza statyczna; [przewodnik kodu zarządzanego](docs/managed-code-analysis.md) |
| Pakiety APK dla Androida | Deklaracje manifestu, klasy, zdekompilowane metody i odwołania | JADX bez interfejsu graficznego i pełny JDK w systemach Linux/macOS/Windows x64; [przewodnik Androida](docs/android-analysis.md) |
| Urządzenia z Androidem | Urządzenia, pakiety, procesy, logi, zrzuty, zrzuty ekranu oraz transfery APK/plików | adb dostarczony przez wywołującego (emulator lub urządzenie); [przewodnik ADB](docs/adb-device-analysis.md) |
| Projekty JEB | Jednostki projektu obsługiwane przez silnik, skróty artefaktów i pseudokod typów/metod | Uruchomiony przez wywołującego klient JEB udostępniający MCP, wybrany przez REA_JEB_MCP_URL; [przewodnik JEB](docs/jeb-analysis.md) |
| Zasoby Androida | Zdekodowany manifest, tablice ciągów, języki i informacje o wersji | Należący do wywołującego launcher Apktool; [przewodnik zasobów](docs/apktool-resource-analysis.md) |
| Aplikacje Flutter | Hash migawki Dart, sumy bibliotek per ABI i pochodzenie kompilacji silnika | Brak (statyczna analiza APK); [przewodnik Flutter](docs/flutter-analysis.md) |
| Oprogramowanie układowe | Regiony, wyniki wyodrębniania i przekazanie do analizy kodu natywnego | Binwalk / Unblob w systemie Linux; [przewodnik oprogramowania układowego](docs/firmware-analysis.md) |
| Zapisane pakiety | Wybrane pola, powtarzane wartości, filtry i reguły dekodowania | Linux: TShark 4.x + prlimit; [przewodnik po przechwyconych pakietach](docs/packet-captures.md) |
| Zapisane sygnały logiczne | Adnotacje dekodera, zakresy próbek i diagnostyka | Linux: sigrok-cli 0.7.2 + prlimit; [przewodnik po sygnałach](docs/signal-recordings.md) |
| Pakiety i zasoby | Spisy plików, skróty, pliki plist, struktura pakietów Apple i wyodrębnione zasoby | [Przewodnik artefaktów i JavaScript](docs/javascript-artifact-reconstruction.md), [aplikacje Apple](docs/apple-application-analysis.md) |
| Zachowanie procesów | Wyjście terminala, interakcje, obserwacje zakończenia i systemu plików oraz porównania uruchomień | Linux/macOS z natywnym PTY; [przechwytywanie procesów](docs/process-capture.md) |
@@ -262,7 +276,7 @@ Zgłaszaj podatności zgodnie z [SECURITY.md](SECURITY.md).
## Historia gwiazdek
🎉 **170 000 gwiazdek na GitHubie — dziękujemy!**
🎉 **110 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.
@@ -276,13 +290,7 @@ Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują no
## Zastrzeżenie
Wskazówki dotyczące odpowiedzialnego korzystania znajdziesz w [DISCLAIMER.md](DISCLAIMER.md).
REA służy zgodnym z prawem badaniom, edukacji, zapewnianiu interoperacyjności, zachowaniu oprogramowania oraz analizie oprogramowania, które posiadasz lub masz prawo badać.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
Zobacz [Odpowiedzialne korzystanie](#odpowiedzialne-korzystanie).
## Współtworzenie
@@ -293,15 +301,3 @@ Zobacz [CONTRIBUTING.md](CONTRIBUTING.md), aby poznać konfigurację środowiska
## Licencja
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### Um único MCP para engenharia reversa de binários, aplicativos e comportamento em execução.
**Viu uma funcionalidade de que gostou? Entenda como ela funciona, até o nível binário.**
**Entenda como o software funciona, até o nível binário — para pesquisa de segurança, interoperabilidade e softwares que você tem autorização para analisar.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Viu uma funcionalidade em um aplicativo que gostaria de ter no seu próprio produto? Peça ao seu agente para investigá-la com o REA. Ele pode inspecionar o aplicativo sem o código-fonte, explicar como a funcionalidade funciona, apresentar as evidências e criar uma versão para o seu projeto.
O REA ajuda pesquisadores de segurança, analistas de malware, jogadores de CTF e desenvolvedores a entender softwares compilados por meio de seus agentes. Aponte seu agente para um binário, aplicativo ou captura que você tenha autorização para analisar; o REA o inspeciona sem o código-fonte, explica seu comportamento e mostra as evidências por trás de cada conclusão.
O REA conecta seu agente a ferramentas para inspecionar binários nativos, aplicativos JavaScript e Electron, assemblies .NET e sites. Você também pode usar as mesmas ferramentas pelo terminal. A análise acontece localmente, e os resultados incluem as evidências e limitações por trás de cada conclusão.
@@ -55,6 +55,23 @@ A configuração registra o REA no seu agente e instala as instruções de fluxo
> **[Visite o site do REA](https://rea.tools/pt-BR/)** para instruções de configuração, guias ilustrados e estudos de caso reais.
## Uso responsável
O REA foi criado para análises lícitas: pesquisa de segurança, análise de malware e de incidentes, pesquisa de vulnerabilidades e divulgação coordenada, CTFs e educação, interoperabilidade, preservação de software e depuração ou auditoria de software que você possui ou tem autorização para examinar.
O projeto REA não apoia e não ajudará com:
- contornar DRM, verificações de licença, sistemas anti-cheat ou outras medidas técnicas de proteção;
- desenvolver cheats para jogos ou adulterar serviços online;
- burlar autenticação, proteção contra bots ou controles de acesso em sistemas que você não tem autorização para testar;
- copiar software proprietário ou reproduzir seu código e seus recursos protegidos;
- driblar as políticas de uso ou as medidas de segurança de provedores de modelos de IA;
- revender ou compartilhar contas de IA ou acesso a APIs.
Você é responsável por obter as autorizações necessárias e cumprir as leis, os contratos de licença e os termos de serviço aplicáveis. A engenharia reversa pode ser restrita na sua jurisdição ou pela licença do software que você analisa.
Pedidos de ajuda para os usos acima serão fechados sem resposta em issues e discussões e podem resultar na remoção da comunidade do REA.
## Início rápido
### Configure seu agente
@@ -72,10 +89,11 @@ A configuração oferece suporte ao Claude Code, Codex, Cursor, Gemini CLI, Grok
### Peça ao seu agente
```text
Investigue como a busca funciona no aplicativo Notes, mostre as evidências e crie uma funcionalidade semelhante para o meu projeto.
O build de release do meu aplicativo trava na inicialização, mas o build de debug não.
Inspecione ./build/MyApp, descubra onde os dois builds divergem e mostre as evidências.
```
Substitua Notes pelo aplicativo alvo e indique a funcionalidade que deseja entender.
Aponte seu agente para um alvo que você tenha autorização para analisar e descreva o que deseja entender.
### Use o terminal
@@ -139,16 +157,12 @@ O REA requer Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, além do npm. As fer
| JavaScript / Electron | Módulos, importações, source maps, rotas, IPC e relações com complementos nativos | Node.js e npm; [análise de aplicativos](https://rea.tools/pt-BR/guides/javascript/) |
| Sites | Estrutura da página, scripts, observações de rede e capturas de tela solicitadas | Um navegador da família Chrome; [análise do navegador](https://rea.tools/pt-BR/guides/browser/) |
| Capturas de rede salvas | Requisições, respostas, payloads acessíveis e localizações de origem | HAR; mitmdump no Linux para capturas no formato nativo do mitmproxy; [guia de capturas](docs/web-network-captures.md) |
| Capturas de pacotes | Endpoints, DNS, TLS SNI, distribuição de protocolos e requisições HTTP | tshark e capinfos fornecidos pelo chamador; [guia pcap](docs/pcap-analysis.md) |
| Assemblies .NET | Metadados, instruções CIL, dependências nativas declaradas e comparações de builds | Inspeção estática; [guia de código gerenciado](docs/managed-code-analysis.md) |
| APKs Android | Declarações do manifesto, classes, métodos descompilados e referências | JADX sem interface gráfica e um JDK completo no Linux/macOS/Windows x64; [guia de Android](docs/android-analysis.md) |
| Dispositivos Android | Dispositivos, pacotes, processos, logs, despejos, capturas de tela e transferências de APK/arquivos | adb fornecido pelo chamador (emulador ou aparelho); [guia de ADB](docs/adb-device-analysis.md) |
| Projetos JEB | Unidades de projeto do motor, hashes de artefatos e pseudocódigo de tipos/métodos | Um cliente JEB iniciado pelo chamador servindo MCP, selecionado com REA_JEB_MCP_URL; [guia de JEB](docs/jeb-analysis.md) |
| Recursos do Android | Manifesto decodificado, tabelas de strings, idiomas e fatos de versão | Lançador do Apktool fornecido pelo chamador; [guia de recursos](docs/apktool-resource-analysis.md) |
| Aplicativos Flutter | Hash de snapshot Dart, hashes de bibliotecas por ABI e procedência de build do motor | Nenhuma (análise estática de APK); [guia Flutter](docs/flutter-analysis.md) |
| Firmware | Regiões, resultados de extração e encaminhamentos à análise nativa | Binwalk / Unblob no Linux; [guia de firmware](docs/firmware-analysis.md) |
| Pacotes gravados | Campos selecionados, valores repetidos, filtros e regras de decodificação | Linux: TShark 4.x + prlimit; [guia de capturas](docs/packet-captures.md) |
| Sinais lógicos gravados | Anotações do decodificador, intervalos de amostras e diagnósticos | Linux: sigrok-cli 0.7.2 + prlimit; [guia de sinais](docs/signal-recordings.md) |
| Pacotes e recursos | Inventários de arquivos, digests, plists, estrutura de bundles Apple e recursos extraídos | [Guia de artefatos e JavaScript](docs/javascript-artifact-reconstruction.md), [aplicativos Apple](docs/apple-application-analysis.md) |
| Comportamento de processos | Saída do terminal, interações, observações de encerramento e do sistema de arquivos, e comparações entre execuções | Linux/macOS com PTY nativo; [captura de processos](docs/process-capture.md) |
@@ -262,7 +276,7 @@ Relate vulnerabilidades conforme [SECURITY.md](SECURITY.md).
## Histórico de estrelas
🎉 **170.000 estrelas no GitHub — muito obrigado!**
🎉 **110.000 estrelas no GitHub — muito obrigado!**
Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam builds e contribuem com correções.
@@ -276,13 +290,7 @@ Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam b
## Aviso legal
Consulte [DISCLAIMER.md](DISCLAIMER.md) para orientações sobre o uso responsável.
O REA destina-se à pesquisa, à educação, à interoperabilidade, à preservação de software e à análise de software que você possui ou está autorizado a examinar, dentro da lei.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
Veja [Uso responsável](#uso-responsável).
## Contribuir
@@ -293,15 +301,3 @@ Consulte [CONTRIBUTING.md](CONTRIBUTING.md) para configurar o ambiente de desenv
## Licença
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+41 -45
View File
@@ -6,7 +6,7 @@
### Один MCP для реверс-инжиниринга бинарных файлов, приложений и поведения во время выполнения.
**Нашли интересную функцию? Разберитесь, как она работает, вплоть до двоичного кода.**
**Разберитесь, как работает программное обеспечение, вплоть до двоичного кода — для исследований безопасности, обеспечения совместимости и работы с ПО, которое вам разрешено анализировать.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Увидели в приложении функцию, которую хотите добавить в свой продукт? Попросите агента исследовать её с помощью REA. Он может изучить приложение без исходного кода, объяснить работу функции, показать подтверждающие данные и создать подходящую реализацию для вашего проекта.
REA помогает исследователям безопасности, аналитикам вредоносного ПО, участникам CTF и разработчикам разбираться в скомпилированных программах с помощью их агентов. Укажите агенту бинарный файл, приложение или захват, которые вам разрешено анализировать; REA изучит их без исходного кода, объяснит их поведение и покажет данные, подтверждающие каждый вывод.
REA подключает вашего агента к инструментам для исследования нативных бинарных файлов, приложений JavaScript и Electron, сборок .NET и сайтов. Те же инструменты доступны в терминале. Анализ выполняется локально, а результаты содержат данные и ограничения, на которых основан каждый вывод.
@@ -55,6 +55,23 @@ REA подключает вашего агента к инструментам
> **[Посетите сайт REA](https://rea.tools/ru/)**: там есть инструкции по настройке, иллюстрированные руководства и реальные исследования.
## Ответственное использование
REA создан для законного анализа: исследований безопасности, анализа вредоносного ПО и инцидентов, исследования уязвимостей и скоординированного раскрытия, CTF и обучения, обеспечения совместимости, сохранения программного обеспечения, а также отладки или аудита ПО, которым вы владеете или которое вам разрешено изучать.
Проект REA не поддерживает следующее и не будет с этим помогать:
- обход DRM, проверок лицензий, античит-систем и других технических средств защиты;
- разработка читов для игр или вмешательство в работу онлайн-сервисов;
- обход аутентификации, защиты от ботов или контроля доступа в системах, которые вам не разрешено тестировать;
- копирование проприетарного ПО или воспроизведение его защищённого кода и ресурсов;
- уклонение от правил использования или мер безопасности поставщиков ИИ-моделей;
- перепродажа или передача аккаунтов ИИ-сервисов или доступа к API.
Вы отвечаете за получение необходимых разрешений и соблюдение применимых законов, лицензионных соглашений и условий обслуживания. Реверс-инжиниринг может быть ограничен в вашей юрисдикции или лицензией анализируемого ПО.
Запросы о помощи в перечисленных выше целях будут закрываться без ответа в issues и обсуждениях и могут привести к исключению из сообщества REA.
## Быстрый старт
### Настройте агента
@@ -72,10 +89,11 @@ npx rea-agents setup
### Задайте вопрос агенту
```text
Исследуй, как работает поиск в приложении Notes, покажи подтверждающие данные и создай похожую функцию для моего проекта.
Release-сборка моего приложения падает при запуске, а debug-сборка — нет.
Изучи ./build/MyApp, найди, где расходятся две сборки, и покажи подтверждающие данные.
```
Замените Notes нужным приложением и укажите функцию, которую хотите понять.
Укажите агенту цель, которую вам разрешено анализировать, и опишите, что вы хотите понять.
### Используйте терминал
@@ -130,27 +148,23 @@ npx rea-agents@latest setup
REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а также npm. Дополнительные инструменты и поддерживаемые системы зависят от цели:
| Цель | Что возвращает REA | Требования и руководство |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](https://rea.tools/ru/guides/native/) |
| Структура ELF без запуска | Секции, сегменты, исходные символы/релокации и возможные механизмы защиты по данным статического анализа | pwntools, предоставленный вызывающей стороной, в Linux x64; [диагностика бинарных файлов](docs/binary-diagnostics.md) |
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](docs/evm-bytecode.md) |
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](docs/recorded-crashes.md) |
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](https://rea.tools/ru/guides/javascript/) |
| Сайты | Структура страницы, скрипты, наблюдения за сетью и запрошенные снимки экрана | Браузер семейства Chrome; [анализ браузера](https://rea.tools/ru/guides/browser/) |
| Сохранённые сетевые захваты | Запросы, ответы, доступные полезные данные и позиции в источнике | HAR; mitmdump в Linux для захватов в собственном формате mitmproxy; [руководство по сетевым захватам](docs/web-network-captures.md) |
| Сборки .NET | Метаданные, инструкции CIL, объявленные нативные зависимости и сравнения сборок | Статическое исследование; [руководство по управляемому коду](docs/managed-code-analysis.md) |
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS/Windows x64; [руководство по Android](docs/android-analysis.md) |
| Устройства Android | Устройства, пакеты, процессы, журналы, дампы, снимки экрана и передача APK/файлов | adb, предоставленный вызывающей стороной (эмулятор или устройство); [руководство по ADB](docs/adb-device-analysis.md) |
| Проекты JEB | Единицы проекта от движка, дайджесты артефактов и псевдокод типов/методов | Запущенный вызывающей стороной клиент JEB с интерфейсом MCP, выбирается через REA_JEB_MCP_URL; [руководство по JEB](docs/jeb-analysis.md) |
| Ресурсы Android | Декодированный манифест, таблицы строк, языки и сведения о версии | Запуск Apktool, предоставленный вызывающей стороной; [руководство по ресурсам](docs/apktool-resource-analysis.md) |
| Приложения Flutter | Хеш снапшота Dart, дайджесты библиотек по ABI и происхождение сборки движка | Не требуется (статический разбор APK); [руководство по Flutter](docs/flutter-analysis.md) |
| Прошивки | Области, результаты извлечения и передача в нативный анализ | Binwalk / Unblob в Linux; [руководство по прошивкам](docs/firmware-analysis.md) |
| Записанные пакеты | Выбранные поля, повторяющиеся значения, фильтры и правила декодирования | Linux: TShark 4.x + prlimit; [руководство по захватам](docs/packet-captures.md) |
| Захват пакетов | Конечные точки, DNS, TLS SNI, распределение протоколов и HTTP-запросы | Предоставленные вызывающей стороной tshark и capinfos; [руководство по pcap](docs/pcap-analysis.md) |
| Записанные логические сигналы | Аннотации декодера, диапазоны отсчётов и диагностика | Linux: sigrok-cli 0.7.2 + prlimit; [руководство по сигналам](docs/signal-recordings.md) |
| Пакеты и ресурсы | Списки файлов, хеши, plist, структура пакетов Apple и извлечённые ресурсы | [Руководство по артефактам и JavaScript](docs/javascript-artifact-reconstruction.md), [приложения Apple](docs/apple-application-analysis.md) |
| Поведение процессов | Вывод терминала, взаимодействия, наблюдения за завершением и файловой системой, сравнения запусков | Linux/macOS с нативным PTY; [захват процессов](docs/process-capture.md) |
| Цель | Что возвращает REA | Требования и руководство |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](https://rea.tools/ru/guides/native/) |
| Структура ELF без запуска | Секции, сегменты, исходные символы/релокации и возможные механизмы защиты по данным статического анализа | pwntools, предоставленный вызывающей стороной, в Linux x64; [диагностика бинарных файлов](docs/binary-diagnostics.md) |
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](docs/evm-bytecode.md) |
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](docs/recorded-crashes.md) |
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](https://rea.tools/ru/guides/javascript/) |
| Сайты | Структура страницы, скрипты, наблюдения за сетью и запрошенные снимки экрана | Браузер семейства Chrome; [анализ браузера](https://rea.tools/ru/guides/browser/) |
| Сохранённые сетевые захваты | Запросы, ответы, доступные полезные данные и позиции в источнике | HAR; mitmdump в Linux для захватов в собственном формате mitmproxy; [руководство по сетевым захватам](docs/web-network-captures.md) |
| Сборки .NET | Метаданные, инструкции CIL, объявленные нативные зависимости и сравнения сборок | Статическое исследование; [руководство по управляемому коду](docs/managed-code-analysis.md) |
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS/Windows x64; [руководство по Android](docs/android-analysis.md) |
| Устройства Android | Устройства, пакеты, процессы, журналы, дампы, снимки экрана и передача APK/файлов | adb, предоставленный вызывающей стороной (эмулятор или устройство); [руководство по ADB](docs/adb-device-analysis.md) |
| Проекты JEB | Единицы проекта от движка, дайджесты артефактов и псевдокод типов/методов | Запущенный вызывающей стороной клиент JEB с интерфейсом MCP, выбирается через REA_JEB_MCP_URL; [руководство по JEB](docs/jeb-analysis.md) |
| Ресурсы Android | Декодированный манифест, таблицы строк, языки и сведения о версии | Запуск Apktool, предоставленный вызывающей стороной; [руководство по ресурсам](docs/apktool-resource-analysis.md) |
| Прошивки | Области, результаты извлечения и передача в нативный анализ | Binwalk / Unblob в Linux; [руководство по прошивкам](docs/firmware-analysis.md) |
| Пакеты и ресурсы | Списки файлов, хеши, plist, структура пакетов Apple и извлечённые ресурсы | [Руководство по артефактам и JavaScript](docs/javascript-artifact-reconstruction.md), [приложения Apple](docs/apple-application-analysis.md) |
| Поведение процессов | Вывод терминала, взаимодействия, наблюдения за завершением и файловой системой, сравнения запусков | Linux/macOS с нативным PTY; [захват процессов](docs/process-capture.md) |
Статическое исследование JavaScript и .NET читает предоставленные файлы, не запуская приложение. Захват во время выполнения запускает выбранную цель или взаимодействует с ней с правами вашего пользователя; соответствующие руководства описывают последствия.
@@ -262,7 +276,7 @@ npx rea-agents@latest setup
## История звёзд
🎉 **170 000 звёзд на GitHub — спасибо!**
🎉 **110 000 звёзд на GitHub — спасибо!**
Спасибо всем, кто использует REA, сообщает об ошибках, предлагает новые функции, тестирует сборки и помогает с исправлениями.
@@ -276,13 +290,7 @@ npx rea-agents@latest setup
## Отказ от ответственности
Рекомендации по ответственному использованию приведены в [DISCLAIMER.md](DISCLAIMER.md).
REA предназначен для законных исследований, обучения, обеспечения совместимости, сохранения программного обеспечения и анализа программ, которыми вы владеете или которые вам разрешено изучать.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
См. [Ответственное использование](#ответственное-использование).
## Участие в проекте
@@ -293,15 +301,3 @@ applicable licenses.
## Лицензия
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### MCP เดียวสำหรับวิศวกรรมย้อนกลับ ทั้งไบนารี แอปพลิเคชัน และพฤติกรรมขณะทำงาน
**เห็นฟีเจอร์ที่ชอบแล้วอยากรู้ว่าทำงานอย่างไร? เข้าใจได้ลึกถึงระดับไบนารี**
**เข้าใจว่าซอฟต์แวร์ทำงานอย่างไรได้ลึกถึงระดับไบนารี — สำหรับงานวิจัยด้านความปลอดภัย การทำงานร่วมกันได้ และซอฟต์แวร์ที่คุณได้รับอนุญาตให้วิเคราะห์**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
เห็นฟีเจอร์ในแอปที่อยากนำมาใช้ในผลิตภัณฑ์ของคุณเองหรือไม่? ขอให้เอเจนต์ของคุณตรวจสอบด้วย REA เอเจนต์สามารถวิเคราะห์แอปโดยไม่ต้องมีซอร์สโค้ด อธิบายการทำงานของฟีเจอร์ แสดงหลักฐาน และสร้างเวอร์ชันสำหรับโปรเจกต์ของคุณได้
REA ช่วยให้นักวิจัยด้านความปลอดภัย นักวิเคราะห์มัลแวร์ ผู้เล่น CTF และนักพัฒนาเข้าใจซอฟต์แวร์ที่คอมไพล์แล้วผ่านเอเจนต์ของตน ชี้เอเจนต์ของคุณไปยังไบนารี แอปพลิเคชัน หรือข้อมูลที่บันทึกไว้ซึ่งคุณได้รับอนุญาตให้วิเคราะห์ แล้ว REA จะตรวจสอบโดยไม่ต้องมีซอร์สโค้ด อธิบายพฤติกรรม และแสดงหลักฐานเบื้องหลังข้อสรุปแต่ละข้อ
REA เชื่อมเอเจนต์ของคุณกับเครื่องมือสำหรับตรวจสอบไบนารีเนทีฟ แอป JavaScript และ Electron แอสเซมบลี .NET และเว็บไซต์ คุณใช้เครื่องมือเดียวกันจากเทอร์มินัลได้ การวิเคราะห์ทำงานบนเครื่องของคุณ และผลลัพธ์มีทั้งหลักฐานและข้อจำกัดที่ประกอบแต่ละข้อสรุป
@@ -55,6 +55,23 @@ REA เชื่อมเอเจนต์ของคุณกับเคร
> **[เยี่ยมชมเว็บไซต์ REA](https://rea.tools/th/)** เพื่อดูคำแนะนำการตั้งค่า คู่มือพร้อมภาพประกอบ และกรณีศึกษาจริง
## การใช้งานอย่างรับผิดชอบ
REA สร้างขึ้นเพื่อการวิเคราะห์ที่ถูกกฎหมาย ได้แก่ การวิจัยด้านความปลอดภัย การวิเคราะห์มัลแวร์และเหตุการณ์ด้านความปลอดภัย การวิจัยช่องโหว่และการเปิดเผยข้อมูลแบบประสานงาน CTF และการศึกษา การทำงานร่วมกันได้ การอนุรักษ์ซอฟต์แวร์ ตลอดจนการดีบักหรือตรวจสอบซอฟต์แวร์ที่คุณเป็นเจ้าของหรือได้รับอนุญาตให้ตรวจสอบ
โปรเจกต์ REA ไม่สนับสนุนและจะไม่ช่วยเหลือในเรื่องต่อไปนี้
- การหลบเลี่ยง DRM การตรวจสอบไลเซนส์ ระบบป้องกันการโกง หรือมาตรการป้องกันทางเทคนิคอื่น ๆ
- การพัฒนาโปรแกรมโกงเกมหรือการแทรกแซงบริการออนไลน์
- การข้ามการยืนยันตัวตน การป้องกันบอต หรือการควบคุมการเข้าถึงบนระบบที่คุณไม่ได้รับอนุญาตให้ทดสอบ
- การคัดลอกซอฟต์แวร์กรรมสิทธิ์หรือการทำซ้ำโค้ดและแอสเซ็ตที่ได้รับการคุ้มครอง
- การหลีกเลี่ยงนโยบายการใช้งานหรือมาตรการด้านความปลอดภัยของผู้ให้บริการโมเดล AI
- การขายต่อหรือแบ่งปันบัญชี AI หรือสิทธิ์การเข้าถึง API
คุณมีหน้าที่ขออนุญาตตามที่จำเป็นและปฏิบัติตามกฎหมาย ข้อตกลงไลเซนส์ และข้อกำหนดในการให้บริการที่เกี่ยวข้อง วิศวกรรมย้อนกลับอาจถูกจำกัดในเขตอำนาจศาลของคุณหรือโดยไลเซนส์ของซอฟต์แวร์ที่คุณวิเคราะห์
คำขอความช่วยเหลือสำหรับการใช้งานข้างต้นใน issue และการสนทนาจะถูกปิดโดยไม่มีการตอบกลับ และอาจส่งผลให้ถูกนำออกจากชุมชน REA
## เริ่มต้นอย่างรวดเร็ว
### ตั้งค่าเอเจนต์
@@ -72,10 +89,11 @@ npx rea-agents setup
### ถามเอเจนต์
```text
ตรวจสอบว่าการค้นหาในแอป Notes ทำงานอย่างไร แสดงหลักฐานให้ฉันดู และสร้างฟีเจอร์ที่คล้ายกันสำหรับโปรเจกต์ของฉัน
บิลด์ release ของแอปฉันแครชตอนเริ่มทำงาน แต่บิลด์ debug ไม่แครช
ตรวจสอบ ./build/MyApp หาจุดที่สองบิลด์แตกต่างกัน และแสดงหลักฐานให้ฉันดู
```
แทนที่ Notes ด้วยแอปเป้าหมายและฟีเจอร์ที่คุณต้องการเข้าใจ
ชี้เอเจนต์ของคุณไปยังเป้าหมายที่คุณได้รับอนุญาตให้วิเคราะห์ และอธิบายสิ่งที่คุณต้องการเข้าใจ
### ใช้เทอร์มินัล
@@ -139,16 +157,12 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
| JavaScript / Electron | โมดูล การนำเข้า ซอร์สแมป เส้นทาง IPC และความสัมพันธ์กับส่วนเสริมเนทีฟ | Node.js และ npm; [การวิเคราะห์แอปพลิเคชัน](https://rea.tools/th/guides/javascript/) |
| เว็บไซต์ | โครงสร้างหน้า สคริปต์ ข้อมูลเครือข่ายที่สังเกตได้ และภาพหน้าจอที่ร้องขอ | เบราว์เซอร์ในตระกูล Chrome; [การวิเคราะห์ผ่านเบราว์เซอร์](https://rea.tools/th/guides/browser/) |
| ข้อมูลเครือข่ายที่บันทึกไว้ | คำขอ คำตอบ เพย์โหลดที่ปรากฏ และตำแหน่งต้นทาง | HAR; mitmdump บน Linux สำหรับข้อมูลที่บันทึกในรูปแบบเนทีฟของ mitmproxy; [คู่มือการบันทึกข้อมูล](docs/web-network-captures.md) |
| การจับแพ็กเก็ต | จุดเชื่อมต่อ, DNS, TLS SNI, การกระจายโปรโตคอล และคำขอ HTTP | tshark และ capinfos ที่ผู้เรียกจัดเตรียม; [คู่มือ pcap](docs/pcap-analysis.md) |
| แอสเซมบลี .NET | เมทาดาทา คำสั่ง CIL การพึ่งพาเนทีฟที่ประกาศไว้ และการเปรียบเทียบผลการบิลด์ | การตรวจสอบแบบสถิต; [คู่มือโค้ดแบบจัดการ](docs/managed-code-analysis.md) |
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS/Windows x64; [คู่มือ Android](docs/android-analysis.md) |
| อุปกรณ์ Android | อุปกรณ์ แพ็กเกจ โพรเซส บันทึก ดัมพ์ ภาพหน้าจอ และการถ่ายโอน APK/ไฟล์ | adb ที่ผู้เรียกจัดเตรียม (โปรแกรมจำลองหรืออุปกรณ์จริง); [คู่มือ ADB](docs/adb-device-analysis.md) |
| โปรเจกต์ JEB | หน่วยโปรเจกต์จากเอนจิน, แฮชของอาร์ติแฟกต์ และซูโดโค้ดของไทป์/เมท็อด | ไคลเอนต์ JEB ที่ผู้เรียกเริ่มและให้บริการ MCP เลือกด้วย REA_JEB_MCP_URL; [คู่มือ JEB](docs/jeb-analysis.md) |
| ทรัพยากร Android | ไฟล์ manifest ที่ถอดรหัสแล้ว ตารางสตริง ภาษา และข้อมูลเวอร์ชัน | ตัวเรียก Apktool ที่ผู้เรียกจัดเตรียม; [คู่มือทรัพยากร](docs/apktool-resource-analysis.md) |
| แอป Flutter | แฮชสแนปชอต Dart, แฮชไลบรารีราย ABI และที่มาของบิลด์เอนจิน | ไม่ต้อง (วิเคราะห์ APK แบบ static); [คู่มือ Flutter](docs/flutter-analysis.md) |
| เฟิร์มแวร์ | พื้นที่ข้อมูล ผลการแตกไฟล์ และการส่งต่อไปวิเคราะห์เนทีฟ | Binwalk / Unblob บน Linux; [คู่มือเฟิร์มแวร์](docs/firmware-analysis.md) |
| แพ็กเก็ตที่บันทึกไว้ | ฟิลด์ที่เลือก ค่าซ้ำ ตัวกรอง และกฎการถอดรหัส | Linux: TShark 4.x + prlimit; [คู่มือไฟล์แคปเจอร์](docs/packet-captures.md) |
| สัญญาณลอจิกที่บันทึกไว้ | คำอธิบายจากตัวถอดรหัส ช่วงตัวอย่าง และข้อมูลวินิจฉัย | Linux: sigrok-cli 0.7.2 + prlimit; [คู่มือสัญญาณ](docs/signal-recordings.md) |
| แพ็กเกจและทรัพยากร | รายการไฟล์ ค่าแฮช plist โครงสร้างบันเดิลของ Apple และทรัพยากรที่แตกออกมา | [คู่มืออาร์ติแฟกต์และ JavaScript](docs/javascript-artifact-reconstruction.md), [แอปพลิเคชัน Apple](docs/apple-application-analysis.md) |
| พฤติกรรมของโปรเซส | เอาต์พุตเทอร์มินัล การโต้ตอบ ข้อมูลการสิ้นสุดและระบบไฟล์ที่สังเกตได้ และการเปรียบเทียบการรัน | Linux/macOS ที่มี PTY เนทีฟ; [การบันทึกโปรเซส](docs/process-capture.md) |
@@ -262,7 +276,7 @@ npx rea-agents@latest setup
## ประวัติดาว
🎉 **170,000 ดาวบน GitHub — ขอบคุณทุกคน!**
🎉 **110,000 ดาวบน GitHub — ขอบคุณทุกคน!**
ขอบคุณทุกคนที่ใช้ REA รายงานบั๊ก เสนอฟีเจอร์ ทดสอบบิลด์ และช่วยแก้ไข
@@ -276,13 +290,7 @@ npx rea-agents@latest setup
## ข้อสงวนสิทธิ์
ดูแนวทางการใช้งานอย่างรับผิดชอบใน [DISCLAIMER.md](DISCLAIMER.md)
REA มีไว้สำหรับการวิจัย การศึกษา การทำงานร่วมกัน การอนุรักษ์ซอฟต์แวร์ และการวิเคราะห์ซอฟต์แวร์ที่คุณเป็นเจ้าของหรือได้รับอนุญาตให้ตรวจสอบ โดยปฏิบัติตามกฎหมาย
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
ดู[การใช้งานอย่างรับผิดชอบ](#การใช้งานอย่างรับผิดชอบ)
## การมีส่วนร่วม
@@ -293,15 +301,3 @@ applicable licenses.
## สัญญาอนุญาต
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### İkili dosyaların, uygulamaların ve çalışma zamanı davranışının tersine mühendisliği için tek bir MCP.
**Beğendiğiniz bir özellik mi gördünüz? İkili kod düzeyine kadar nasıl çalıştığını anlayın.**
**Yazılımın nasıl çalıştığını ikili kod düzeyine kadar anlayın — güvenlik araştırmaları, birlikte çalışabilirlik ve analiz etme yetkiniz olan yazılımlar için.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Bir uygulamada kendi ürününüze eklemek istediğiniz bir özellik mi gördünüz? Ajanınızdan REA ile araştırmasını isteyin. Kaynak kodu olmadan uygulamayı inceleyebilir, özelliğin nasıl çalıştığını açıklayabilir, kanıtları gösterebilir ve projenize uygun bir sürümünü geliştirebilir.
REA; güvenlik araştırmacılarının, kötü amaçlı yazılım analistlerinin, CTF oyuncularının ve geliştiricilerin derlenmiş yazılımları ajanları aracılığıyla anlamasına yardımcı olur. Ajanınızı analiz etme yetkiniz olan bir ikili dosyaya, uygulamaya veya yakalamaya yönlendirin; REA onu kaynak kodu olmadan inceler, davranışını açıklar ve her sonucun dayandığı kanıtları gösterir.
REA, ajanınızı yerel makine kodu içeren ikili dosyaları, JavaScript ve Electron uygulamalarını, .NET derlemelerini ve web sitelerini inceleyen araçlara bağlar. Aynı araçları terminalden de kullanabilirsiniz. Analiz yerel olarak çalışır; sonuçlar her çıkarımın dayandığı kanıtları ve sınırlamaları içerir.
@@ -55,6 +55,23 @@ Kurulum, REA'yı ajanınıza kaydeder ve uyumlu iş akışı talimatlarını yü
> Kurulum talimatları, görselli rehberler ve gerçek örnek çalışmalar için **[REA web sitesini ziyaret edin](https://rea.tools/tr/)**.
## Sorumlu kullanım
REA yasal analiz için tasarlanmıştır: güvenlik araştırmaları, kötü amaçlı yazılım ve olay analizi, güvenlik açığı araştırması ve koordineli açıklama, CTF'ler ve eğitim, birlikte çalışabilirlik, yazılımların korunması ve sahibi olduğunuz ya da inceleme yetkiniz olan yazılımlarda hata ayıklama veya denetim.
REA projesi aşağıdakileri desteklemez ve bunlara yardım etmez:
- DRM'yi, lisans denetimlerini, hile önleme sistemlerini veya diğer teknik koruma önlemlerini atlatmak;
- oyun hileleri geliştirmek veya çevrim içi hizmetlere müdahale etmek;
- test etme yetkiniz olmayan sistemlerde kimlik doğrulamayı, bot korumasını veya erişim denetimlerini aşmak;
- tescilli yazılımları kopyalamak veya korunan kodlarını ve varlıklarını yeniden üretmek;
- yapay zekâ modeli sağlayıcılarının kullanım politikalarından veya güvenlik önlemlerinden kaçmak;
- yapay zekâ hesaplarını veya API erişimini yeniden satmak ya da paylaşmak.
Gerekli izinleri almak ve geçerli yasalara, lisans sözleşmelerine ve hizmet şartlarına uymak sizin sorumluluğunuzdadır. Tersine mühendislik, bulunduğunuz yargı bölgesinde veya analiz ettiğiniz yazılımın lisansı tarafından kısıtlanmış olabilir.
Yukarıdaki kullanımlar için yardım talepleri, issue'larda ve tartışmalarda yanıt verilmeden kapatılır ve REA topluluğundan çıkarılmaya yol açabilir.
## Hızlı başlangıç
### Ajanınızı yapılandırın
@@ -72,10 +89,11 @@ Kurulum Claude Code, Codex, Cursor, Gemini CLI, Grok Build ve [diğer ajanları]
### Ajanınıza sorun
```text
Notes uygulamasında aramanın nasıl çalıştığını araştır, kanıtları göster ve projem için benzer bir özellik geliştir.
Uygulamamın release derlemesi açılışta çöküyor ama debug derlemesi çökmüyor.
./build/MyApp dosyasını incele, iki derlemenin nerede ayrıştığını bul ve kanıtları göster.
```
Notes yerine hedef uygulamanızı ve anlamak istediğiniz özelliği belirtin.
Ajanınızı analiz etme yetkiniz olan bir hedefe yönlendirin ve neyi anlamak istediğinizi açıklayın.
### Terminali kullanın
@@ -139,16 +157,12 @@ REA; Node.js 22.x (>=22.19), 24.x (>=24.11) veya 26+ ve npm gerektirir. Ek araç
| JavaScript / Electron | Modüller, içe aktarmalar, kaynak haritaları, rotalar, IPC ve yerel eklenti ilişkileri | Node.js ve npm; [uygulama analizi](https://rea.tools/tr/guides/javascript/) |
| Web siteleri | Sayfa yapısı, betikler, ağ gözlemleri ve istenen ekran görüntüleri | Chrome ailesinden bir tarayıcı; [tarayıcı analizi](https://rea.tools/tr/guides/browser/) |
| Kaydedilmiş ağ yakalamaları | İstekler, yanıtlar, erişilebilir yük içerikleri ve kaynak konumları | HAR; mitmproxy'nin kendi biçimindeki yakalamalar için Linux üzerinde mitmdump; [ağ yakalama rehberi](docs/web-network-captures.md) |
| Paket yakalamaları | Uç noktalar, DNS, TLS SNI, protokol dağılımı ve HTTP istekleri | Çağıranın sağladığı tshark ve capinfos; [pcap rehberi](docs/pcap-analysis.md) |
| .NET derlemeleri | Meta veriler, CIL talimatları, bildirilmiş yerel bağımlılıklar ve derleme karşılaştırmaları | Statik inceleme; [yönetilen kod rehberi](docs/managed-code-analysis.md) |
| Android APK'leri | Manifest bildirimleri, sınıflar, tersine derlenmiş metotlar ve referanslar | Linux/macOS/Windows x64 üzerinde arayüzsüz JADX ve tam bir JDK; [Android rehberi](docs/android-analysis.md) |
| Android cihazları | Cihazlar, paketler, süreçler, günlükler, dökümler, ekran görüntüleri ve APK/dosya aktarımları | Çağıranın sağladığı adb (emülatör veya cihaz); [ADB rehberi](docs/adb-device-analysis.md) |
| JEB projeleri | Motor destekli proje birimleri, artefakt özetleri ve tür/metot sözdekodu | Çağıranın başlattığı, MCP sunan bir JEB istemcisi, REA_JEB_MCP_URL ile seçilir; [JEB rehberi](docs/jeb-analysis.md) |
| Android kaynakları | Çözülmüş manifest, dize tabloları, diller ve sürüm bilgileri | Çağıranın sağladığı Apktool başlatıcısı; [kaynak rehberi](docs/apktool-resource-analysis.md) |
| Flutter uygulamaları | Dart anlık görüntü karması, ABI başına kitaplık özetleri ve motor derleme kökeni | Yok (statik APK çözümleme); [Flutter rehberi](docs/flutter-analysis.md) |
| Donanım yazılımı | Bölgeler, çıkarma sonuçları ve yerel kod analizine devirler | Linux üzerinde Binwalk / Unblob; [donanım yazılımı rehberi](docs/firmware-analysis.md) |
| Kaydedilmiş paketler | Seçilen alanlar, yinelenen değerler, filtreler ve çözümleme kuralları | Linux: TShark 4.x + prlimit; [yakalama kılavuzu](docs/packet-captures.md) |
| Kaydedilmiş mantık sinyalleri | Kod çözücü açıklamaları, örnek aralıkları ve tanılama | Linux: sigrok-cli 0.7.2 + prlimit; [sinyal kılavuzu](docs/signal-recordings.md) |
| Paketler ve kaynaklar | Dosya envanterleri, özet değerleri, plist'ler, Apple paket yapısı ve çıkarılmış kaynaklar | [Artefakt ve JavaScript rehberi](docs/javascript-artifact-reconstruction.md), [Apple uygulamaları](docs/apple-application-analysis.md) |
| Süreç davranışı | Terminal çıktısı, etkileşimler, sonlanma ve dosya sistemi gözlemleri, çalıştırma karşılaştırmaları | Yerel PTY ile Linux/macOS; [süreç yakalama](docs/process-capture.md) |
@@ -262,7 +276,7 @@ Güvenlik açıklarını [SECURITY.md](SECURITY.md) üzerinden bildirin.
## Yıldız geçmişi
🎉 **GitHub'da 170.000 yıldız — teşekkürler!**
🎉 **GitHub'da 110.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.
@@ -276,13 +290,7 @@ REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve d
## Sorumluluk reddi
Sorumlu kullanım yönergeleri için [DISCLAIMER.md](DISCLAIMER.md) dosyasına bakın.
REA; yasal araştırma, eğitim, birlikte çalışabilirlik, yazılımın korunması ve sahibi olduğunuz ya da inceleme yetkiniz bulunan yazılımların analizi için tasarlanmıştır.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
Bkz. [Sorumlu kullanım](#sorumlu-kullanım).
## Katkıda bulunma
@@ -293,15 +301,3 @@ Geliştirme ortamı ve kontroller için [CONTRIBUTING.md](CONTRIBUTING.md), doğ
## Lisans
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### Один MCP для реверс-інжинірингу бінарних файлів, застосунків і поведінки під час виконання.
**Побачили цікаву функцію? Зрозумійте, як вона працює, аж до рівня двійкового коду.**
**Зрозумійте, як працює програмне забезпечення, аж до рівня двійкового коду — для досліджень безпеки, забезпечення сумісності та роботи з ПЗ, яке вам дозволено аналізувати.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Побачили в застосунку функцію, яку хочете додати до свого продукту? Попросіть агента дослідити її за допомогою REA. Він може перевірити застосунок без вихідного коду, пояснити роботу функції, показати підтвердження та створити реалізацію для вашого проєкту.
REA допомагає дослідникам безпеки, аналітикам шкідливого ПЗ, учасникам CTF і розробникам розбиратися в скомпільованому програмному забезпеченні за допомогою їхніх агентів. Вкажіть агенту бінарний файл, застосунок або захоплення, які вам дозволено аналізувати; REA дослідить їх без вихідного коду, пояснить їхню поведінку й покаже підтвердження кожного висновку.
REA підключає вашого агента до інструментів дослідження нативних бінарних файлів, застосунків JavaScript і Electron, збірок .NET та сайтів. Ті самі інструменти можна використовувати з термінала. Аналіз виконується локально, а результати містять підтвердження й обмеження, на яких ґрунтується кожен висновок.
@@ -55,6 +55,23 @@ REA підключає вашого агента до інструментів
> **[Відвідайте сайт REA](https://rea.tools/uk/)**, щоб знайти інструкції налаштування, ілюстровані посібники та реальні дослідження.
## Відповідальне використання
REA створено для законного аналізу: досліджень безпеки, аналізу шкідливого ПЗ та інцидентів, дослідження вразливостей і скоординованого розкриття, CTF і навчання, забезпечення сумісності, збереження програмного забезпечення, а також налагодження чи аудиту ПЗ, яким ви володієте або яке вам дозволено досліджувати.
Проєкт REA не підтримує таких дій і не допомагатиме з ними:
- обхід DRM, перевірок ліцензій, античит-систем та інших технічних засобів захисту;
- розробка читів для ігор або втручання в роботу онлайн-сервісів;
- обхід автентифікації, захисту від ботів або контролю доступу в системах, які вам не дозволено тестувати;
- копіювання пропрієтарного ПЗ або відтворення його захищеного коду й ресурсів;
- ухиляння від правил використання або заходів безпеки постачальників моделей ШІ;
- перепродаж або передавання облікових записів ШІ чи доступу до API.
Ви відповідаєте за отримання необхідних дозволів і дотримання застосовних законів, ліцензійних угод та умов обслуговування. Реверс-інжиніринг може бути обмежений у вашій юрисдикції або ліцензією програмного забезпечення, яке ви аналізуєте.
Запити про допомогу з переліченими вище діями закриватимуться без відповіді в issues та обговореннях і можуть призвести до виключення зі спільноти REA.
## Швидкий старт
### Налаштуйте агента
@@ -72,10 +89,11 @@ npx rea-agents setup
### Запитайте агента
```text
Досліди, як працює пошук у застосунку Notes, покажи підтвердження й створи подібну функцію для мого проєкту.
Release-збірка мого застосунку падає під час запуску, а debug-збірка — ні.
Досліди ./build/MyApp, знайди, де розходяться дві збірки, і покажи підтвердження.
```
Замініть Notes цільовим застосунком і вкажіть функцію, яку хочете зрозуміти.
Вкажіть агенту ціль, яку вам дозволено аналізувати, і опишіть, що ви хочете зрозуміти.
### Використовуйте термінал
@@ -139,16 +157,12 @@ REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а та
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](https://rea.tools/uk/guides/javascript/) |
| Сайти | Структура сторінки, скрипти, мережеві спостереження й запитані знімки екрана | Браузер сімейства Chrome; [аналіз браузера](https://rea.tools/uk/guides/browser/) |
| Збережені мережеві захоплення | Запити, відповіді, доступні корисні дані та місця в джерелі | HAR; mitmdump у Linux для захоплень у власному форматі mitmproxy; [посібник мережевих захоплень](docs/web-network-captures.md) |
| Захоплення пакетів | Кінцеві точки, DNS, TLS SNI, розподіл протоколів та HTTP-запити | Надані викликаючою стороною tshark та capinfos; [підручник pcap](docs/pcap-analysis.md) |
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](docs/managed-code-analysis.md) |
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS/Windows x64; [посібник Android](docs/android-analysis.md) |
| Пристрої Android | Пристрої, пакети, процеси, журнали, дампи, знімки екрана та передавання APK/файлів | adb, наданий викликаючою стороною (емулятор або пристрій); [підручник ADB](docs/adb-device-analysis.md) |
| Проєкти JEB | Єдиниці проєкту від рушія, дайджести артефактів і псевдокод типів/методів | Запущений викликаною стороною клієнт JEB з MCP, обирається через REA_JEB_MCP_URL; [посібник JEB](docs/jeb-analysis.md) |
| Ресурси Android | Декодований маніфест, таблиці рядків, мови та відомості про версію | Засіб запуску Apktool, наданий викликаючою стороною; [підручник ресурсів](docs/apktool-resource-analysis.md) |
| Додатки Flutter | Хеш знімка Dart, дайджести бібліотек за ABI та походження збірки рушія | Не потрібні (статичний розбір APK); [підручник Flutter](docs/flutter-analysis.md) |
| Прошивки | Області, результати видобування й передавання до нативного аналізу | Binwalk / Unblob у Linux; [посібник прошивок](docs/firmware-analysis.md) |
| Записані пакети | Вибрані поля, повторювані значення, фільтри та правила декодування | Linux: TShark 4.x + prlimit; [посібник із записів пакетів](docs/packet-captures.md) |
| Записані логічні сигнали | Анотації декодера, діапазони відліків і діагностика | Linux: sigrok-cli 0.7.2 + prlimit; [посібник із сигналів](docs/signal-recordings.md) |
| Пакети й ресурси | Переліки файлів, хеші, plist, структура пакетів Apple та видобуті ресурси | [Посібник артефактів і JavaScript](docs/javascript-artifact-reconstruction.md), [застосунки Apple](docs/apple-application-analysis.md) |
| Поведінка процесів | Вивід термінала, взаємодії, спостереження за завершенням і файловою системою та порівняння запусків | Linux/macOS із нативним PTY; [захоплення процесів](docs/process-capture.md) |
@@ -262,7 +276,7 @@ npx rea-agents@latest setup
## Історія зірок
🎉 **170 000 зірок на GitHub — дякуємо!**
🎉 **110 000 зірок на GitHub — дякуємо!**
Дякуємо всім, хто використовує REA, повідомляє про помилки, пропонує нові функції, тестує збірки й допомагає з виправленнями.
@@ -276,13 +290,7 @@ npx rea-agents@latest setup
## Відмова від відповідальності
Рекомендації щодо відповідального використання наведено в [DISCLAIMER.md](DISCLAIMER.md).
REA призначений для законних досліджень, навчання, забезпечення сумісності, збереження програмного забезпечення й аналізу програм, якими ви володієте або які маєте дозвіл досліджувати.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
Див. [Відповідальне використання](#відповідальне-використання).
## Участь у проєкті
@@ -293,15 +301,3 @@ applicable licenses.
## Ліцензія
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -28
View File
@@ -6,7 +6,7 @@
### Một MCP để dịch ngược tệp nhị phân, ứng dụng và hành vi khi chạy.
**Thấy một tính năng bạn thích? Hiểu cách nó hoạt động, đến tận mức mã nhị phân.**
**Hiểu cách phần mềm hoạt động, đến tận mức mã nhị phân — phục vụ nghiên cứu bảo mật, khả năng tương tác và phần mềm bạn được phép phân tích.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
Bạn thấy một tính năng trong ứng dụng và muốn đưa nó vào sản phẩm của mình? Hãy nhờ tác nhân của bạn điều tra bằng REA. Tác nhân có thể kiểm tra ứng dụng mà không cần mã nguồn, giải thích cách tính năng hoạt động, đưa ra bằng chứng và xây dựng một phiên bản cho dự án của bạn.
REA giúp các nhà nghiên cứu bảo mật, nhà phân tích mã độc, người chơi CTF và nhà phát triển hiểu phần mềm đã biên dịch thông qua tác nhân của họ. Hãy chỉ cho tác nhân của bạn một tệp nhị phân, ứng dụng hoặc bản ghi mà bạn được phép phân tích; REA kiểm tra nó mà không cần mã nguồn, giải thích hành vi của nó và đưa ra bằng chứng đằng sau từng kết luận.
REA kết nối tác nhân của bạn với các công cụ kiểm tra tệp nhị phân mã máy, ứng dụng JavaScript và Electron, assembly .NET và trang web. Bạn cũng có thể dùng các công cụ đó từ terminal. Việc phân tích chạy cục bộ; kết quả bao gồm bằng chứng và giới hạn làm cơ sở cho từng kết luận.
@@ -55,6 +55,23 @@ Quá trình thiết lập đăng ký REA với tác nhân và cài đặt các h
> **[Truy cập trang web REA](https://rea.tools/vi/)** để xem cách thiết lập, hướng dẫn có hình minh họa và các nghiên cứu điển hình thực tế.
## Sử dụng có trách nhiệm
REA được xây dựng cho hoạt động phân tích hợp pháp: nghiên cứu bảo mật, phân tích mã độc và sự cố, nghiên cứu lỗ hổng và công bố có phối hợp, CTF và giáo dục, khả năng tương tác, bảo tồn phần mềm, cũng như gỡ lỗi hoặc kiểm tra phần mềm mà bạn sở hữu hoặc được phép xem xét.
Dự án REA không ủng hộ và sẽ không hỗ trợ những việc sau:
- vượt qua DRM, cơ chế kiểm tra giấy phép, hệ thống chống gian lận hoặc các biện pháp bảo vệ kỹ thuật khác;
- phát triển công cụ gian lận trong trò chơi hoặc can thiệp vào dịch vụ trực tuyến;
- vượt qua cơ chế xác thực, chống bot hoặc kiểm soát truy cập trên các hệ thống bạn không được phép kiểm thử;
- sao chép phần mềm độc quyền hoặc tái tạo mã và tài nguyên được bảo hộ của phần mềm đó;
- né tránh chính sách sử dụng hoặc biện pháp an toàn của các nhà cung cấp mô hình AI;
- bán lại hoặc chia sẻ tài khoản AI hoặc quyền truy cập API.
Bạn có trách nhiệm có được các quyền cho phép cần thiết và tuân thủ luật, thỏa thuận cấp phép và điều khoản dịch vụ áp dụng. Dịch ngược có thể bị hạn chế tại khu vực pháp lý của bạn hoặc bởi giấy phép của phần mềm bạn phân tích.
Các yêu cầu trợ giúp cho những mục đích nêu trên sẽ bị đóng mà không phản hồi trong issue và thảo luận, và có thể dẫn đến việc bị loại khỏi cộng đồng REA.
## Bắt đầu nhanh
### Thiết lập tác nhân
@@ -72,10 +89,11 @@ Quá trình thiết lập hỗ trợ Claude Code, Codex, Cursor, Gemini CLI, Gro
### Hỏi tác nhân
```text
Tìm hiểu cách tính năng tìm kiếm trong ứng dụng Notes hoạt động, cho tôi xem bằng chứng và xây dựng tính năng tương tự cho dự án của tôi.
Bản build release của ứng dụng tôi bị crash khi khởi động nhưng bản build debug thì không.
Hãy kiểm tra ./build/MyApp, tìm chỗ hai bản build khác nhau và cho tôi xem bằng chứng.
```
Thay Notes bằng ứng dụng mục tiêu và chỉ rõ tính năng bạn muốn hiểu.
Hãy chỉ cho tác nhân của bạn một mục tiêu mà bạn được phép phân tích và mô tả điều bạn muốn hiểu.
### Sử dụng terminal
@@ -139,16 +157,12 @@ REA yêu cầu Node.js 22.x (>=22.19), 24.x (>=24.11) hoặc 26+, cùng với np
| JavaScript / Electron | Mô-đun, các khai báo import, source map, tuyến, IPC và quan hệ với tiện ích mở rộng mã máy | Node.js và npm; [phân tích ứng dụng](https://rea.tools/vi/guides/javascript/) |
| Trang web | Cấu trúc trang, script, quan sát mạng và ảnh chụp màn hình được yêu cầu | Trình duyệt thuộc họ Chrome; [phân tích trình duyệt](https://rea.tools/vi/guides/browser/) |
| Bản ghi lưu lượng mạng đã lưu | Yêu cầu, phản hồi, payload có thể truy cập và vị trí nguồn | HAR; mitmdump trên Linux cho bản ghi định dạng gốc của mitmproxy; [hướng dẫn bản ghi mạng](docs/web-network-captures.md) |
| Bắt gói tin | Điểm cuối, DNS, TLS SNI, phân bố giao thức và yêu cầu HTTP | tshark và capinfos do nơi gọi cung cấp; [hướng dẫn pcap](docs/pcap-analysis.md) |
| Assembly .NET | Siêu dữ liệu, lệnh CIL, các phụ thuộc mã máy được khai báo và so sánh bản dựng | Kiểm tra tĩnh; [hướng dẫn mã được quản lý](docs/managed-code-analysis.md) |
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS/Windows x64; [hướng dẫn Android](docs/android-analysis.md) |
| Thiết bị Android | Thiết bị, gói, tiến trình, nhật ký, dump, ảnh chụp màn hình và truyền APK/tệp | adb do nơi gọi cung cấp (trình giả lập hoặc thiết bị); [hướng dẫn ADB](docs/adb-device-analysis.md) |
| Dự án JEB | Đơn vị dự án từ engine, hash của artifact và mã giả của kiểu/phương thức | Một ứng dụng JEB do nơi gọi khởi động, phục vụ MCP, chọn bằng REA_JEB_MCP_URL; [hướng dẫn JEB](docs/jeb-analysis.md) |
| Tài nguyên Android | Manifest đã giải mã, bảng chuỗi, ngôn ngữ và thông tin phiên bản | Trình khởi chạy Apktool do nơi gọi cung cấp; [hướng dẫn tài nguyên](docs/apktool-resource-analysis.md) |
| Ứng dụng Flutter | Băm snapshot Dart, hash thư viện theo ABI và nguồn gốc build engine | Không cần (phân tích APK tĩnh); [hướng dẫn Flutter](docs/flutter-analysis.md) |
| Phần sụn | Các vùng, kết quả trích xuất và dữ liệu chuyển sang phân tích mã máy | Binwalk / Unblob trên Linux; [hướng dẫn phần sụn](docs/firmware-analysis.md) |
| Gói tin đã ghi | Trường được chọn, giá trị lặp, bộ lọc và quy tắc giải mã | Linux: TShark 4.x + prlimit; [hướng dẫn bản ghi gói tin](docs/packet-captures.md) |
| Tín hiệu logic đã ghi | Chú thích bộ giải mã, phạm vi mẫu và chẩn đoán | Linux: sigrok-cli 0.7.2 + prlimit; [hướng dẫn tín hiệu](docs/signal-recordings.md) |
| Gói và tài nguyên | Danh sách tệp, giá trị băm, plist, cấu trúc bundle Apple và tài nguyên được trích xuất | [Hướng dẫn hiện vật phần mềm và JavaScript](docs/javascript-artifact-reconstruction.md), [ứng dụng Apple](docs/apple-application-analysis.md) |
| Hành vi tiến trình | Đầu ra terminal, tương tác, quan sát khi thoát và hệ thống tệp, cùng so sánh các lần chạy | Linux/macOS có PTY gốc; [ghi lại tiến trình](docs/process-capture.md) |
@@ -262,7 +276,7 @@ Báo cáo lỗ hổng theo [SECURITY.md](SECURITY.md).
## Lịch sử sao
🎉 **170.000 sao trên GitHub — xin cảm ơn!**
🎉 **110.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.
@@ -276,13 +290,7 @@ Cảm ơn mọi người đã sử dụng REA, báo lỗi, đề xuất tính n
## Miễn trừ trách nhiệm
Xem [DISCLAIMER.md](DISCLAIMER.md) để biết hướng dẫn sử dụng có trách nhiệm.
REA dành cho nghiên cứu, giáo dục, khả năng tương tác, bảo tồn phần mềm và phân tích phần mềm bạn sở hữu hoặc được phép kiểm tra, trong khuôn khổ pháp luật.
The project's position on illegal or unauthorized use covers all REA
versions, distribution channels, and platforms; each copy retains its
applicable licenses.
Xem [Sử dụng có trách nhiệm](#sử-dụng-có-trách-nhiệm).
## Đóng góp
@@ -293,15 +301,3 @@ Xem [CONTRIBUTING.md](CONTRIBUTING.md) về thiết lập môi trường phát t
## Giấy phép
[MIT](LICENSE)
REA-authored code is licensed under MIT. Third-party material retains its own
licenses and copyright notices; see [Third-party notices](THIRD_PARTY_NOTICES.md)
for the dependency inventory, preserved license texts, and external-tool terms.
**You must legally obtain and be authorized to use commercial tools**, including
IDA Pro / Hex-Rays decompilers, Hopper, and JEB, under their applicable licenses.
REA grants no tool license, key, or activation entitlement. Trials and demos
remain subject to vendor terms, including user, feature, automation, and output
sharing restrictions. Cracked copies, stolen keys, unauthorized key sharing,
and bypassing license restrictions are not authorized. This guidance does not
amend MIT or third-party licenses.
+24 -23
View File
@@ -6,7 +6,7 @@
### 通過一個 MCP 服務,逆向分析二進位檔案、應用程式和執行階段行為。
**看到喜歡的功能,弄清它的工作原理,深入到二進位層面。**
**弄清軟體的工作原理,深入到二進位層面——用於安全研究、互通性,以及你獲授權分析的軟體。**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
在應用中看到一個想加入自己產品的功能?讓 AI 代理用 REA 調查它。即使沒有原始碼,AI 代理也可以檢查應用、解釋功能的工作方式、展示證據,並為你的專案實現類似功能。
REA 協助資安研究人員、惡意程式分析師、CTF 選手和開發者透過 AI 代理理解已編譯的軟體。把你獲授權分析的二進位檔案、應用程式或擷取資料交給 AI 代理;REA 無需原始碼即可檢查它、解釋其行為,並展示每個結論背後的證據。
REA 將 AI 代理連接到分析工具,用於檢查原生二進位檔案、JavaScript 和 Electron 應用、.NET 程式集以及網站。你也可以在終端中使用同樣的工具。分析在本機執行,結果包含支撐各項結論的證據和相關限制。
@@ -55,6 +55,23 @@ REA 將 AI 代理連接到分析工具,用於檢查原生二進位檔案、Jav
> **[訪問 REA 網站](https://rea.tools/zh-TW/)**,查看設定說明、圖解指南和真實案例。
## 負責任的使用
REA 專為合法分析而打造:資安研究、惡意程式與資安事件分析、漏洞研究與協調揭露、CTF 與教育、互通性、軟體保存,以及對你擁有或獲授權檢查的軟體進行除錯或稽核。
REA 專案不支持、也不會協助以下用途:
- 規避 DRM、授權檢查、反作弊系統或其他技術保護措施;
- 開發遊戲外掛或竄改線上服務;
- 在你未獲授權測試的系統上繞過身分驗證、機器人防護或存取控制;
- 複製專有軟體,或重現其受保護的程式碼和資源;
- 規避 AI 模型供應商的使用政策或安全措施;
- 轉售或共享 AI 帳號或 API 存取權限。
你有責任取得所需授權,並遵守適用的法律、授權協議和服務條款。逆向工程可能受到你所在司法管轄區或所分析軟體授權條款的限制。
在 issue 和討論區中尋求上述用途協助的請求將被直接關閉且不予回覆,並可能導致被移出 REA 社群。
## 快速開始
### 設定 AI 代理
@@ -72,10 +89,11 @@ npx rea-agents setup
### 詢問 AI 代理
```text
弄清 Notes 應用的搜尋功能如何工作,展示證據,並為我的專案實現類似功能。
我的應用程式的 release 建置在啟動時當機,但 debug 建置不會。
檢查 ./build/MyApp,找出兩個建置在哪裡出現分歧,並展示證據。
```
把 Notes 替換為目標應用,並描述你想瞭解的功能。
把你獲授權分析的目標交給 AI 代理,並描述你想瞭解的內容。
### 使用終端
@@ -139,16 +157,12 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
| JavaScript / Electron | 模組、匯入、source map、路由、IPC 和原生附加元件關係 | Node.js 和 npm;[應用分析](https://rea.tools/zh-TW/guides/javascript/) |
| 網站 | 頁面結構、腳本、網路觀察結果和按請求獲取的螢幕擷取畫面 | Chrome 系瀏覽器;[瀏覽器分析](https://rea.tools/zh-TW/guides/browser/) |
| 已保存的網路擷取 | 請求、回應、可訪問的酬載和來源位置 | HAR;原生 mitmproxy 擷取需要 Linux 上的 mitmdump;[擷取指南](docs/web-network-captures.md) |
| 封包擷取 | 端點、DNS、TLS SNI、通訊協定分佈和 HTTP 請求 | 呼叫端提供的 tshark 和 capinfos;[pcap 指南](docs/pcap-analysis.md) |
| .NET 程式集 | 中繼資料、CIL 指令、聲明的原生依賴和建置對比 | 靜態檢查;[托管程式碼指南](docs/managed-code-analysis.md) |
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS/Windows x64 上的無界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android 裝置 | 裝置、套件、程序、日誌、傾印、螢幕擷取以及 APK/檔案傳輸 | 呼叫端提供的 adb(模擬器或實體裝置);[ADB 指南](docs/adb-device-analysis.md) |
| JEB 專案 | 引擎支援的專案單元、成品摘要和型別/方法的虛擬碼 | 由呼叫端啟動、提供 MCP 的 JEB 用戶端,透過 REA_JEB_MCP_URL 選擇;[JEB 指南](docs/jeb-analysis.md) |
| Android 資源 | 解碼後的清單、字串表、語系和版本資訊 | 呼叫端提供的 Apktool 啟動器;[資源指南](docs/apktool-resource-analysis.md) |
| Flutter 應用 | Dart 快照雜湊、依 ABI 的程式庫雜湊及引擎建置來源 | 無(靜態 APK 解析);[Flutter 指南](docs/flutter-analysis.md) |
| 韌體 | 區域、提取結果和轉交原生分析的內容 | Linux 上的 Binwalk / Unblob;[韌體指南](docs/firmware-analysis.md) |
| 封包記錄 | 指定欄位、重複值、篩選條件與解碼規則 | Linux: TShark 4.x + prlimit; [封包分析指南](docs/packet-captures.md) |
| 錄製的邏輯訊號 | 解碼註解、樣本範圍與診斷資訊 | Linux: sigrok-cli 0.7.2 + prlimit; [訊號記錄指南](docs/signal-recordings.md) |
| 軟體包與資源 | 檔案清單、摘要、plist、Apple bundle 結構和提取的資源 | [製品與 JavaScript 指南](docs/javascript-artifact-reconstruction.md)、[Apple 應用](docs/apple-application-analysis.md) |
| 處理程序行為 | 終端輸出、互動、退出和檔案系統觀察結果,以及執行對比 | 支援原生 PTY 的 Linux/macOS;[處理程序擷取](docs/process-capture.md) |
@@ -264,7 +278,7 @@ npx rea-agents@latest setup
## Star 歷史
🎉 **GitHub Star 達到 170,000 個,感謝大家!**
🎉 **GitHub Star 達到 110,000 個,感謝大家!**
感謝每一位使用 REA、報告錯誤、提出功能需求、測試建置和貢獻修復的朋友。
@@ -278,12 +292,7 @@ npx rea-agents@latest setup
## 免責聲明
負責任使用的相關指引請見 [DISCLAIMER.md](DISCLAIMER.md)。
REA 用於合法的研究、教育、互通性、軟體保存,以及分析你擁有或獲准檢查的軟體。
本專案對非法或未經授權使用的立場涵蓋所有 REA 版本、分發管道和執行平台;
每份副本仍適用其隨附的授權。
參見[負責任的使用](#負責任的使用)。
## 參與貢獻
@@ -294,11 +303,3 @@ REA 用於合法的研究、教育、互通性、軟體保存,以及分析你
## 授權條款
[MIT](LICENSE)
REA 自行編寫的程式碼採用 MIT 授權;第三方內容保留各自的授權和著作權聲明。
依賴清單、授權原文及外部工具條款見[第三方聲明](THIRD_PARTY_NOTICES.md)。
**使用者須自行合法取得商用工具及所需使用權**,包括 IDA Pro / Hex-Rays 反編譯器、
Hopper 和 JEB,並遵守各自授權。REA 不提供工具授權、金鑰或啟用權利;試用版和
展示版也須遵守廠商對使用者、功能、自動化及輸出分享的限制。不得使用破解副本、
竊取或違規共用金鑰,也不得繞過授權限制。本指引不變更 MIT 或第三方授權。
+24 -23
View File
@@ -6,7 +6,7 @@
### 通过一个 MCP 服务,逆向分析二进制文件、应用程序和运行时行为。
**看到喜欢的功能,弄清它的工作原理,深入到二进制层面。**
**弄清软件的工作原理,深入到二进制层面——用于安全研究、互操作性,以及你获授权分析的软件。**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](docs/mcp-contracts.md#generated-catalog)
@@ -47,7 +47,7 @@
---
在应用中看到一个想加入自己产品的功能?让智能体用 REA 调查它。即使没有源代码,智能体也可以检查应用、解释功能的工作方式、展示证据,并为你的项目实现类似功能。
REA 帮助安全研究人员、恶意软件分析师、CTF 选手和开发者通过智能体理解已编译的软件。把你获授权分析的二进制文件、应用程序或捕获数据交给智能体;REA 无需源代码即可检查它、解释其行为,并展示每个结论背后的证据。
REA 将智能体连接到分析工具,用于检查原生二进制文件、JavaScript 和 Electron 应用、.NET 程序集以及网站。你也可以在终端中使用同样的工具。分析在本机运行,结果包含支撑各项结论的证据和相关限制。
@@ -55,6 +55,23 @@ REA 将智能体连接到分析工具,用于检查原生二进制文件、Java
> **[访问 REA 网站](https://rea.tools/zh-CN/)**,查看设置说明、图解指南和真实案例。
## 负责任的使用
REA 专为合法分析而构建:安全研究、恶意软件与安全事件分析、漏洞研究与协调披露、CTF 与教育、互操作性、软件保存,以及对你拥有或获授权检查的软件进行调试或审计。
REA 项目不支持、也不会协助以下用途:
- 规避 DRM、许可证检查、反作弊系统或其他技术保护措施;
- 开发游戏外挂或篡改在线服务;
- 在你未获授权测试的系统上绕过身份验证、机器人防护或访问控制;
- 复制专有软件,或复现其受保护的代码和资源;
- 规避 AI 模型提供商的使用政策或安全措施;
- 转售或共享 AI 账号或 API 访问权限。
你有责任取得所需授权,并遵守适用的法律、许可协议和服务条款。逆向工程可能受到你所在司法管辖区或所分析软件许可证的限制。
在 issue 和讨论区中寻求上述用途协助的请求将被直接关闭且不予回复,并可能导致被移出 REA 社区。
## 快速开始
### 设置智能体
@@ -72,10 +89,11 @@ npx rea-agents setup
### 询问智能体
```text
弄清 Notes 应用的搜索功能如何工作,展示证据,并为我的项目实现类似功能。
我的应用的 release 构建在启动时崩溃,但 debug 构建不会。
检查 ./build/MyApp,找出两个构建在哪里出现分歧,并展示证据。
```
把 Notes 替换为目标应用,并描述你想了解的功能。
把你获授权分析的目标交给智能体,并描述你想了解的内容。
### 使用终端
@@ -139,16 +157,12 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
| JavaScript / Electron | 模块、导入、source map、路由、IPC 和原生扩展关系 | Node.js 和 npm;[应用分析](https://rea.tools/zh-CN/guides/javascript/) |
| 网站 | 页面结构、脚本、网络观察结果和按请求获取的截图 | Chrome 系浏览器;[浏览器分析](https://rea.tools/zh-CN/guides/browser/) |
| 已保存的网络捕获 | 请求、响应、可访问的载荷和来源位置 | HAR;原生 mitmproxy 捕获需要 Linux 上的 mitmdump;[捕获指南](docs/web-network-captures.md) |
| 数据包捕获 | 端点、DNS、TLS SNI、协议分布和 HTTP 请求 | 调用方提供的 tshark 和 capinfos;[pcap 指南](docs/pcap-analysis.md) |
| .NET 程序集 | 元数据、CIL 指令、声明的原生依赖和构建对比 | 静态检查;[托管代码指南](docs/managed-code-analysis.md) |
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS/Windows x64 上的无界面 JADX 和完整 JDK;[Android 指南](docs/android-analysis.md) |
| Android 设备 | 设备、软件包、进程、日志、转储、屏幕截图以及 APK/文件传输 | 调用方提供的 adb(模拟器或实体设备);[ADB 指南](docs/adb-device-analysis.md) |
| JEB 项目 | 引擎支持的项目单元、工件摘要和类型/方法的伪代码 | 由调用方启动、提供 MCP 的 JEB 客户端,通过 REA_JEB_MCP_URL 选择;[JEB 指南](docs/jeb-analysis.md) |
| Android 资源 | 解码后的清单、字符串表、语言区域和版本信息 | 调用方提供的 Apktool 启动器;[资源指南](docs/apktool-resource-analysis.md) |
| Flutter 应用 | Dart 快照哈希、按 ABI 的库摘要及引擎构建溯源 | 无(静态 APK 解析);[Flutter 指南](docs/flutter-analysis.md) |
| 固件 | 区域、提取结果和转交原生分析的内容 | Linux 上的 Binwalk / Unblob;[固件指南](docs/firmware-analysis.md) |
| 抓包文件 | 指定字段、重复值、过滤条件与解码规则 | Linux: TShark 4.x + prlimit; [抓包分析指南](docs/packet-captures.md) |
| 录制的逻辑信号 | 解码注释、样本范围和诊断信息 | Linux: sigrok-cli 0.7.2 + prlimit; [信号记录指南](docs/signal-recordings.md) |
| 软件包与资源 | 文件清单、摘要、plist、Apple bundle 结构和提取的资源 | [制品与 JavaScript 指南](docs/javascript-artifact-reconstruction.md)、[Apple 应用](docs/apple-application-analysis.md) |
| 进程行为 | 终端输出、交互、退出和文件系统观察结果,以及运行对比 | 支持原生 PTY 的 Linux/macOS;[进程捕获](docs/process-capture.md) |
@@ -264,7 +278,7 @@ npx rea-agents@latest setup
## Star 历史
🎉 **GitHub Star 达到 170,000 个,感谢大家!**
🎉 **GitHub Star 达到 110,000 个,感谢大家!**
感谢每一位使用 REA、报告错误、提出功能需求、测试构建和贡献修复的朋友。
@@ -278,12 +292,7 @@ npx rea-agents@latest setup
## 免责声明
负责任使用的相关指引请见 [DISCLAIMER.md](DISCLAIMER.md)。
REA 用于合法的研究、教育、互操作性、软件保存,以及分析你拥有或获准检查的软件。
本项目对非法或未经授权使用的立场涵盖所有 REA 版本、分发渠道和运行平台;
每份副本仍适用其随附的许可。
参见[负责任的使用](#负责任的使用)。
## 参与贡献
@@ -294,11 +303,3 @@ REA 用于合法的研究、教育、互操作性、软件保存,以及分析
## 许可证
[MIT](LICENSE)
REA 自行编写的代码采用 MIT 许可;第三方内容保留各自的许可和著作权声明。
依赖清单、许可原文及外部工具条款见[第三方声明](THIRD_PARTY_NOTICES.md)。
**用户须自行合法取得商用工具及所需使用权**,包括 IDA Pro / Hex-Rays 反编译器、
Hopper 和 JEB,并遵守各自许可。REA 不提供工具许可、密钥或激活权利;试用版和
演示版也须遵守厂商对用户、功能、自动化及输出分享的限制。不得使用破解副本、
窃取或违规共用密钥,也不得绕过许可限制。本指引不变更 MIT 或第三方许可。
+3 -6
View File
@@ -24,12 +24,9 @@ provider-dependent behavior to be reproduced safely.
## Security boundary
REA authenticates its Hopper and Ghidra bridges with per-session random
capability tokens. POSIX uses current-user Unix sockets; Windows Ghidra uses
authenticated loopback TCP with a private NTFS runtime whose DACL admits only
the current user and SYSTEM. See [Windows Ghidra P0](docs/windows-ghidra-p0.md#private-runtime-transport-and-lifecycle).
Tokens are transferred through private session descriptors rather than process
arguments or environment variables.
REA authenticates each local provider bridge session with a random capability
token and a current-user Unix socket. Tokens are transferred through private
session descriptors rather than process arguments or environment variables.
This is not a sandbox and does not protect against malicious processes already
running as the same operating-system user. Opening an untrusted binary
delegates parsing and analysis to the selected local provider with that user's
-134
View File
@@ -1,134 +0,0 @@
# Third-party notices
REA-authored code is licensed under [MIT](LICENSE). Third-party material retains
its own copyright, license, attribution, and NOTICE requirements. REA's MIT
license grants no rights to proprietary analysis tools. Project and product
names identify integrations; they do not imply affiliation or endorsement.
This inventory covers the locked npm dependency graph, code or assets derived
from upstream projects, and separately obtained engines used by REA. A listed
integration is not a statement that its executable is bundled. Upstream
components and caller-selected versions may have additional terms; retain the
notices supplied with the software you actually obtain or redistribute.
## Distributed dependencies, derived code, and assets
| Material | Use and licensing records |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| npm dependencies | [Complete inventory](licenses/npm-dependencies.txt) of every entry in `package-lock.json`, including transitive, optional platform, development, and website dependencies. [Runtime notices](licenses/npm-runtime-notices.txt) preserve the copyright, license, and NOTICE documents from integrity-verified release archives, plus the MIT notice for Rolldown's generated runtime helpers. Development dependencies are inventoried but are not all distributed in REA's npm package. |
| NativeAOT parser | REA's derived parser uses the MIT-licensed [ghidra-nativeaot](https://github.com/Washi1337/ghidra-nativeaot/tree/effeb734fc570c32650f88b159608979dc7b423e) work of Washi and the NativeAOT layout definitions in [dotnet/runtime](https://github.com/dotnet/runtime/tree/a3b2d40328be0be3f8dd43f0e5cc925b8827b044). Preserve [Washi's MIT notice](licenses/nativeaot-parser-MIT.txt) and the [.NET Foundation MIT notice](licenses/dotnet-runtime-MIT.txt). |
| EVM analysis | `evmole@0.9.3`, MIT, copyright 2023 Maxim Andreev. The published npm archive omits its license document; REA retains the [original upstream license](third_party/evmole/LICENSE) and [provenance](third_party/evmole/README.md). It is also included in the runtime notices. |
| Windows native addon | The release addon is compiled with MinGW-w64 and statically links GCC runtime libraries. Preserve the [MinGW-w64 runtime notices](licenses/MinGW-w64-runtime.txt), [GPLv3 text](licenses/GPL-3.0.txt), and [GCC Runtime Library Exception 3.1](licenses/GCC-Runtime-Library-Exception-3.1.txt). The exception governs eligible compiled combinations; it does not relicense the runtime itself under MIT. The Node-API build headers are from Node 22.19.0; its [original license and component notices](licenses/Node-22.19.0-LICENSE.txt) are retained. Node itself is supplied by the user. Snapshot provenance and release-toolchain review requirements are in [licenses/README.md](licenses/README.md). |
| Dinosaur website example | Selected excerpts from [wayou/t-rex-runner](https://github.com/wayou/t-rex-runner/tree/5455bfa408ec6b707c7300ff194b7390733a766d), derived from Chromium's dinosaur game. The website retains the [original BSD-3-Clause notices](website/public/assets/licenses/dinosaur.txt), including Chromium authors and wayou. This asset is not part of the npm runtime. |
Two locked runtime releases, [`clean-git-ref@2.0.1`](https://github.com/TheSavior/clean-git-ref/tree/bf3c8afc8032bcdc6a53634c18b601dc6df478fb) (declared Apache-2.0) and
[`minimisted@2.0.1`](https://github.com/kt3k/minimisted/tree/95fdfb8d6efb9546c1117854fe3a58105f6332ce) (declared MIT), omit a full license/copyright document in their
published archives and inspected upstream release sources. Their runtime notice
entries preserve the declared license and author metadata and include a clearly
labeled standard license text. These are documented upstream notice gaps, not
recovered copyright notices or a claim that attribution has been fully verified.
The optional `frida@17.23.2` npm archive and tagged Node binding source also
omit a standalone license/copyright document. Its declared
`LGPL-2.0 WITH WxWindows-exception-3.1` license is recorded with unchanged
[Frida licensing text](licenses/frida-17.23.2-COPYING.txt) and the
[GNU Library GPL v2](licenses/LGPL-2.0.txt). These are licensing supplements,
not recovered Node binding or prebuild-component copyright notices.
## Open-source engine credits and licenses
We thank the maintainers and contributors of the projects below. Their
decompilers, binary-analysis engines, debuggers, parsers, and capture tools
provide capabilities used through REA's integrations. Each row identifies the
upstream project, its own license, and its role in REA. In particular, JADX
provides the Android decompiler, while jadx-headless-mcp provides the separate
headless integration used by REA; both projects deserve credit.
These acknowledgments are voluntary thanks. Required upstream copyright and
NOTICE texts remain in their original form and are not replaced by this
summary. Credits do not imply endorsement or change any license.
REA's adapters do not grant, replace, or waive these licenses. The upstream
executables and their dependency graphs are supplied separately. Git submodules
pin inspection sources; they are not included in the npm package.
| Project | License and source | REA relationship |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ghidra | [Apache-2.0](https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1.4_build/LICENSE), with the government-work and component qualifications in its [NOTICE](https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1.4_build/NOTICE) | Bring your own Ghidra 12.1.4. Copies of its [LICENSE](licenses/ghidra-12.1.4-LICENSE.txt), [NOTICE](licenses/ghidra-12.1.4-NOTICE.txt), and [DISCLAIMER](licenses/ghidra-12.1.4-DISCLAIMER.txt) are retained for reference. |
| 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. |
| 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. |
| Wakaru | [Apache-2.0](https://github.com/pionxzh/wakaru/blob/8219bf5016a063d7fb215101a8c45d5959ec733f/LICENSE) | v1.14.0; pinned source and separately obtained JavaScript reconstruction tooling. |
| WABT | [Apache-2.0](https://github.com/WebAssembly/wabt/blob/ff0ef7e0009402740c805a9744c09b05be063e48/LICENSE) | v1.0.42; external WebAssembly tools; [integration provenance](third_party/wabt/README.md). |
| pwntools | [MIT, with GPL/BSD component qualifications](https://github.com/Gallopsled/pwntools/blob/3ad86ec5adab1abf9781ca7552a6f5d7cff7a33c/LICENSE-pwntools.txt) | 4.15.0; caller-supplied offline ELF analysis package. |
| pyelftools | [Public-domain dedication and component notices](https://github.com/eliben/pyelftools/blob/v0.33/LICENSE) | 0.33; includes separately licensed bundled material, including Construct. |
| Unicorn | [GPL-2.0 and component notices](https://github.com/unicorn-engine/unicorn/blob/2.1.2/COPYING) | 2.1.2; used by the caller-supplied ELF analysis profile for instruction emulation. |
| pwndbg | [MIT](third_party/pwndbg/LICENSE.md) | 2026.09.15, commit `55596aa676a2756efb8d67034f31675170eabe48`; separately obtained debugger extension. |
| GNU GDB | [GPL-3.0-or-later](https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/COPYING) | Caller-supplied debugger for the optional pwndbg core-file workflow. |
| LLDB / LLVM | [Apache-2.0 with LLVM exceptions](https://github.com/llvm/llvm-project/blob/main/LICENSE.TXT) | Caller-supplied debugger; the installed distribution's component and historical notices also apply. |
| mitmproxy | [MIT](https://github.com/mitmproxy/mitmproxy/blob/6c09d56e4c29a92f5ad01b03199977584b8ea14f/LICENSE) | 12.2.3; separately supplied network capture proxy. |
| Android Debug Bridge (adb) | [Apache-2.0](https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/NOTICE) | User-supplied Android device tool. A complete Android SDK download has its own [SDK license terms](https://developer.android.com/studio/terms); adb's source license does not replace them. |
| ILSpy / ICSharpCode.Decompiler | [MIT](https://github.com/icsharpcode/ILSpy/blob/master/ICSharpCode.Decompiler/Properties/AssemblyInfo.cs) | Optional separately installed .NET decompiler; not a redistributed REA dependency. |
Ghidra's original notice credits software developed at the National Security
Agency. It explains that US-government-created portions are not subject to US
copyright protection, while other portions retain their authors' rights. Its
modules include additional third-party licenses, and standalone programs under
`GPL/` have GPLv3 terms. The three retained top-level documents do not replace
the module notices and license directories in a complete Ghidra distribution.
REA is not affiliated with or endorsed by the NSA.
## Commercial tools and bridges
**You must legally obtain the tools and the rights needed for your use.** REA
does not include an IDA Pro, Hex-Rays decompiler, Hopper, or JEB license, license
key, or activation entitlement. A permitted trial/demo may be used only within
its official terms. Cracked copies, stolen keys, unauthorized sharing, and
bypassing activation or license limits are not authorized by REA.
| Project / product | Applicable terms and distinction |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| IDA Pro and Hex-Rays decompilers | Proprietary Hex-Rays software governed by the [EULA](https://hex-rays.com/eula), purchase agreement, and applicable license scheme. Obtain rights for the required product, user, machine, decompiler, and automation interfaces. Availability of an API or a bridge does not grant hosting, service, or additional-user rights. |
| ida-pro-mcp | The bridge's [MIT license](https://github.com/mrexodia/ida-pro-mcp/blob/main/LICENSE) belongs to Duncan Ogilvie. It licenses the bridge code, not IDA or Hex-Rays products. Its [README](https://github.com/mrexodia/ida-pro-mcp#prerequisites) requires IDA Pro and explicitly states that IDA Free is unsupported. Follow the prerequisites for the version you actually install. The bridge is separately supplied, not bundled by REA. |
| Hopper Disassembler | Proprietary Cryptic Apps software under its [license agreement](https://www.hopperapp.com/license_agreement.html). Personal and computer licenses have different permitted-user and installation rules; an official evaluation trial is available. REA setup may obtain the official installer after approval, but this grants no paid license or activation entitlement. |
| JEB | Proprietary PNF Software product under its [EULA](https://www.pnfsoftware.com/jeb/LICENSE.TXT) and edition-specific agreement. Check user/seat/server rights and whether your edition permits automation, backend/service integration, and disclosure of generated output. The published EULA restricts public or third-party disclosure of decompiled code, reconstructed artifacts, and analysis reports unless expressly permitted by the license type. |
The vendor's applicable agreement controls. These summaries do not interpret
your individual contract or expand the rights it grants. Verify permissions
before publishing analysis output, sharing tool access, or operating a service.
Vendor terms above were checked on 2026-10-12.
## Runtimes, development tooling, and fixtures
REA uses a caller-supplied Node.js runtime ([MIT and component notices](https://github.com/nodejs/node/blob/main/LICENSE)).
Optional workflows may also use Python ([PSF and component licenses](https://docs.python.org/3/license.html)),
OpenJDK ([GPLv2 with Classpath Exception and component notices](https://openjdk.org/legal/)),
Electron ([MIT and component notices](https://github.com/electron/electron/blob/main/LICENSE)),
or a Chromium-based browser ([BSD-3-Clause and third-party licenses](https://chromium.googlesource.com/chromium/src/+/main/LICENSE)).
These external installations are not licensed or bundled by REA's MIT license.
Development, test, and website npm packages are included in the locked inventory.
GitHub Actions, operating-system utilities, downloaded verification fixtures,
and their runtimes retain the terms supplied by their publishers. Fixture
identities and provenance are recorded under `scripts/fixtures/` and the
existing `third_party/` records; downloaded executable fixtures are not tracked
or included in the npm package. This notice does not claim to inventory every
dependency of a caller's operating system, agent, or separately installed tool.
## Maintaining and redistributing notices
Refresh the dependency inventory and runtime notice collection when the lockfile
changes. Review the actual versions and distributed contents, retain the
upstream license and copyright texts, and account for optional platform
packages. See [licenses/README.md](licenses/README.md) for source provenance,
collection scope, and known upstream notice gaps.
The npm package includes this document, the `licenses/` directory, and the
existing redistributed license records under `third_party/`. If you additionally
bundle an external engine or modify upstream code, review that actual
distribution and retain its full applicable licenses, copyright notices,
NOTICE files, modification notices, and source obligations. REA's inventory is
not a substitute for those obligations.
+4 -13
View File
@@ -17,7 +17,6 @@ export default defineConfig({
text: "Getting started",
items: [
{ text: "Installation and setup", link: "/installation" },
{ text: "Client configuration", link: "/client-configuration" },
{ text: "CLI and Evidence", link: "/cli" },
{ text: "Agent prompts", link: "/mcp-prompts" },
{ text: "Roadmap", link: "/roadmap" },
@@ -37,19 +36,16 @@ export default defineConfig({
link: "/javascript-application-workflows",
},
{ text: "Browser observation", link: "/browser-observation" },
{
text: "Web network captures",
link: "/web-network-captures",
},
{ text: "Electron observation", link: "/electron-observation" },
{ text: "Process capture", link: "/process-capture" },
{ text: ".NET assemblies", link: "/managed-code-analysis" },
{ text: "Android applications", link: "/android-analysis" },
{ text: "Apple applications", link: "/apple-application-analysis" },
{ text: "Firmware", link: "/firmware-analysis" },
{ text: "SQLite databases", link: "/sqlite-databases" },
{ text: "Packet captures", link: "/packet-captures" },
{ text: "Signal recordings", link: "/signal-recordings" },
{
text: "Reconstruction readiness",
link: "/reconstruction-readiness",
},
],
},
{
@@ -71,11 +67,6 @@ export default defineConfig({
{ text: "MCP contracts", link: "/mcp-contracts" },
{ text: "Tool design", link: "/tool-design" },
{ text: "Testing", link: "/testing" },
{ text: "Client verification", link: "/client-verification" },
{
text: "Reconstruction readiness",
link: "/reconstruction-readiness",
},
{ text: "Releasing", link: "/releasing" },
],
},
+2 -7
View File
@@ -136,8 +136,8 @@ existing analysis families directly, for example
## Resource and lifecycle limits
- Caller values reach adb only as positional arguments in fixed vectors;
no tool accepts an arbitrary shell command line, `input`, or `monkey`.
The app/activity lifecycle tools use `am start -W` and `am force-stop`.
no tool accepts an arbitrary shell command line, and UI interaction
(`input`, `am`, `monkey`) is deliberately not exposed.
- Per-invocation budgets: client/devices 10-20 s, shell reads 20-60 s with
64 KiB-8 MiB capture caps (logcat 4 MiB, screen 32 MiB), transfers and
bugreports 600 s. Exceeded budgets report `resource_constraint`; stopped
@@ -148,11 +148,6 @@ existing analysis families directly, for example
- 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.
- 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
its recoverable `local_path`, the original `adb_reported_path`, and an unknown
digest status. Later operations and shutdown preserve this retained evidence.
- Failed package acquisition rollback retains its directory identity and retries
cleanup before later work and during shutdown. Cleanup refuses a replacement
directory. Terminal shutdown stops admission and drains active operations.
-21
View File
@@ -9,27 +9,6 @@ This family is present on repository main and in npm 4.1.0. Check the
[released package boundary](installation.md#released-package-and-main) and the
connected server's tool list before selecting it.
## Optional package delivery
The MCP `inspect_android_package` request keeps complete output when `detail` is
omitted or `"complete"`. Select `detail: "summary"` explicitly to receive all
package, SDK and permission declarations, engine identity and class/resource
counts without decoded manifest text or duplicate raw provider replies. A
retaining session keeps the complete original Evidence and returns a distinct
linked `inspect_analysis_view` summary. This changes delivery, not JADX analysis.
Use the returned `normalized_result.parent_evidence_id` with
`inspect_analysis_view`, source kind `retained-evidence`, and
`view: {kind: "android", facet: "manifest", offset: 0, limit: 4096}` to read the
exact decoded manifest without reopening the APK. Offsets and limits count UTF-16
code units; follow `coverage.next_offset`. The page preserves `source_status` and
`reported_total_bytes`: exhausting retained text does not make a partial decoded
manifest complete. Complete source Evidence remains exportable under the existing
session lifetime. Servers without retention reject summary before starting JADX.
One-shot CLI output remains complete. Older servers require the existing complete
request after schema discovery. APK authenticity and runtime behavior remain
unverified.
## Supply tools
Use a **full JDK 17 or newer** (including its compiler module) and
+1 -5
View File
@@ -6,7 +6,7 @@ graph TD
end
subgraph "Production Composition"
COMPOSITION["src/composition/<br/>fresh typed provider and session factories<br/>one-shot binding and independent optional loading<br/>static WASM/EVM descriptors: named contracts, factories, retryable lifetimes"]
COMPOSITION["src/composition/<br/>fresh typed provider and session factories<br/>one-shot binding and independent optional loading"]
end
subgraph "Adapters"
@@ -27,7 +27,6 @@ graph TD
subgraph "Provider Layers"
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"]
HOPPER["src/hopper/<br/>Hopper launch & Unix-socket protocol<br/>BridgeLauncher, HopperClient, protocol"]
GHIDRA["src/ghidra/<br/>Ghidra discovery, profile & function analysis<br/>snapshot, Unix/Windows transport, bounded lifecycle"]
@@ -95,9 +94,6 @@ graph TD
APP -->|record callbacks| RECORDS
SERVER -->|narrow record ports| RECORDS
RECORDS --> DOMAIN
COMPOSITION --> WASM
WASM --> PROCESS
WASM --> DOMAIN
COMPOSITION --> PWNTOOLS
PWNTOOLS --> PROCESS
PWNTOOLS --> DOMAIN
+1 -3
View File
@@ -101,9 +101,7 @@ Complete results have a 32 MiB input, 64 MiB reply, 1 MiB combined diagnostics
and 30-second owned command deadline. The reply budget applies to the decoder
record; the CLI/MCP Evidence envelope adds copies and encoding overhead. The
pinned MCP SDK defaults to a 10 MiB receive buffer. Large complete results need
a caller-configured `StdioClientTransport({ maxBufferSize: ... })` and a matching
server `REA_MCP_MAX_RESPONSE_BYTES`. See [MCP delivery budgets](mcp-contracts.md#tool-results).
These settings affect delivery, not decoder coverage or limits. The large
a caller-configured `StdioClientTransport({ maxBufferSize: ... })`; the large
extended-index verification uses 256 MiB and an explicit five-minute request
timeout in its separate opt-in MCP lane. REA does not silently truncate the result. Python lowers resource soft limits to at most 3 GiB virtual address space,
30 CPU seconds and 64 MiB file output. Inherited tighter soft/hard limits are
+1 -13
View File
@@ -8,10 +8,6 @@ exported script's native imports under an explicit URL/import-map context.
REA can attach to a user-owned Chrome-family browser through the Chrome DevTools Protocol (CDP) and produce bounded Evidence about an existing page. This is a passive reverse-engineering capability, not a general browser automation or remote-control surface.
For request/response bodies and traffic debugging, see
[Fiddler Everywhere captures and MCP](web-network-captures.md#reading-fiddler-captures-saz).
Inspect native SAZ or HAR 1.2 offline with REA, or connect Everywhere's separate MCP server.
## Shipped surfaces
- `list_browser_targets` / `rea list-browser-targets` discovers all eligible page targets at the endpoint by default, with an optional exact-origin filter.
@@ -197,15 +193,7 @@ validation and resource bounds. Omitted script metadata makes its affected
section explicitly truncated.
Disallowed-origin entries are filtered before retention.
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
and malformed replies to pending commands poison the connection so later
commands fail closed. A correlated reply's session ID must match the command's
selected session. An optional method is unavailable only when the browser
rejects it as unknown; other command rejections retain their reported failure.
CDP discovery, WebSocket connection, and commands continue until the peer responds or the caller cancels the operation; REA has no internal byte, message-count, or pending-command quota for these exchanges. Without caller cancellation, a stalled peer can leave an operation waiting. On cancellation, REA closes only its own WebSocket, waiting up to one second before terminating it. Malformed unsolicited events and malformed replies to pending commands poison the connection so later commands fail closed. When a correlated reply reports a session ID, it must match the command's selected session. An optional method is reported unavailable only when the browser rejects it as unknown; other command rejections retain their reported failure.
Network and console coverage starts only after REA attaches and enables the relevant CDP domains. `prior_activity_available` is always `false`; absence from these arrays is not evidence that an event never occurred. If CDP reuses a request ID without supplying redirect metadata, REA retains the predecessor observation and marks network coverage incomplete.
+2 -13
View File
@@ -262,13 +262,8 @@ Capturing more data alone does not establish a website change.
states. Captured bodies retain base64 bytes, byte count, media type, and SHA-256
of the retained bytes. Request bytes are those exposed by Playwright; a
`not_exposed` request body does not prove absence or complete multipart file
coverage. Response bytes are the result of Playwright's `Response.body()` API.
Playwright may satisfy that API with a credentialed follow-up load of the
request URL when CDP has no response body. Event and transaction references
identify the associated Playwright response object, but do not verify that the
retained bytes came from the original network transaction. Successful selected
response bodies include this limitation in the capture. These bytes are not
the compressed wire representation.
coverage. Response bytes are decoded by the browser, not the compressed wire
representation. No later fetch is substituted for the original response.
Headers preserve producer order and duplicates. Authorization,
Proxy-Authorization, Cookie, and Set-Cookie values are null with
`redacted: true`; ordinary values remain intact. Declared UTF-8 secret values
@@ -312,9 +307,3 @@ artifacts carry their normalized before/after digests and capture states.
Every changed or unknown artifact record is returned inline for each aligned
step. Missing, truncated, or mismatched capture coverage remains unknown
instead of being treated as equality.
`scenario.event_families` records the sorted, de-duplicated `capture.events`
selection. Captures with different selections report event evidence as unknown
with a recovery instruction, even when no selected family emitted an event.
Captures written before this field existed omit it, so their event evidence is
also unknown.
+2 -12
View File
@@ -62,14 +62,6 @@ unpack .NET single-file hosts or decode IL2CPP metadata. NativeAOT method bodies
require native analysis. See the [managed-code guide](managed-code-analysis.md)
for supported deployment forms, selection semantics, and coverage limits.
## SQLite snapshots
For a local database snapshot, use `rea inspect-sqlite-database PATH --json`.
Add `--table NAME --row-limit 20` to read a bounded sample from an ordinary
table. This command does not require a native analysis provider. See
[SQLite database snapshots](sqlite-databases.md) for database/WAL identity,
source-file handling and row-value semantics.
## Native analysis
Inspect embedded Go build metadata without installing Go or configuring a
@@ -101,7 +93,7 @@ a function dossier; `decompile` returns pseudocode. For assembly instructions
alone, use `rea instructions`. A macOS `.app` bundle can be supplied directly.
Run `rea --help` or a command's `--help` for arguments and output options.
The [generated catalog](mcp-contracts.md#generated-catalog) lists all CLI commands and MCP
The [generated catalog](product-catalog.json) lists all CLI commands and MCP
tools. Provider-specific target support is described in the
[native guide](native-investigation.md), [DOS guide](ghidra-dos.md),
[raw binary guide](raw-binary.md), and
@@ -215,9 +207,7 @@ rea import-reference-source /absolute/path/to/source
```
The import records hashes and metadata for the supplied files, separately
from observations of the current app. For a directory inside a Git checkout,
it records the HEAD of the nearest enclosing repository; whether the working
tree matches that commit remains unknown. It honors the source tree's `.gitignore`
from observations of the current app. It honors the source tree's `.gitignore`
and applies default exclusions for common generated and dependency paths such
as `node_modules/`, `dist/`, and `*.log`. Pattern-based exclusions record the
matched pattern and whether it came from project, default, caller, or sensitive
-280
View File
@@ -1,280 +0,0 @@
# Client configuration and troubleshooting
Use this reference when a client's configuration paths, profiles, trust settings,
or schema limits affect REA. Start with [installation and setup](installation.md)
for the reviewed setup transaction and [client IDs](installation.md#supported-agents).
The versioned verification notes below describe their stated runs; live service
acceptance is verified only where explicitly recorded.
## Fiddler Everywhere alongside REA
Connect Fiddler Everywhere's MCP server separately for HTTP traffic debugging,
preserving your REA client entry. See the
[setup instructions and public skills](web-network-captures.md#fiddler-everywhere-mcp-and-public-skills).
## GitHub Copilot CLI
For GitHub Copilot CLI 1.0.95, `gpt-4.1` model metadata can block ordinary
chat with REA's full input-schema profile before sending a model request
(`compaction_static_context_blocked`; [#1554](https://github.com/morluto/rea/issues/1554)).
For the native offline OpenAI-compatible BYOK adapter, full-profile chat and
analysis also passed with a distinct `COPILOT_PROVIDER_MODEL_ID` such as
`rea-gpt-4.1`, `COPILOT_PROVIDER_WIRE_MODEL=gpt-4.1`, and that distinct ID selected
through `copilot --model rea-gpt-4.1`. The local fixture requested
`COPILOT_PROVIDER_MAX_PROMPT_TOKENS=1000000`; configure the limit supported by
your backend. This keeps every full schema and the actual wire model intact.
It does not establish the effective client budget or fix the built-in-ID path.
The existing compact profile passed native chat and analysis with the complete
tool inventory on Linux using a loopback model fixture. After setup, add
`"REA_MCP_INPUT_SCHEMA_PROFILE": "compact"` to the `env` object of the
`mcpServers.rea` entry in Copilot's `mcp-config.json`, preserving its other
settings, then restart the client. Compact advertisements can reduce nested
schema constraints; REA still validates complete canonical inputs. Full-profile
`gpt-5.4` metadata is also verified locally. Live model API acceptance and
Windows remain unverified; see [native client verification](testing.md).
## Claude Code
Claude Code normally defers MCP tool definitions through tool search. It
[turns tool search off](https://code.claude.com/docs/en/mcp#configure-tool-search)
when `ANTHROPIC_BASE_URL` points to a non-first-party host, such as DeepSeek's
Anthropic-compatible endpoint. It then sends every REA tool's name, description
and input schema with every request
([#2019](https://github.com/morluto/rea/issues/2019)). On main at 04089d5be,
with 172 tools, that payload measured about 496 KB with the default profile and
about 290 KB with `compact`. By the o200k and cl100k tokenizers, that is roughly
120k and 68k tokens. Compaction cannot remove tool definitions. If they nearly
fill the window Claude Code assumes, the context refills after every compaction
and Claude Code reports that autocompact is thrashing. To avoid this:
- Make Claude Code assume the model's actual context window. DeepSeek's Claude
Code guide selects `deepseek-flash[1m]`; the `[1m]` suffix makes Claude Code
assume a one-million-token window. For other unrecognized model IDs, set
`CLAUDE_CODE_MAX_CONTEXT_TOKENS` to the window the provider documents.
- If the endpoint forwards `tool_reference` blocks, set `ENABLE_TOOL_SEARCH=true`
to restore deferred loading. DeepSeek's Anthropic API guide does not list
`tool_reference` among its supported content blocks, so this setting may cause
its requests to fail.
- To shrink the upfront catalog, add
`"REA_MCP_INPUT_SCHEMA_PROFILE": "compact"` to the `env` object of the
`mcpServers.rea` entry in `~/.claude.json` (`$CLAUDE_CONFIG_DIR/.claude.json`
when that variable is set), then restart Claude Code. Setup keeps this
override.
The sizes above come from REA's own `tools/list`. A live Claude Code session
against DeepSeek's API is unverified.
## Pi
For [Pi](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/mcp.md),
setup writes a `type: "stdio"` entry under `mcpServers.rea` in the user-level
`~/.pi/agent/mcp.json` and installs the bundled skill under `~/.agents/skills`.
Use `rea setup --client pi --dry-run --json` to inspect the plan, then
`rea setup --client pi --yes --json` to approve it. Check the registration with
`rea doctor --client pi --json`. Pi reads `mcp.json` as strict JSON, like its
own loader: comments, trailing commas, a byte-order mark, or an empty existing
file are invalid, and setup reports them instead of rewriting the file. Repair
such a file to plain JSON first, then rerun setup.
Setup follows Pi's `PI_CODING_AGENT_DIR`: unset or empty selects the default;
`~` and `~/` expand to the home directory; absolute paths and file URLs select
that directory; relative paths stay relative to the command's working directory.
On Windows, native paths, `~\`, and Git Bash/MSYS, Cygwin, and WSL drive paths
are normalized as Pi does. Run REA and Pi from the same working directory when
using a relative override. Pi has no profiles: `OMP_PROFILE`, `PI_PROFILE`,
`PI_CONFIG_DIR`, and OMP's `enabledServers`/`disabledServers` lists do not affect
Pi registration. Doctor accepts an omitted `type` for stdio but reports a
non-stdio type as invalid; `enabled: false` stays disabled.
REA configures only the user scope. Pi also reads `.pi/mcp.json` in trusted
projects; a same-name project entry can replace the user entry or override its
enabled state and exposure. Check that file if the user registration is aligned
but unavailable in a project. An extension that registers `/mcp` can replace
Pi's built-in MCP support and use its own configuration instead. Run `/reload`
in an existing Pi session after changing servers outside the session.
## Qwen Code
For Qwen Code, setup registers `rea` in the `mcpServers` table of the
user-level `~/.qwen/settings.json`, or `$QWEN_HOME/settings.json` when configured.
Setup and doctor follow Qwen Code's tilde and working-directory-relative home
overrides. Qwen Code also discovers personal skills in `~/.agents/skills`,
where setup installs the bundled workflow.
## Antigravity
Antigravity 2.0 discovers personal skills in `~/.gemini/config/skills`.
Setup installs its selected skill copy there.
## Gemini CLI
Gemini CLI uses `$GEMINI_CLI_HOME/.gemini/settings.json` when that home override
is nonempty, including its shared personal skills at
`$GEMINI_CLI_HOME/.agents/skills`. Setup and doctor check MCP allow/exclude
policies from system defaults, user settings, trusted workspace settings, and
system overrides. Workspace trust follows `GEMINI_CLI_TRUST_WORKSPACE`,
`GEMINI_RESTRICTED_MODE`, the effective `security.folderTrust.enabled` setting,
and the selected `trustedFolders.json` (including
`GEMINI_CLI_TRUSTED_FOLDERS_PATH`). Settings in an untrusted workspace do not
participate. A workspace or system `mcpServers.rea` replaces the entire user
entry; setup stops if the winning definition conflicts with its planned entry.
Review those files manually: setup never edits administrator/workspace settings
or grants workspace trust. Trust supplied only by a running IDE is outside this
standalone CLI check.
## Codex and Devin
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
For OMP, setup writes a `type: "stdio"` entry to the user-level
`~/.omp/agent/mcp.json`. It follows `PI_CONFIG_DIR` and
`PI_CODING_AGENT_DIR` (relative to the setup working directory), and the profile selected by `OMP_PROFILE` or
`PI_PROFILE` (`~/.omp/profiles/<name>/agent/mcp.json`). Setup also removes
`rea` from that file's `disabledServers` list, which would otherwise hide the
registration. Doctor treats an `enabled: false` entry as active when
`enabledServers` lists `rea`, as OMP does, unless `disabledServers` also lists
it. Run setup under each profile that should load REA.
## Hermes
For Hermes, setup writes a `mcp_servers.rea` entry to `config.yaml`, preserving
comments and unrelated settings. It resolves that file from `HERMES_HOME`, else
from the platform default Hermes itself uses — `%LOCALAPPDATA%\hermes` on
Windows, `~/.hermes` elsewhere — including any `HERMES_DATA_DIR_SUFFIX`. Hermes
connects an entry unless `enabled` is false, so setup states `enabled: true`.
Hermes personal skills install under the active Hermes home's `skills` directory.
Setup, doctor and uninstall follow the root's `active_profile` selection, as
plain Hermes CLI commands do. An explicit `HERMES_HOME` pointing to
`profiles/<name>` selects that named profile directly. An invalid, missing or
deleted sticky profile is reported instead of writing into the default home;
repair the profile or run `hermes profile use default` before retrying.
REA follows `HERMES_HOME` whitespace trimming, environment-variable expansion,
and home expansion before resolving that profile. Setup previews the resolved
configuration and skill destinations; doctor and uninstall use those same paths.
## Qoder CLI
For [Qoder](https://docs.qoder.com/cli/mcp-reference), setup writes
`mcpServers.rea` into the user-level `~/.qoder/settings.json` (the
`QODER_CONFIG_DIR` override is honored). Entries carry `command`, `args`, and
`env`; stdio is the default transport. Qoder CLI discovers personal skills
from `~/.qoder/skills` (following `QODER_CONFIG_DIR` when set), so setup
installs its skill copy there.
## Trae
For [Trae](https://docs.trae.ai/ide/add-mcp-servers), setup writes
`mcpServers.rea` into the user-scope `mcp.json` under Trae's VS Code-style
user directory (`%APPDATA%\Trae\User` on Windows,
`~/Library/Application Support/Trae/User` on macOS, and
`~/.config/Trae/User` elsewhere). Entries carry `command`, `args`, and
`env`; stdio is the default transport. Trae discovers personal skills from
`~/.trae/skills` (`%userprofile%\.trae\skills` on Windows), so setup
installs its skill copy there.
The user-level MCP paths follow the editor's VS Code layout. Trae's official
documentation describes the raw JSON editor without specifying those paths;
loading this registration in Trae remains unverified.
## ZCode
For [ZCode](https://zcode.z.ai/en/docs/mcp-services), setup registers `rea` in the nested `mcp.servers` table of the
user-level `~/.zcode/cli/config.json`. Entries carry `command`, `args`, and
`env` without a transport discriminator. ZCode discovers personal skills from
`~/.zcode/skills` rather than the shared directory, so setup installs its
skill copy there.
ZCode reads the user-scope `~/.agents/mcp.json` fallback only while the native
`.zcode` config defines no servers at all, with no merging. When setup writes
the first native server into an empty table, it copies the fallback's
`mcpServers` entries into the native table so they keep loading, and leaves
the fallback file untouched. Existing REA environment overrides are preserved
when refreshing its command. A malformed or unreadable fallback file fails setup instead of
being silently suppressed; repair or remove it and rerun. ZCode disables a
server with `enable: false` on its entry; doctor reports such a registration
as stale, and rerunning setup removes the flag to repair it. Native configuration
uses strict JSON; setup refuses comments, trailing commas and a BOM rather than
writing a registration ZCode cannot load.
## DeepSeek Harness
DeepSeek Harness registers MCP clients through a Cordis YAML patch sequence
rather than a `mcpServers` object. `rea setup --client dsh` appends (or
replaces) the REA entry in the home patch `$DSH_HOME/cordis.patch.yml`
(`~/.dsh/cordis.patch.yml` when `DSH_HOME` is unset), preserving unrelated
patches and comments. `rea doctor --client dsh` checks that same entry id.
`rea uninstall` removes it by scanning supported clients; uninstall takes no
`--client` flag. The home patch applies to every Harness profile, so the
registration is written once and no per-profile edit is needed. The written
entry is:
```yaml
- insert:
- id: rea-mcp
name: "@deepseek-ai/dsh-mcp-client"
config:
serverName: rea
transport: stdio
command: /absolute/path/to/node
args: ["/absolute/path/to/rea/scripts/rea.mjs", mcp]
```
Setup preserves caller-owned Cordis expressions and replaces launcher fields
with literal values that doctor can verify. It refuses to edit an expression
that produces the entire REA config, or a group-targeted REA insertion. Use a
literal config and a root-level insertion as shown above.
For a global npm installation, the launcher is under
`$(npm root -g)/rea-agents/scripts/rea.mjs`. Restart Harness after setup; it
exposes tools as `mcp__rea__<tool_name>`. Run `rea setup --skill --dry-run`,
review the destination, then `rea setup --skill --yes` to install the workflow
in `~/.agents/skills` (`$DSH_AGENTS_HOME/skills` when configured); Harness
discovers that directory, and its native `skill` tool can load
`reverse-engineer-anything`.
REA's optional [native client verification](testing.md#end-to-end-integration-and-golden-evidence)
checks headless chat, skill loading, all tool input schemas and actual analysis
using the installed Harness and a local model fixture. This establishes the
Harness integration, with live DeepSeek API compatibility remaining unverified.
See the [Harness MCP guide](https://github.com/deepseek-ai/deepseek-harness/blob/639ed015397290b3745d163aafe02ffee4aa3f84/packages/mcp/mcp-client/README.md)
for its native configuration contract.
## Other client settings
For OpenCode, setup writes the V1 `mcp.rea` entry, which OpenCode V1 and V2
both load. If the configuration already uses OpenCode V2's native
`mcp.servers` table, setup registers REA there instead and replaces any earlier
`mcp.rea` entry from REA. Setup honors `OPENCODE_CONFIG_DIR` and
`OPENCODE_CONFIG`, preferring the later-loaded JSONC file when both JSON and
JSONC exist. The ordinary XDG global configuration still participates when a
custom directory is selected. Doctor checks the merged user registration; uninstall removes
REA-owned entries from every applicable user file so an older entry cannot
become active again. Malformed applicable files block setup before changes.
Grok Build loads `[mcp_servers.rea]` from `$GROK_HOME/config.toml`, or from
`~/.grok/config.toml` when `GROK_HOME` is unset or empty. Setup edits that server
table, `[mcp_servers.rea.env]`, and a root `disabled_mcp_servers` entry that
names `rea`. It sets `startup_timeout_sec = 30` and leaves every other name
in that list. The shared skill installed under `~/.agents/skills` is already
on Grok Build's skill path.
Grok Bot (`grok_bot`) is detected from `~/.grokbot`, or from `SAND_DATA_ROOT`
when that value is an absolute path. A relative or empty `SAND_DATA_ROOT`
stays on `~/.grokbot`. That directory is not the connector store. Grok Bot
keeps connectors in the signed-in account and runs them on its hosted
computer. It does not import `mcp.json` from the data directory, and it does
not attach a stdio server running on this machine. Setup does not call the
account connector API, does not write a registration file, and does not report
the data directory as aligned. Ask the Grok Bot chat to add a custom MCP
server named `rea` that runs on the Bot's computer:
```bash
npx -y rea-agents@<version> mcp
```
Do not put credentials in that command or its arguments. `rea doctor --client grok_bot`
reports this manual step. `rea uninstall` does not remove the account connector.
-517
View File
@@ -1,517 +0,0 @@
# Client and agent verification
Use these optional lanes to verify an installed client or evaluate an agent's
REA workflow. [Testing REA](testing.md) provides the normal development commands
and provider lanes. Each record below states its host, client version, model
fixture, and remaining coverage; a native-client run with a loopback model does
not establish live model-service acceptance.
## End-to-end, integration and golden evidence
The optional `verify:qwen-client`, `verify:pi-client`, and `verify:hermes-client`
lanes require an installed native client. Select its executable with
`REA_VERIFY_QWEN_COMMAND`, `REA_VERIFY_PI_COMMAND`, or `REA_VERIFY_HERMES_COMMAND`.
They configure disposable profiles through the public REA CLI, preserve caller
settings and backups, and exercise real stdio MCP calls and skill loading. The
`call` mode checks complete catalog discovery and actual JavaScript Evidence;
pass `-- chat` to check plain chat with REA enabled. Qwen also reads the full
result that its client offloads, and Pi exercises default codemode execution.
Use `REA_VERIFY_RUNTIME_ROOT` to select a production-only installed REA package.
Receipts retain client versions, result digests, host coverage and owned-process
cleanup. These POSIX lanes use a deterministic loopback model, so they do not
prove live model-provider or native Windows compatibility. Qwen, Pi and Hermes
bind both `HOME` and `USERPROFILE` to the disposable account. Qwen and Pi discover
the shared personal skill through their default search paths without an explicit
skill setting; Hermes discovers it through the selected `HERMES_HOME`.
Set `REA_VERIFY_HERMES_STICKY_PROFILE=1` to exercise native Hermes selection of
a named sticky profile with `HERMES_HOME` still pointing to its root.
`verify:gemini-client` requires an installed Gemini CLI (verified with
`@google/gemini-cli@0.63.0` on POSIX and native Windows); select it with
`REA_VERIFY_GEMINI_COMMAND`. A selected `.js`, `.mjs` or `.cjs` entry point runs
under the verifier's Node. On Windows, select the npm install's
`node_modules/@google/gemini-cli/bundle/gemini.js`, because only a `gemini.cmd`
shim reaches `PATH`.
The optional lane uses native `GEMINI_CLI_HOME` discovery in an isolated
Git project, checks setup plans, backups and idempotence, activates the installed
personal skill, validates all forwarded input JSON Schemas against their declared
dialect, forwards the complete REA catalog and checks full JavaScript
Evidence for a Unicode path. Use `-- chat` for ordinary chat with REA enabled,
or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed REA package.
The local fixture exercises the real Gemini API adapter, including its
`untrusted_context` tool-result envelope. Token counts are synthetic; live
Google API compatibility remains unverified. The lane disables
the client's memory-based relaunch to preserve the caller's Node heap budget.
`verify:opencode-client` requires an installed OpenCode (verified with
`opencode-ai@1.18.35`); select it with `REA_VERIFY_OPENCODE_COMMAND`.
The optional POSIX lane configures isolated XDG roots and `OPENCODE_CONFIG_DIR`,
checks setup plans, backups, preserved JSONC comments and idempotence, activates
the installed skill, validates all forwarded input schemas and verifies complete
JavaScript Evidence for a Unicode path. JSONC is the default fixture; set
`REA_VERIFY_OPENCODE_CONFIG_FORMAT=json` for JSON. Use `-- chat` for ordinary
chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The native core runs with external plugins disabled through `OPENCODE_PURE`;
the local OpenAI-compatible fixture has a caller-declared one-million-token
context and synthetic usage. Skills use an explicit isolated `skills.paths`
directory, so default OS-home discovery remains unverified. Live model APIs and
native Windows are also unverified.
`verify:claude-client` requires installed Claude Code (verified with
`@anthropic-ai/claude-code@2.1.296` on POSIX and native Windows); select it
with `REA_VERIFY_CLAUDE_COMMAND`. On Windows, select
`claude.exe`: npm installs put only a `claude.cmd` shim on `PATH`, and the real
executable is under `node_modules/@anthropic-ai/claude-code/bin`.
The optional lane uses native `CLAUDE_CONFIG_DIR` discovery, an independent
Git workspace, user settings and default built-in tools. It preserves caller
preferences and backups, checks idempotent setup, waits through the native
`WaitForMcpServers` tool when discovery is pending, and validates the complete
catalog and forwarded input schemas. Call mode loads the personal skill through
native `Skill`, checks its full body and verifies named-schema JavaScript Evidence
for a Unicode path. Use `-- chat` for ordinary chat with REA enabled, or
`REA_VERIFY_RUNTIME_ROOT` for a production-only installed package. The local
Anthropic Messages/SSE fixture preserves native resource-hint envelopes in its
request artifacts. Usage is synthetic; live Anthropic API and bare-mode
personal-skill activation remain unverified by this lane.
`verify:copilot-client` requires installed GitHub Copilot CLI (verified with
`@github/copilot@1.0.95`); select it with `REA_VERIFY_COPILOT_COMMAND`.
The optional POSIX lane uses native `COPILOT_HOME` discovery, an independent
Git workspace, guarded setup plans, preserved registrations, backups and
idempotence. Native `skill add` registers the isolated installed skill; call
mode loads its full body, validates all forwarded input schemas and checks
named-schema JavaScript Evidence for a Unicode path. When Copilot spills a
large MCP result, the model requests native `view` with `forceReadLargeFiles`
and validates the complete returned Evidence rather than its preview.
Use `-- chat` for ordinary
chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The native offline BYOK adapter uses a loopback OpenAI completions/SSE fixture
and `gpt-5.4` model metadata; model inference and token usage are synthetic.
Set `REA_VERIFY_COPILOT_MODEL` to examine another client model ID and
`REA_VERIFY_COPILOT_WIRE_MODEL` for its backend model name (defaults to the client
ID). Every actual HTTP request's model is checked and recorded separately.
Both `HOME` and `USERPROFILE` point to the disposable account; native `skill add`
still selects the installed skill directory explicitly.
The same native client passed full-profile chat and analysis with the actual
wire model `gpt-4.1` under a distinct BYOK model ID:
```bash
REA_VERIFY_COPILOT_MODEL=rea-gpt-4.1 REA_VERIFY_COPILOT_WIRE_MODEL=gpt-4.1 npm run verify:copilot-client -- chat
REA_VERIFY_COPILOT_MODEL=rea-gpt-4.1 REA_VERIFY_COPILOT_WIRE_MODEL=gpt-4.1 npm run verify:copilot-client -- call
```
These runs retain full canonical input/output schemas, all tools, installed-skill
loading and complete Evidence readback. They use the fixture's requested
one-million-token BYOK prompt setting; effective capacity and live API acceptance
remain unknown. With the built-in `gpt-4.1` model ID, the verified client still
blocks the full input-schema profile before HTTP with
`compaction_static_context_blocked`, even when requesting a larger BYOK prompt
capacity. The effective capacity is unknown. The default verifier preserves
the complete catalog and full schemas. To verify the existing compact profile:
```bash
REA_VERIFY_COPILOT_MODEL=gpt-4.1 REA_VERIFY_COPILOT_SCHEMA_PROFILE=compact npm run verify:copilot-client -- chat
REA_VERIFY_COPILOT_MODEL=gpt-4.1 REA_VERIFY_COPILOT_SCHEMA_PROFILE=compact npm run verify:copilot-client -- call
```
Both native workflows passed with the complete tool inventory. The verifier selects the
profile only in its disposable Copilot registration and records it in the
receipt. Compact advertisements can reduce nested validation structure; the
server still validates complete canonical inputs. This is a tested alternate
workflow, not a fix for the full-profile client/model limit tracked in #1554.
Live model APIs, native Windows and default OS-home skill discovery remain
unverified.
`verify:grok-client` requires installed Grok Build (verified with the official
Linux x64 1.0.50 binary); select it with `REA_VERIFY_GROK_COMMAND`. This optional
POSIX lane isolates `GROK_HOME`, an independent Git workspace and additional
skill roots, disables foreign configuration discovery, guards setup writes,
preserves unrelated registrations/backups and checks idempotence. Call mode
loads the full skill through native `read_file`, queries all REA names and input
schemas through native `search_tool`, and calls analysis through `use_tool`.
If discovery reports `partial`, the native agent diagnoses REA registration and
retries discovery. No startup-timeout override or fixed readiness delay is used.
A larger Unicode-path fixture exercises native result offloading: the full
retained Evidence is validated against its named schema, then native terminal
queries recover the selected export facts, subject and full artifact digest in
the next model request. This verifies useful artifact recovery without claiming
that every offloaded graph fact enters model context. Native line-number and
truncation envelopes remain in the request artifacts. Use `-- chat` for ordinary
chat, or `REA_VERIFY_RUNTIME_ROOT` for a production-only installed package.
The loopback OpenAI completions/SSE custom model declares a one-million-token
context and synthetic usage. Live xAI APIs, native Windows and default OS-home
skill discovery remain unverified.
`verify:commandcode-client` requires installed Command Code (verified with npm
1.79.2); select it with `REA_VERIFY_COMMANDCODE_COMMAND`. Auth, MCP tokens and
sessions use the actual OS home, so provision a disposable POSIX account rather
than overriding `HOME`. Set `REA_VERIFY_COMMANDCODE_ACCOUNT_HOME` to that account's
actual home and create `.rea-client-verification` there with exactly
`Disposable REA client verification account` followed by a newline. The lane
owns that account's `.commandcode` configuration and shared REA skill. Build the
runtime as the checkout owner, then run `node scripts/verify-commandcode-client.mjs`
as the disposable account; the npm shortcut also needs a writable checkout.
The verifier does not create accounts or install clients. It guards setup
targets, preserves an unrelated registration and backups, checks idempotence,
and verifies native default shared-skill discovery and complete activation.
Default deferred-schema delivery stays enabled: the native prompt advertises
every REA tool, exact-name `search_tools` returns every input schema, and a native
shell query recovers the saved catalog's count and digest when the client spills
it. Actual analysis of a Unicode-path fixture delivers full named-schema Evidence
to the next model request. Use `-- chat` for ordinary chat or
`REA_VERIFY_RUNTIME_ROOT` for a production-only installed package. The loopback
OpenAI completions/SSE model is a keyless BYOK endpoint declaring a million-token
context with synthetic usage. A synthetic account-key value satisfies the
client's print-mode gate; native local-only mode refuses hosted API calls.
Updates, telemetry and cron are disabled. Hosted authentication, live models
and Windows remain unverified.
`verify:omp-client` requires installed OMP (verified with the official Linux x64
18.8.7 binary); select it with `REA_VERIFY_OMP_COMMAND`. This optional POSIX lane
isolates the default agent, global config and XDG roots, guards setup targets,
preserves unrelated registrations and backups, and checks idempotence. It
compares native rejection of an invalid profile with REA's refusal to plan
fallback writes. OMP's default `xd://` interface mounts the complete REA catalog
as devices: call mode reads the complete installed skill and tool documentation,
then dispatches analysis through native `write`. It checks full named-schema
JavaScript Evidence with a Unicode path in the next model request. Device
metadata and documentation are distinct from forwarding all JSON schemas as
model functions. Native print-mode MCP readiness uses its defaults.
Use `-- chat` for ordinary chat or `REA_VERIFY_RUNTIME_ROOT` for a production-only
installed package. The loopback OpenAI completions/SSE model fixture declares a
one-million-token context and synthetic usage. Live model APIs, native Windows,
named-profile native execution and default OS-home skill discovery are
unverified; skill discovery uses an explicit isolated custom directory.
`verify:deepseek-client` requires an installed DeepSeek Harness (`dsh`;
verified with `@deepseek-ai/dsh@0.2.0-rc.2`) and Git. Set
`REA_VERIFY_DEEPSEEK_COMMAND` to select its executable. This optional POSIX lane
seeds caller model settings and a stale Cordis registration in an isolated
`DSH_HOME`, then runs public `setup --client dsh` dry-run, setup, repeated setup,
and scoped doctor. It checks the backup and unrelated patches before booting
Harness with the generated registration. After native execution it uninstalls
through the public CLI and checks that only caller patches remain. `HOME` and
`USERPROFILE` point to the disposable account. The native default
`~/.agents/skills` search path discovers
the installed skill without a `DSH_AGENTS_HOME` override. A separate Git root prevents inherited project skills from
masking a missing installation. The default `call` mode checks skill loading,
complete catalog discovery, the actual forwarded input schemas and regexes,
and full JavaScript Evidence for a Unicode path. Use `-- chat` for ordinary
chat with REA enabled, or `REA_VERIFY_RUNTIME_ROOT` for an installed package.
The fixture uses Harness's custom OpenAI adapter and the one-million-token
context capacity declared by its default DeepSeek Flash model; it does not
establish live DeepSeek API or native Windows coverage. Receipts include
request artifacts, result digests and owned-process lineage.
The DSH acceptance journey also exercises public setup, approval, doctor,
generated-launcher MCP startup and uninstall without an installed Harness.
That journey proves REA workflow behavior, not native Cordis expression
evaluation. Filesystem regressions retain tagged values and unrelated rows
across alias dependencies and check refusal of unsafe YAML without mutation.
Full E2E tests invoke the production command dispatcher and real providers,
without fake launchers, runners or responses. `verify:keyed-archive` writes
Foundation binary, XML, and integer archives using one run-owned Swift module
cache. It checks CLI and separate stdio MCP parity, pagination, escaping-path
rejection, an XML graph golden, and numeric meaning for safe controls, unsafe
integers, boxed numbers, and integral-valued reals. `verify:asset-catalog`
compiles source-owned colors with
`actool`, invokes real `assetutil`, then checks CLI/MCP results, exact catalog
digest, every raw metadata field, pagination and malformed input rejection.
Neither artifact workflow requires Hopper or launches it. Both run in macOS CI.
`verify:macos-bundle` needs only macOS with Command Line Tools. It compiles a
source-owned app with `clang`: a versioned framework, XPC services, an app
extension, a login item, a privileged helper, launchd plists, and a helper tool,
signed ad hoc. It packs the app as a directory, a `ditto` ZIP, and an APFS DMG,
then checks that `inspect-artifact` plus `project-apple-application-graph`
report the same bundle anatomy for all three through the CLI, with stdio MCP
parity. It also checks that the DMG is detached afterwards. The same app
covers `trace-dylib-resolution`:
- each resolution status and finding, with CLI/MCP parity;
- for every traced image, dependencies, rpaths, and install names equal to
`otool -l`;
- for the main executable and an XPC service, a predicted load order equal to
the images dyld actually loads under `DYLD_PRINT_LIBRARIES`.
The lane also compiles executable/library pairs with empty embedded directory,
versioned-path, and suffix settings. It checks present and removed dependencies
through CLI and MCP, and compares actual `DYLD_PRINT_SEARCHING` diagnostics for
root-level candidates. These cases distinguish an empty search directory from
an empty versioned scan or a suffix that only repeats the original path.
It runs in macOS CI.
Prepare the native inspector before cases that measure producer output or exit
behavior; keep startup deadlines and cancellation in distinct cases. Run real
process-capture verification separately from package or build checks. On macOS,
new npm processes can become token-unreadable after changing their display
title and prevent verified cleanup during a capture's ownership sweep.
MCP SDK transport tests with recording providers remain integration tests.
They are useful for schema drift and failure projection but do not prove that
Hopper, Ghidra or another substituted engine works. `verify:package` proves
packaging/install behavior and fake-provider integration; use the corresponding
real-provider lanes for engine claims. Packed-bridge checks verify shipped files and Python syntax.
Real Apple dispatch and Interface
Builder verifiers currently prove format integration through production readers.
`verify:hopper` exercises an installed Hopper through the production stdio MCP
server and CLI. It checks source-owned call chains, CFG edges, references and
complete large inventories, then probes unnamed bookmarks, annotation clearing,
batch validation before mutation, malformed addresses and regexes, segment-end
partial reads, and synthetic file-offset rejection. Advertised schemas are
validated in their JSON Schema dialect and successful replies are checked against
their advertised output schemas. Navigation checks cover interior-object cursor
readback and mapped-memory boundaries. Annotation probes verify invalid native
text and duplicate destinations/names before mutation, preserve unselected label
owners, and exercise explicit batch label swaps. Function locals retain observed
names and stack displacements. Graph probes check symbol/interior-address parity
and a source-owned recursive cycle; literal tracing preserves complete queries
and whitespace. Disposable binary copies prove that switching and closing
actually removes the native document, and that CLI byte, function-dossier,
literal-trace results and invalid-address diagnostics agree with MCP.
No provider is mocked in this lane.
Real search probes cover Unicode names, literal metacharacters, case and regex
modes, annotation cache invalidation, complete native fragments of long literals
checked against byte reads, escaped UTF-8/control text, byte-preserving Latin-1
decoding, and Hopper's UTF-16 symbol-name truncation boundary. It verifies native
CallReference classifications across reference and dossier results, retains long
string fragment metadata in dossiers, and exercises pathological regex deadline
and cancellation followed by successful requests in the same native session. When the macOS
Objective-C fixture is present, the lane also verifies native UTF-16 string objects
and their inferred encodings against their actual bytes. Native terminal calls
are checked across reference, instruction, assembly, block-range and procedure-length
projections; block endpoints are normalized using actual native membership.
Exact Objective-C names also exercise named CLI selectors for function, instruction,
decompilation, reference and search operations. A literal `--help` trace query proves
that selector data is preserved independently of global CLI flags.
Unmapped annotation destinations and
oversized later batch names fail before any earlier edit is applied.
`verify:hopper:deadlines` checks the native client's optional request deadlines
on macOS with an owned source-built fixture. Zero and elapsed deadlines must
leave native comments unchanged, including when a synchronous progress observer
delays timer dispatch. It also observes a short analysis deadline and verifies
subsequent wire recovery and clean shutdown. Caller timeout does not interrupt
Hopper's synchronous native operation. Socket boundary tests deterministically
cover active and queued expiry, late replies and timer cleanup.
The Linux demo lane remains a separate `verify:hopper:linux` command. Hopper
6.4.2's ELF loader did not recognize the original 4,119-byte literal or three
non-ASCII byte strings in the measured fixtures. The lane retains complete raw
byte checks for those literals through source-owned symbols. Recognition of the
original full-length literal is bound to its exact source address; its decoded
object coverage remains explicitly unverified on Linux even when recognized.
Absent non-ASCII recognition also reports decoded-object coverage as unverified.
Recognized non-ASCII and control-text objects must still match their source
bytes, encoding, filters and searches.
A separate 548-byte ASCII literal requires native fragmentation, shortened
provider display, complete decoded fragments and dossier provenance on Linux;
the macOS lane retains the original full-length recognition requirement. These
are observed fixture/build capabilities, not universal Hopper length limits.
Its lifecycle checks attempt competing CLI launches for the active target and a
different target, requiring rejection before either can change the owning
MCP session's documents or procedures. Lease boundary tests also preserve
unresponsive or malformed live endpoints while allowing confirmed stale
sockets to recover.
`verify:setup:linux` exercises installation on a clean supported Linux runner as
root. Use a disposable VM: this lane installs Hopper and its Linux runtime
dependencies through the system package manager. Set `REA_VERIFY_SERVER_COMMAND`
to the CLI entrypoint being verified. The command builds and checks source-owned
ELF fixtures before testing the read-only Hopper setup plan, approved
installation, scoped doctor, real CLI/MCP analysis, rejection of a modified
launcher, idempotent setup without requesting a reinstall, and owned child
cleanup. Before installation and after teardown, a clean-runner process scan
also rejects surviving Hopper demo helpers or Xvfb groups, including orphans
whose launcher exited. This scan observes processes without signaling them.
Hopper detection compares executable file identity through `/proc`, covering
alternate or configured launcher paths even after an invoked symlink is removed.
The dedicated runner must have no unrelated Hopper/Xvfb sessions. It requires
the repository's pinned development toolchain and an
existing host C compiler, `file`, `nm`, and `strings`. Use `verify:hopper:linux`
instead when Hopper is already installed.
`verify:hopper:fat` is a separate macOS lane requiring installed Hopper and the
existing Xcode clang/lipo toolchain. It compiles arm64/x86-64 thin executables and
one- and two-slice FAT32 containers, verifies exact/interior address mappings
against bytes in the original files, checks CLI/MCP parity, and checks owned
runtime cleanup. Source byte changes, removal, permission denial (for non-root
callers), and nonregular replacement must retain native partial mapping facts,
reject unverified original-file coordinates,
and recover after restoration. Single-slice FAT cases also relocate the slice
without changing its loaded bytes. `verify:hopper:fat64` additionally checks
FAT64 preparation through Hopper's native Mach-O loader, source-container
mappings, profile identity,
malformed and ambiguous slice rejection, and temporary-image lifetime. Both
lanes have been verified on Hopper 6.1.0-demo; this establishes REA's prepared
FAT64 workflow, not native FAT64-loader support.
Cross-architecture fixture compilation is not required by `verify:hopper`.
Golden tests use immutable captured text inputs with producer/source provenance
under `tests/fixtures/golden/`. Expected results are reviewed for the semantic
claim; capture commands do not automatically approve new expected outputs.
Do not call handcrafted utility output or synthetic binary builders real-data
goldens. Keep unsupported binary layouts and malformed boundaries as targeted
regressions until a real fixture establishes equivalent coverage.
`verify:browser` exercises source-map failure isolation and expanded-output limits through the compiled CLI and stdio MCP with real Chrome. It also submits five 2 MiB source-map annotations, checks retained script identities and explicit map omissions, and closes its owned fixture target. Replacement and document-reset behavior has separate producer-boundary coverage.
The raw Chrome fixture launchers use `--password-store=basic` so Linux startup
does not wait for an unlock prompt from a reachable but locked desktop keyring.
Such a stall leaves the initial page unloaded with empty or placeholder CDP URLs;
it does not establish permission to capture that page. See
[the keyring diagnosis](https://github.com/morluto/rea/issues/1384#issuecomment-6093781686).
`verify:browser` also captures a source-owned noise canvas as a real PNG above
8 MiB through the CLI and stdio MCP, with complete byte/digest parity and real PNG
decoding. Its SDK client explicitly permits the larger inline JSON response;
this lane does not establish large image-comparison request transport coverage.
The scenario checks read locale, timezone, device scale and viewport dimensions
from actual page JavaScript through CLI and stdio MCP DOM captures. They also
verify that attached-page emulation is released after success, initialization
failure, action failure and cancellation while the external target stays open.
`verify:browser:network` is a focused real-browser lane for transaction identity,
selected request/response bytes, binary and compressed responses, duplicate
headers, credential and declared-secret redaction, redirects, streaming cutoff,
CLI/MCP parity, and owned-profile cleanup. Set `REA_BROWSER_EXECUTABLE` to an
installed Chrome-family browser. An optional script argument selects an already
installed package's `scripts/rea.mjs` entry point for packaged-artifact checks.
The complete `verify:browser` lane includes these same checks.
After building, `verify:browser:dom` checks empty and HTML-whitespace form
destinations against a native Chrome DOM-property oracle through CLI and stdio
MCP. It requires `REA_BROWSER_EXECUTABLE` and accepts an optional installed REA
entrypoint. The full browser lane includes the same public-adapter assertions
before other fixtures navigate the selected page.
`verify:browser:scripts` checks active script capture → exact-byte export →
existing static JavaScript analysis through CLI and stdio MCP, including
manifest readback, competing query variants, and resolved relative imports.
It uses an installed browser and accepts an optional installed REA entrypoint.
The complete `verify:browser` lane also exercises passive script export through
both public adapters. See [website script export](website-script-export.md).
`verify:browser:modules` compares CLI and stdio MCP traces against an independent
real Chromium module-loading fixture: import-map scopes, package prefixes,
null/backtracking rejection, query/fragment identities, repeated module instances,
lazy and computed unknowns, exact source/map identities and no implicit refetch.
Set `REA_BROWSER_EXECUTABLE`; the optional script argument selects an installed
package entrypoint. The complete `verify:browser` lane and existing conditional
Chrome CI include this verifier. See [module relationships](website-module-trace.md).
## Agent evaluation and conformance records
Evaluate native, JavaScript, managed and browser investigation tasks through a
real local Codex CLI with:
```bash
npm run verify:agent
```
The lane runs scenarios sequentially in standalone Codex (`--no-daemon`) with a
disposable HOME and CODEX_HOME under `~/.cache/rea-agent-evaluations/`. Set
`REA_AGENT_EVAL_ROOT` to choose another parent directory outside the OS temporary
directory: current Codex refuses helper aliases under `/tmp`, preventing shell
commands and skill reads even if MCP works. Each owned run directory is removed
after verification unless fixture retention is requested. The lane
installs the packaged skill and MCP registration through public `rea setup`,
rather than copying a skill into a project that also inherits the caller's
skills and configuration. Only authentication is copied, when present, and it
is removed even with `REA_AGENT_EVAL_KEEP_FIXTURES=true`. No user configuration,
rules, plugins or history is copied; shell snapshots and additional agents are
disabled. Existing API-key environment authentication remains available.
The native missing-provider scenario preapproves only `open_binary` and
`close_binary` in the disposable client so it reaches REA's actual provider
boundary instead of stopping at Codex approval. This does not validate a real
native engine or authorize arbitrary runtime execution.
Select a smaller run with `REA_AGENT_EVAL_SCENARIOS`, a comma-separated list of
scenario IDs. `asar-zh` exercises the packaged desktop rubric from a Chinese
request. `javascript-module-view` exercises summary analysis, module paging and
item inspection in a tree with unrelated modules; its routing and text checks
remain heuristic, so review the retained transcript for selector choice and
coverage claims. Set `REA_CODEX_CLI` to an installed Codex executable and
`REA_AGENT_EVAL_MODEL` to an account-supported model. Use an external resource
limit for the whole process tree when testing on a constrained host; a Node
heap limit alone does not bound client and child-process memory.
`missing-target` leaves desktop fixtures visible without selecting one in the
request. It requires zero REA calls and a structured request for an app name or
artifact path. Its `expectedFirstTool` is `null`, and
`targetClarificationPassed` grades that limited routing outcome independently
of analysis prose heuristics. Analyzing a nearby example cannot pass this case.
The packaged desktop and parser-comparison scenarios now assess a closed set of
known fixture claims. Each final answer must be a strict JSON manifest containing
exactly the requested claim IDs, values, Evidence IDs, and Evidence authority and
confidence. Golden values are not included in the prompt. The evaluator checks
exact values against both the fixture oracle and authenticated successful REA
results; an Evidence ID by itself is insufficient. Missing, duplicate, extra,
contradictory, incorrectly sourced, or unsupported claims fail the scenario.
The desktop rubric covers the exposed bridge API and members, renderer and main
IPC operations, and the resolved preload. It binds its Evidence to the exact
packaged artifact path and SHA-256. The parser rubric checks the precise heading
depth addition, discriminant, complete comparison counts, and the explicit limit
on runtime semantics. Its comparison must link to the two delivered source
analyses and use the requested module and export selectors. Boundary tests package
the same source-owned desktop fixture and compare the same source-owned parser
files through actual MCP tool results, then verify that fabricated answers fail.
Per-scenario `factualCorrectness` is `passed`, `failed`, or `not_assessed` within
the `configured_fixture_claims` scope. A pass establishes only the configured
claims, not unrestricted factual correctness. Native, managed, browser,
navigation-context, and address-context scenarios have no factual rubric and
remain `not_assessed`; the managed workflow requires both artifact and member
inspection to answer its type and entry-point question.
The closed factual scenarios request complete producer Evidence on the initial
analysis so their source selectors can authenticate all configured facts.
Summary/page/item workflows are exercised separately by `javascript-module-view`;
its heuristic gate does not establish full-producer factual correctness.
All scenarios retain routing, workflow, validation, repetition, process-exit,
and token-use gates. Configured factual scenarios additionally require a factual
pass. Their answer-text heuristics are diagnostic and do not affect the gate.
Validation counts include complete text-only REA `invalid_request` envelopes
and failed SDK calls whose arguments violate the named current REA contract.
Client approval rejections and provider unavailability remain distinct failures;
truncated JSON previews are not parsed into invented error codes.
Repeated `binary_session` observations separated by a successful `open_binary`
or `close_binary` are treated as lifecycle verification. An unchanged retry,
including one after a failed lifecycle call, still counts as repetition.
Scenarios without a rubric retain the legacy text-heuristic gate.
`answerTermCoverageMet` checks case-insensitive substrings,
`epistemicCuePresent` checks keywords, and `finalCitesEvidence` checks only an ID's
presence. These metrics can still accept fabricated prose and must not be read
as factual assessments. Set `REA_AGENT_EVAL_TRANSCRIPT_DIR` to retain complete
tool results and final answers for review.
Report schema version 4 adds negative routing scenarios with nullable
`expectedFirstTool` and a `targetClarificationPassed` outcome. Consumers must
allow an expected absence of REA calls; this does not make an analysis scenario
pass without its required tools. Version 3 changed the top-level
`factualCorrectness` from a constant
string to an assessment summary with status, scope, and assessed/passed/failed/
not-assessed scenario counts. Scenario records include the factual assessment and
configured claim IDs. The evaluation scope is
`routing_workflow_and_configured_fixture_claims`. Update report consumers for
these changes. The narrower heuristic field names introduced in version 2 remain:
`answerHeuristicsMet`, `epistemicCuePresent`, `answerTermCoverageMet`, and
`requiredAnswerTermGroups`.
Regenerate the managed conformance manifest and Evidence completion ledger from
live verification results, or check them for drift:
```bash
npm run evidence:generate
npm run evidence:check
```
The records preserve unsupported and unverified coverage as explicit unknowns.
Run the matching real-tool prerequisites described in this guide.
+1 -44
View File
@@ -35,7 +35,7 @@ license](https://github.com/morluto/rea/blob/main/third_party/evmole/README.md)
and whitespace. Decoded-byte SHA-256 identifies actual selected EVM bytes.
Neither digest is the Ethereum Keccak code hash.
- Full bytecode, upstream function offsets and original producer representation
are returned inline by default. Offsets are byte positions in decoded bytecode.
are returned inline. Offsets are byte positions in decoded bytecode.
- Upstream also returns terminal metadata during selector recovery. Its reported
values remain in `raw_result`; integer precision and non-text-key coverage are
unknown in the JS binding. Full bytecode retains the original encoded metadata.
@@ -47,49 +47,6 @@ license](https://github.com/morluto/rea/blob/main/third_party/evmole/README.md)
- Analysis is offline: no target runtime execution, implicit chain/RPC/explorer
lookup, wallet action, transaction broadcast or network request.
## Selected interface delivery and retained views
Existing CLI calls and MCP calls with omitted or `complete` detail keep the
complete inline result. On a retaining MCP server, select `detail: "summary"`
when the question needs every inferred function and its identity/uncertainty,
without bytecode text or duplicated raw stdout:
```json
{
"name": "inspect_evm_interface",
"arguments": {
"path": "/artifacts/runtime.hex",
"encoding": "hex",
"detail": "summary"
}
}
```
The result is distinct derived Evidence linked to its complete parent. Its
`normalized_result.summary` preserves every producer-returned selector, decoded
byte offset, dispatch, argument/mutability string including null, carrier/decoded
identities, original limitations and explicit unknowns. Payload `evidence_kind`
remains `inferred`. It preserves stderr/truncation and records stdout text length.
Complete-within-view coverage covers returned candidates; discovery completeness
remains unknown even for an empty or exhausted collection. Analysis still runs;
delivery selection does not save interpreter work or change source parameters.
Use `normalized_result.parent_evidence_id` with `inspect_analysis_view` source
kind `retained-evidence`. EVM view kind `evm` pages `functions` by original row
order, or `bytecode_hex`, `stdout`, `stderr` by UTF-16 code units. Hex pages preserve
the original lowercase text without a prefix; two characters represent one decoded
byte. A text-page offset differs from a function's decoded-byte offset. Complete
parent Evidence remains accessible through the normal ledger/export workflow;
reading views does not rerun analysis or change its identity. Existing record
retention and close semantics are unchanged.
Portable historical complete EVM Evidence can use source kind `inline` without
a provider. A fixed server without Evidence retention rejects selected summary
delivery before starting analysis and continues to support complete delivery.
Discover the actual advertised schema before sending `detail` to an older server;
use its complete operation when an equivalent workflow is required. The one-shot
CLI keeps its existing complete result.
## Resource and lifecycle limits
Inputs are limited to 4 MiB, complete replies to 16 MiB and combined diagnostic
+2 -4
View File
@@ -123,10 +123,8 @@ Select a verified native child for the existing tools:
```
Then use `analyze_function`, `inspect_native_api` or the other native primitives.
Native architecture and executable validation still apply. Generic
[MIPS ELF](ghidra-mips.md) and [RISC-V ELF](ghidra-riscv.md) lanes are separate
documents with their own admission boundaries. This milestone does
not add PPC decompilation, raw flash load profiles, bootloader/device
Native architecture and executable validation still apply. This milestone does
not add MIPS/PPC/RISC-V decompilation, raw flash load profiles, bootloader/device
tree semantics, vulnerability scanning, emulation or hardware runtime capture.
## Resource and lifecycle policy
-176
View File
@@ -1,176 +0,0 @@
# Flutter build identification
REA identifies a Flutter app's build facts by **pure parsing** of its APK:
the Dart VM snapshot hash, per-ABI library digests, the engine's GNU
build-id, and any labeled version strings. No engine, no tool installation,
no execution, and no external lookups — this family answers "which Dart SDK
build is this, and what exactly is in the payload?" before any deeper
native analysis.
This is the triage step for Flutter reversing: the snapshot hash is the
artifact that maps to a Dart SDK release through an external dataset (such
as the one reFlutter maintains), and knowing the SDK version is what makes
SDK-layout-specific snapshot parsers applicable.
## Answer an analyst question
```sh
rea identify-flutter-build /targets/Example.apk
rea inspect-dart-aot /targets/Example.apk
rea inspect-dart-aot /targets/Example.apk --abi armeabi-v7a
```
The equivalent MCP methods are `identify_flutter_build` (with `path`) and
`inspect_dart_aot` (with `path` and an optional `abi`; the default prefers
arm64-v8a, then x86_64, then x86, then armeabi-v7a, then the remaining
ABIs alphabetically).
## Optional retained AOT delivery
MCP `inspect_dart_aot` keeps complete output when `detail` is omitted or
`"complete"`. Explicit `detail: "summary"` returns the selected target/ABI/library
identity, all snapshot headers, structural coverage, string-pool coverage and
original lower-bound counts without the string lists. It retains complete source
Evidence and returns a distinct linked `inspect_analysis_view` summary. Analysis
and the caller's ABI choice are unchanged; one-shot CLI output stays complete.
Use `normalized_result.parent_evidence_id` as the retained source for
`inspect_analysis_view`, with `view: {kind: "dart-aot", collection: "package_uris",
offset: 0, limit: 64}`. Collections are `package_uris`, `dart_uris` and
`class_like_tokens`. Pages preserve the original strings and order, selected ABI,
library identity and source coverage. `returned_counts` describe producer-returned
rows; counts ending in `_at_least` remain lower bounds. Exhausting a page sequence
does not make a partial pool complete or turn byte-pattern tokens into typed
classes/functions. Views do not reopen the APK. Original Evidence remains
exportable under its existing session lifetime. Summary requires a retaining
server; older servers keep the complete request after schema discovery.
## What the AOT inspection returns
`inspect_dart_aot` reads one ABI's `libapp.so` in full and reports:
- **Snapshot sections** — the four `_kDart*Snapshot*` symbols located
through the ELF **dynamic symbol table** (ELF32 and ELF64, little-endian,
every read bounds-checked), each with file offset, size, and — for data
sections, which carry the `f5f5dcdc` magic — the parsed header kind and
length (the stored length excludes the four magic bytes). Data headers
whose declared snapshot length does not fit their symbol retain their
observed fields and report partial coverage. Complete structural coverage
currently requires kind 3, the FullAOT value in the supported
[Dart 2.14 layout](https://github.com/dart-lang/sdk/blob/2.14.0/runtime/vm/snapshot.h).
Kind numbers vary across Dart releases; other values are preserved with
partial coverage, without guessing their interpretation.
A payload without exported snapshot symbols is refused rather
than guessed at.
- **The snapshot hash** from the header at the start of each exported data
symbol. Complete hash coverage requires a valid header from both the VM
and isolate; duplicate records inside one symbol cannot stand in for the
other's header. Aliased or overlapping data symbols report partial coverage.
- **A string-pool projection from the isolate data section**: distinct
`package:` source URIs (the app's own and its dependencies' Dart files —
a dependency inventory), `dart:` SDK URIs (which SDK libraries the app
uses), and identifier-shaped tokens, each bounded with counts and
`coverage: "partial"` when truncated. On the reference target this counts
756 package URIs and 201 dart URIs on arm64-v8a and x86_64, and 212 / 48
on armeabi-v7a, retaining up to 500 of each in the response.
`libapp.coverage` describes structural snapshot checks;
`string_pool.coverage` describes the bounded projection. Overall coverage
is partial when either facet is partial.
## Interpret the result
- **`flutter_detected`** is true when any `lib/<abi>/libapp.so` exists. A
negative answer reports complete coverage: absence is an answer.
- **`snapshot_hash`** is the Dart build hash observed 20 bytes after the
snapshot magic (`f5 f5 dc dc`) inside `libapp.so`. Identification scans
byte patterns; AOT inspection reads the exported VM and isolate headers.
`snapshot_hash_sources` counts the valid records observed by the chosen
operation, and when they **disagree** the distinct values are
kept in `snapshot_hash_candidates` with `snapshot_hash: null` and
`coverage: "partial"` rather than silently picking one.
- **`elf_header_valid`** checks the supported little-endian ELF32/ELF64
header, table entry widths, and full table extents against the library's
actual byte length. Truncated, malformed, or unsupported headers report
false and partial coverage while retaining byte-scanned hashes. This
header check does not establish valid table contents or exported symbols.
- **`libflutter` facts** are per-ABI observations: byte size, SHA-256
digest, GNU build IDs from ELF-declared `PT_NOTE` / `SHT_NOTE` ranges,
and any _labeled_ strings the build
carries. Release engine builds often strip the `Dart VM version` string —
absence is reported as `null`, not guessed. Android clang/LLVM toolchain
lines are reported verbatim as build provenance.
`build_id_candidates` preserves distinct IDs. `build_id` is populated only
when all declared note ranges were examined and one ID was found;
conflicting IDs or malformed/bounded note metadata make coverage partial.
Matching bytes outside declared note ranges cannot supply a build ID.
- Labeled strings must fit their complete grammar. `dart_version_capped`
and `toolchain_capped` independently report labels omitted by grammar or
projection bounds; either makes identification coverage partial. Values
split across read chunks are retained without publishing truncated prefixes.
- **`coverage: "partial"`** also appears when an ABI carries `libapp.so`
without `libflutter.so` (or vice versa).
- The APK itself is digested before parsing, so `target.sha256` binds the
observation to the exact input.
## Limits
- **Owned snapshots.** Both operations copy the admitted APK into a
provider-owned, read-only snapshot before digesting and parsing, so a
concurrently modified original cannot mix into one observation; failed
reader closure and snapshot cleanup are retained and retried on `close()`.
The snapshot is removed only after all owned readers and file descriptors
close successfully. Copying pins one admitted descriptor and compares its
identity, size, mode and timestamps after the copy. Source permission
failures remain `access_denied`, and source identity changes remain
`artifact_changed`. Provider-owned storage failures report a
`resource_constraint` with their native I/O cause. Cancellation is checked
during copying, metadata/symbol walks, string scanning, and after cleanup.
- **Bounded reads.** APK snapshots are bounded at 2 GiB, including while
copying. Identification permits 768 MiB of cumulative library extraction;
declared sizes are checked before extraction. Library reads are bounded at 256 MiB each and ZIP
metadata at 8 MiB; the AOT image buffer is allocated at exactly the
declared size before reading. Exceeded budgets report
`resource_constraint`.
- **Engine notes.** Engine libraries are spooled into the owned root. ELF
headers, note tables and note payloads share an 8 MiB metadata budget;
up to 64 distinct build IDs are retained. Exceeding either bound preserves
the candidates already examined and reports partial coverage.
- **Metadata and candidate capacity.** Both operations refuse duplicate
relevant library paths. Inventory is limited to 32 ABIs and 1024 bytes per
relevant library path, independently of compressed size. Identification
refuses more than 64 distinct snapshot hashes with `resource_constraint`
rather than silently dropping conflicting evidence.
- **Selected ABI.** AOT inspection applies the library budget to the selected
ABI after selection; an oversized unselected library does not block it.
Undefined dynamic-symbol imports are not treated as snapshot exports.
Section-stripped images require a bounded symbol count from `DT_HASH` or
`DT_GNU_HASH`; layouts without either are refused. Symbol names and their
terminators must fit their linked string table.
- REA performs **no hash-to-SDK lookup**: mapping the snapshot hash to a
Dart SDK release requires an external dataset and is deliberately out of
scope for this family.
- The AOT string pool is a **byte-pattern projection, not deserialized
cluster semantics**: typed class and function recovery requires an
SDK-specific parser (the snapshot layout changes per release — exactly
why the hash is the key), and `class_like_tokens` include incidental
matches. JEB's GUI Dart unit and native analysis of `libapp.so` cover
some ground today.
## Real verification
`npm run verify:flutter -- --apk PATH [--plain-apk PATH]` runs both tools
through compiled CLI and stdio MCP, compares Evidence, and checks every ABI.
Use `--expectations scripts/fixtures/flutter-gallery-expectations.json` with
the Gallery 2.9.2 release APK to check exact per-ABI engine labels,
URI counts and the snapshot hash against its pinned SHA-256. The verifier
requires complete structural snapshot coverage on every ABI and explicitly
reports the bounded pool projection as partial/unverified when truncated.
Other APKs need their own expectations file to verify exact engine labels
and URI counts; otherwise those facets are reported unverified.
The optional plain APK checks negative detection. Record: Flutter Gallery 2.9.2 (112 MB, three
ABIs) — every ABI reports the same agreeing hash
`65817c30a78bb44c3dc3771876b6010a` from two snapshot sections, per-ABI
engine build-ids, no labeled Dart version (as expected for a release
engine), and the Android clang toolchain line; a plain aapt2-built APK
reports not-detected with complete coverage. The suite uses self-contained
synthetic ELF images and scanner payloads; it does not read private local files.
-13
View File
@@ -1,13 +0,0 @@
# Frida instrumentation
REA exposes Frida device and process discovery, attach or spawn sessions, and caller-authored JavaScript instrumentation through the CLI and MCP. The Node bindings are an optional package dependency and load only when a Frida operation runs. REA does not install Frida server on a target.
For remote devices, pass a host with an optional port (`host[:port]`; bracket IPv6 addresses) and any token, certificate, origin, or keepalive options on that operation. The keepalive interval is measured in seconds, matching Frida Core 17.23.2. Authentication values are held only for the active call or session and are excluded from Evidence. Do not embed credentials in the endpoint address.
MCP exposes `list_frida_devices`, `list_frida_processes`, `start_frida_session`, `load_frida_script`, `resume_frida_session`, `unload_frida_script`, `frida_session_status`, and `close_frida_session`. A spawned process starts paused so scripts can load first. Closing unloads session scripts and detaches. If a spawn remains paused, REA resumes it only after script cleanup or session detach confirms the instrumentation is released; if both cleanup paths fail, the target stays paused and the cleanup error is retained. REA never kills the target. MCP sessions end with the server process. The one-shot CLI command `instrument-with-frida` accepts one inline script or script file, observes messages for a bounded duration, and returns Evidence with the source hash and captured messages.
Failed startup cleanup retains acquired Frida handles, including a paused spawn that has not attached, for later cleanup retries. Its remote connection stays leased until session detach and target resume complete. CLI commands await provider cleanup before returning; MCP retains these resources for cleanup when its server closes. A failed cleanup remains reported rather than treating an unregistered session as fully released.
Frida scripts execute inside the selected target with that process's memory, filesystem, and network authority. Message capture is bounded to 16 MiB and reports truncation. Script source is not stored in Evidence; its selected path and SHA-256 digest are. Evidence retains non-authentication target selection such as device or endpoint, mode, program or PID, and spawn arguments. Authentication values remain excluded. Results report the observed session and messages, while unsupported platform metadata remains unknown. A request cancelled before a Frida operation starts has no provider effects. If cancellation arrives during a native Frida call, REA waits for that call to return, then closes any session it created and returns the observed session as a partial observation. Cancellation Evidence separately reports whether a target resume was observed, whether instrumentation cleanup completed, and that final target liveness remains unknown. REA does not kill the target. Remote discovery retains its observations and reports a separate cleanup error if the temporary connection cannot be removed.
The [Frida Core API](https://frida.re/docs/frida-core-api/) documents device management, sessions, and script loading; the [JavaScript API](https://frida.re/docs/javascript-api/) documents target-side instrumentation. [Luma](https://luma.frida.re/) is Frida's standalone GUI; REA does not automate or control it. `npm run verify:frida` requires a Linux host with the optional Frida binding and uses a short-lived local Node.js fixture created by the verifier. Add `-- --address HOST:PORT --pid PID` to run the separate remote attach lane against a caller-selected target. Mock tests do not establish real device/server compatibility.
+4 -7
View File
@@ -130,9 +130,8 @@ range's file offset and analysis address; it does not locate the first differing
byte inside that range. Mapping ends are **inclusive**, unlike the exclusive ends
from `list_segments`. Appended overlays remain in source-file identity and are
excluded from initialized module coverage. Uninitialized allocations are reported;
their contents and DOS runtime semantics are not verified. Independent verification
also covers explicit [raw-binary imports](raw-binary.md); other formats return
`unsupported` with measured observations.
their contents and DOS runtime semantics are not verified. Formats other than MZ and explicit COM return
`unsupported` with measured observations, not a successful MZ verification.
`read_bytes` returns initialized provider memory, including loader fixups; an
unmapped or uninitialized byte ends the read with an explicit returned length and
@@ -151,10 +150,8 @@ For a packed executable, importing the original can analyze its unpacking
stub. Analyze a separately prepared unpacked copy to inspect the original
program's recovered code. Retain both artifact digests and the transformation
evidence; REA never silently replaces the admitted target. Appended overlays
are separate from the initialized MZ module. Headerless COM requires the
[explicit COM interpretation](#headerless-com-images); REA does not guess it
from the filename or unrecognized bytes. DOS extenders without an admitted
MZ real-mode entry remain outside this import boundary.
are separate from the initialized MZ module. Raw COM files and DOS extenders
without an admitted MZ real-mode entry are outside this import boundary.
DOS MZ is available through Ghidra, with no Hopper support claim. It is outside
the Windows native PE P0 boundary. macOS x64 DOS verification remains unverified.
-105
View File
@@ -1,105 +0,0 @@
# RISC-V ELF analysis through Ghidra
This lane extends native ELF analysis for `EM_RISCV` targets. It does not
execute RISC-V code, emulate a boot sequence, or rehost firmware. It addresses
[#2063](https://github.com/morluto/rea/issues/2063) and follows the same
lane shape as [generic MIPS support](ghidra-mips.md).
## Admission boundary
ELF `EM_RISCV` (243) is retained as the provider-neutral `riscv` family. The
target also retains the raw ELF declarations that decide a lane: class, byte
order, `e_type`, and `e_flags`. Recognition does not mean every provider or
RISC-V variant is supported. Existing PE, managed and Mach-O architecture sets
are unchanged, and caller-supplied headerless raw-binary entry still accepts only
its existing four families.
The Ghidra lane admits little-endian ELF32 and ELF64 `ET_EXEC` images that
declare `EF_RISCV_FLOAT_ABI_DOUBLE` in `e_flags`, with no `EF_RISCV_RVE`,
`EF_RISCV_TSO`, or any bit outside `EF_RISCV_RVC | EF_RISCV_FLOAT_ABI`. These are
header declarations, not proof that every instruction conforms to that ISA.
Provider selection returns the specific unsupported constraint rather than
guessing a compatible profile:
| Declaration | Outcome |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------- |
| Little-endian ELF64 `ET_EXEC`, double-float ABI | admitted, `RISCV:LE:64:default` + `gcc` |
| Little-endian ELF32 `ET_EXEC`, double-float ABI | admitted, `RISCV:LE:32:default` + `gcc` |
| Big-endian | refused; Ghidra 12.1.4 ships no big-endian RISC-V language |
| `ET_REL`, `ET_DYN`, other `e_type` | refused with the declared value |
| `EF_RISCV_RVE` | refused; the embedded 16-register profile (x0–x15) needs its own processor specification |
| `EF_RISCV_TSO` | refused; the total-store-order memory model is unverified here |
| Soft, single, or quad float ABI | refused; the pinned generic compiler specification models double-float |
| Reserved or newer `e_flags` bits | refused with the offending bits named |
`e_type` is the only load-shape declaration this lane reads. A fixed-address
`ET_EXEC` declaration does **not** establish static linkage: `PT_INTERP` and
dynamic dependencies are not inspected, and the session records that boundary as
a limitation rather than inferring a load model.
## Why the language is pinned
Ghidra's header-based selection is not reliable for RV32. The 12.1.4
`riscv.opinion` pins `variant="default"` for the 64-bit constraint and leaves the
32-bit constraint unpinned with the comment that the loader "must choose between
'default' and 'AndeStar' variants". Measured against the installed release tree:
| Fixture | Ghidra auto-selection |
| ----------------------------------------------- | ----------------------------- |
| RV64 ELF, `e_flags 0x5` (RVC, double-float ABI) | `RISCV:LE:64:default:gcc` |
| RV32 ELF, `e_flags 0x5`, no Andes declaration | `RISCV:LE:32:AndeStar_v5:gcc` |
So an ordinary RV32 image lands on an Andes processor model unless the language
is stated. REA therefore pins `RISCV:LE:32:default` or `RISCV:LE:64:default`
with the `gcc` compiler specification per class, records
`language_selection: provider-pinned-v1`, and refuses a caller-selected
`REA_GHIDRA_LANGUAGE_ID` or `REA_GHIDRA_COMPILER_SPEC_ID` that disagrees with the
pin without changing the requested override. An override that matches the pin is
accepted and recorded as `configured-v1`.
## Evidence
The lane identity is `elf32-exec-le-double-float-generic-v1` or
`elf64-exec-le-double-float-generic-v1`, and `riscv_elf` retains `elf_class`,
`byte_order`, `type`, and the raw `flags` alongside the read-only booleans
`float_abi_double`, `rvc_declared`, `rve_declared`, and `tso_declared`. Those
fields report declarations the header makes; none of them is evidence of the
original compiler, of instruction conformance, or of a floating-point calling
convention beyond the ABI the pinned language models.
## Verification and limits
Ghidra 12.1.4 PUBLIC with a 64-bit JDK 21+ is required, and on macOS the release
tree ships no host decompiler binary, so `Decompiler/os/<platform>/decompile` and
`sleigh` must come from your own build; see
[installation](installation.md#ghidra).
Run `npm run verify:ghidra:riscv` with an existing Ghidra 12.1.4 installation,
JDK 21+, and a RISC-V-capable Clang, LLD and LLVM readelf. The verifier acquires
no tools and never executes target code. Select installed tools explicitly when
they are not on `PATH`:
```sh
GHIDRA_INSTALL_DIR=/path/to/ghidra_12.1.4_PUBLIC \
JAVA_HOME=/path/to/jdk-21 \
REA_RISCV_CLANG=/path/to/llvm/bin/clang \
REA_RISCV_LLD=/path/to/lld/bin/ld.lld \
REA_RISCV_READELF=/path/to/llvm/bin/llvm-readelf \
npm run verify:ghidra:riscv
```
The lane builds the committed freestanding C and assembly sources into RV32 and
RV64 `ET_EXEC` fixtures. Independent LLVM readelf observations establish ELF
declarations and symbol addresses. Public CLI and stdio MCP workflows verify
function enumeration, decompilation, pinned language/compiler identity, decoded
probe bytes, global data, and direct calls. It validates advertised MCP output
schemas and both JSON representations, saves and reopens snapshots, rejects
header-mutated soft-float and unsupported high-bit declarations, and checks
unchanged source bytes and owned cleanup. Failures retain the diagnostic
workspace; successful runs remove it and report the observed process lineage.
Module tests cover admission and malformed headers. Call-graph completeness,
string inventories, dynamic linkage, Andes or RVE/TSO images, and big-endian
targets are **not** established by this lane. `.riscv.attributes` ISA extensions
are not inspected; the generic language pin remains an analysis convention.
+6 -38
View File
@@ -1,6 +1,6 @@
# IDA provider
# IDA Pro provider
REA adapts an existing IDA MCP server into its native analysis tools. Existing IDA Pro profiles use [mrexodia/ida-pro-mcp](https://github.com/mrexodia/ida-pro-mcp); an optional native bridge for IDA Pro and IDA Free is described below. Install and configure your selected engine and upstream MCP using their instructions. REA does not install, upgrade, activate, or license them, and does not bundle another IDA server.
REA adapts an existing [mrexodia/ida-pro-mcp](https://github.com/mrexodia/ida-pro-mcp) server into its native analysis tools. Install and configure IDA, Hex-Rays, Python, and upstream MCP using that repository's instructions. REA does not install, upgrade, activate, or license them, and does not bundle another IDA server.
Choose one lifecycle mode in an upstream MCP JSON registration. Set `REA_IDA_MCP_CONFIG` to that file, then select `ida` once through `REA_ANALYSIS_PROVIDER`, the CLI's `--provider ida`, or MCP's `open_binary.provider_id`. No provider startup occurs during discovery.
@@ -32,33 +32,7 @@ Open the **original input binary** in REA, not an `.idb` or `.i64` database. Its
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.
## Optional native IDA MCP bridge
IDA Pro and IDA Free can use the separate [ida-free-mcp native plugin](https://github.com/0xshlomil/ida-free-mcp) through an explicit attached registration. Install and start that plugin using its upstream instructions, open the original binary in the IDA GUI, and wait for analysis. The native MCP 1.1.2 release binds `0.0.0.0` without a listen-address setting. Restrict inbound access with the host firewall or use an upstream build that binds only to loopback before starting it. REA's loopback URL restriction does not change the plugin's listener. REA does not install IDA, build the plugin, activate a license, or launch the GUI.
```json
{
"mode": "attached",
"protocol": "native",
"url": "http://127.0.0.1:13337/mcp"
}
```
Set `REA_IDA_MCP_CONFIG` to this file and select `ida` using the same CLI/MCP commands above. Omitting `protocol` preserves existing IDA Pro registrations. Native mode requires `resources/read` for `ida://idb/metadata` and its recorded input SHA-256; it never substitutes a digest of an unrelated local file. The native resource's `path` describes the IDB in the upstream protocol, not the original input path. REA retains it and checks database identity and image base before and after requests.
This experimental profile provides function/string inventory and search, function lookup, assembly, GUI pseudocode, callees, address xrefs, instruction windows, and function dossiers. Direct callers remain unavailable: native code/data xref labels do not prove call edges. It requires neither IDAPython nor idalib. Native headless registrations are rejected.
Native string observations use upstream C-string rendering; other representations remain unknown. Literal searches request conservative candidates and apply REA's original case and Unicode matching rules. Regex searches retain the full scan because native byte-oriented regex semantics cannot replace REA's Unicode regex semantics. All candidate pages are examined, and upstream search errors remain failures.
Native callee resolution batches unique queries and checks each reply's query identity. Results remain live: a recorded input hash does not establish database revision, so cross-request analysis caches cannot prove freshness. For focused questions, use pseudocode, callees, or instruction-window tools; a function dossier requests additional facets and returns more Evidence.
IDA Free's cloud decompiler needs network access and may request consent. Follow its licensing and supported architecture limits; see [IDA Free](https://hex-rays.com/ida-free). Decompilation moves GUI focus and the upstream plugin closes existing pseudocode tabs before requesting fresh output. REA advertises UI/network effects and closes only its MCP connection, preserving the open database. Rendered pseudocode has upstream traversal limits and does not prove complete source recovery. Cloud/widget failures remain explicit failures; retry after the GUI finishes or dismiss its prompt.
Native MCP 1.1.2 can navigate in the previously focused pseudocode tab when switching functions. Use upstream 1.1.3 or a source build including [the navigation correction](https://github.com/0xshlomil/ida-free-mcp/commit/6adf2c615a2a03661059673e9c136ef28d0dc778), which focuses the disassembly view **before** jumping to the requested entry. This REA profile does not repair stale GUI output. Verification must include two different functions before claiming reliable function switching. The initial Linux verification used a locally corrected 1.1.2 plugin; upstream 1.1.3 has not been verified by that run.
Native tool observations retain actual tool names and complete JSON text. Upstream `structuredContent` can be a shortened preview even while text contains the full result. REA reads the full native representation and rejects missing/malformed text instead of treating previews as complete observations.
The legacy producer moves the active GUI as a side effect: assembly and raw function instructions jump to the function, and successful pseudocode opens or reuses a pseudocode view. A function dossier does both. Native GUI decompilation also changes the active view. `binary_session` reports these operations with `effects.may_show_ui: true`; headless operations and the other attached operations report `false`.
The legacy producer moves the active GUI as a side effect: assembly and raw function instructions jump to the function, and successful pseudocode opens or reuses a pseudocode view. A function dossier does both. `binary_session` reports these operations with `effects.may_show_ui: true` in attached mode; headless operations and the other attached operations report `false`.
## Give REA a target for headless analysis
@@ -84,7 +58,7 @@ rea function 'D:\samples\program.exe' main --json
Headless REA and the configured supervisor must share the host filesystem and native path syntax. Run REA on Windows when the supervisor runs on Windows. The attached profile can span WSL and a Windows GUI because it binds recorded input hashes instead of asking the GUI to open a WSL path.
REA copies the admitted binary into a private temporary directory, checks its digest, and requests an owned worker with `force_headless`. POSIX workspaces are created atomically with owner-only permissions, respecting the process umask; Windows uses the matching package's native private-DACL boundary on a local NTFS temporary directory. It injects the returned database ID into analysis requests. It verifies the active owned worker and input path rather than adopting a user database. On close or failed startup, it releases its session with `save: false`, verifies that it is absent from upstream session discovery, and removes its private input and sidecars. An unverified release retains the workspace and reports incomplete cleanup.
REA copies the admitted binary into a private temporary directory, checks its digest, and requests an owned worker with `force_headless`. POSIX workspaces use mode `0700`; Windows uses the matching package's native private-DACL boundary on a local NTFS temporary directory. It injects the returned database ID into analysis requests. It verifies the active owned worker and input path rather than adopting a user database. On close or failed startup, it releases its session with `save: false`, verifies that it is absent from upstream session discovery, and removes its private input and sidecars. An unverified release retains the workspace and reports incomplete cleanup.
One REA session owns one database. Stdio registrations default `IDA_MCP_MAX_WORKERS` to `1`; the explicit upstream `--max-workers 1` also bounds a supervisor. Database size and engine memory depend on the target and upstream; REA does not impose an engine memory limit. The original binary is never executed or overwritten. Optional `workspaceRoot` selects an existing absolute temporary-directory parent on the REA host. Ensure it has space for the input copy and IDA working files.
@@ -124,9 +98,9 @@ For guided registration, set `REA_IDA_MCP_CONFIG` before `rea setup --client <cl
## Coverage and evidence
All profiles support procedure/string inventory and literal or regex search, procedure resolution, pseudocode, assembly, raw function instructions, resolved callees, incoming address references, and a function dossier. Inventories and modern pseudocode/assembly follow upstream pagination. Upstream limits on modern xrefs and callees are retained as explicit truncation limitations. In the modern headless profile, targets that are not proven x86-only use processor-neutral `callgraph` edges instead of the x86 instruction checks in upstream `callees` (mrexodia/ida-pro-mcp#549). REA requests depth zero: the pinned upstream emits the root's outgoing edges without scanning child functions, then REA batches function-name lookup for those addresses. The graph covers recognized function destinations only; imports and other non-function targets remain unknown. A server without `callgraph` returns an empty relationship list with an explicit coverage limitation. Graph and path workflows retain those limitations alongside observed edges. A failed or inconsistent graph reply remains an error. A transport-level truncated preview is rejected rather than reported as complete evidence; the error preserves upstream retrieval guidance.
Both profiles support procedure/string inventory and literal or regex search, procedure resolution, pseudocode, assembly, raw function instructions, resolved callees, incoming address references, and a function dossier. Inventories and modern pseudocode/assembly follow upstream pagination. Upstream limits on modern xrefs and callees are retained as explicit truncation limitations. In the modern headless profile, targets that are not proven x86-only use processor-neutral `callgraph` edges instead of the x86 instruction checks in upstream `callees` (mrexodia/ida-pro-mcp#549). REA requests depth zero: the pinned upstream emits the root's outgoing edges without scanning child functions, then REA batches function-name lookup for those addresses. The graph covers recognized function destinations only; imports and other non-function targets remain unknown. A server without `callgraph` returns an empty relationship list with an explicit coverage limitation. Graph and path workflows retain those limitations alongside observed edges. A failed or inconsistent graph reply remains an error. A transport-level truncated preview is rejected rather than reported as complete evidence; the error preserves upstream retrieval guidance.
The legacy profile additionally supports direct callers. Its producer may report call-site or interior addresses; REA resolves the reported function symbol to its canonical entry. The modern and native profiles do not prove direct callers from its code/data xref labels, so that capability is unavailable and the dossier marks it unknown.
The legacy profile additionally supports direct callers. Its producer may report call-site or interior addresses; REA resolves the reported function symbol to its canonical entry. The modern profile does not prove direct callers from its code/data xref labels, so that capability is unavailable and the dossier marks it unknown.
Complete body ranges, typed reference edges, CFG, referenced data, source locals, comment kinds, and database revision are unavailable. Empty unsupported dossier facets mean **unknown**, not observed absence. `binary_overview`, whole-symbol inventory, mutation, debugging, arbitrary Python forwarding, and requested GUI navigation are outside this adapter's coverage. Check session availability before composing a workflow that needs those facets.
@@ -136,10 +110,4 @@ Complete body ranges, typed reference edges, CFG, referenced data, source locals
Run `npm run verify:ida -- --target /absolute/path/to/program --procedure main` with a configured upstream server. It exercises production CLI and MCP tools, validates their output contracts and Evidence, checks original-input preservation and session cleanup, and keeps local target data out of its console summary. Supply `--package-root` to verify an extracted or installed package. See [testing](testing.md) for the distinction between adapter tests and real-provider evidence.
Native verification requires `--second-procedure other_function --second-marker unique_second_body_text`; these options remain optional for the other profiles. The marker must occur in the second function's pseudocode and be absent from the first; the verifier also checks that returning to the first restores its text.
The verifier requires the resolved procedure in both inventory and procedure search, then compares address, assembly, pseudocode, instruction windows and relationship results with the CLI/MCP dossier. Supply `--expected-string known_literal` to check a known positive string inventory/search result and `--expected-xref 0xSOURCE` to check a known reference source address. Choose those oracles independently from the operation under test. Without them, string and xref correctness are listed in `unverified`; valid output shapes alone do not establish those behaviors. Callee parity does not independently establish semantic completeness. Native callee successes must report an explicit truncation marker; missing markers remain protocol failures.
The initial real workflows use stdio registrations for the legacy Windows GUI profile and a Windows x64 headless supervisor with IDA 9.3. The headless workflow has also passed on macOS arm64 with IDA Professional 9.1 (build 9.1.250226) against the same upstream commit `c133c3853faa111a9b00ee615c013b720d0c4acd`, using a source-built arm64 Mach-O fixture; Mach-O C symbols carry a leading underscore, so the procedure name is `_rea_fixture_add`. Streamable HTTP is tested against a loopback MCP fixture with the pinned client SDK; a real IDA HTTP-supervisor workflow remains unverified. Linux headless engine operation, other IDA releases, architectures, and modern attached GUI tools require their corresponding real workflows before support is claimed.
Native Windows verification uses IDA Pro 9.3 with the public two-function fixture and Windows `whoami.exe`, using upstream `c9d15d98e8a143fc74f6e14037c48f63889b6d6c` with a loopback-listener change. It covers production CLI/MCP parity, distinct-function switching, identity and connection cleanup. See the [correctness and performance measurements](https://github.com/morluto/rea/blob/main/experiments/analysis-efficiency/ida-native-windows.md). This follow-up did not run Windows IDA Free or native macOS.
-22
View File
@@ -43,26 +43,4 @@ npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --
See [installation and setup](./installation.md) for requirements and configuration.
For runtime instrumentation, see the [Frida guide](./frida-instrumentation.md).
## Choose a guide
| Task | Guides |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-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), [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) |
| 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) |
| Observe or compare a browser scenario | [CDP observation](browser-observation.md), [scenarios](browser-scenario-contract.md), [runtime evidence](web-runtime.md), [historical captures](web-network-captures.md) |
| Trace captured website source | [Source locations](web-source-location.md), [module traces](website-module-trace.md), [script export](website-script-export.md) |
| Capture and compare a command | [Process capture](process-capture.md) |
| Use CLI/MCP and retain evidence | [CLI](cli.md), [MCP contracts](mcp-contracts.md), [agent prompts](mcp-prompts.md), [obligation ledgers](reconstruction-obligation-ledgers.md) |
For development, use [testing](testing.md), [client verification](client-verification.md),
[tool design](tool-design.md), and [releasing](releasing.md).
[Reconstruction readiness](reconstruction-readiness.md) describes a development
conformance verifier. [The 6.2 migration](migration-6.2.md) records that release's
compatibility changes; [the roadmap](roadmap.md) tracks future work.
![REA inspecting a native binary in Hopper](./assets/rea-hopper-analysis.png)
+443 -287
View File
@@ -1,197 +1,84 @@
# Installation and setup
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), 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) |
REA separates installing its CLI from configuring external software and agents.
## Start setup
Start setup with:
```bash
npx rea-agents setup
```
Choose the agents to configure, review the proposed paths and changes, and
approve the plan. npm's package-download approval and REA's setup approval are
separate. Setup asks before changing agent configuration or installing Hopper.
Restart the agents named in the completion message.
If npm asks to download and run REA, that approval applies only to downloading
the package. REA shows its own plan and asks before changing agent configuration
or installing Hopper.
For the latest published release, use `npx rea-agents@latest setup`.
[Package-runner and global-installation options](#package-runners-and-global-installation)
cover explicit versions, Bun, runtime requirements, and the curl wrapper.
## Review setup changes
`rea setup` first offers the supported agents in a multi-select. Existing REA
registrations are selected by default. Newly detected clients remain available
but unselected: detection gives setup context, not permission to add a new
registration. Clients without a detected configuration can still be selected.
Explicit `--client` flags skip this question.
Setup adds MCP access for selected clients. It installs REA's bundled workflow
with those integrations by default; use `--skill=false` to omit it. If no agent
is selected, setup offers the workflow separately for CLI use, with No as the
default. Hopper is a separate optional choice: setup shows its proposed
installation or connection and requires its own explicit approval. It can also
save verified paths for an existing Ghidra installation.
After selection, review the plan's exact paths and changes and approve before
REA writes files or installs Hopper. You can cancel at any prompt.
Before applying changes, REA checks your current configuration. The plan lists:
- an existing Hopper installation, a verified existing Ghidra installation, or the official Hopper package it proposes to install;
- each detected agent configuration path;
- each selected REA skill destination;
- external software, network origins, integrity evidence, and package-manager
commands.
Malformed or unsafe existing configuration blocks the whole transaction before
Hopper installation or any file write. Declining or pressing Ctrl-C makes no
changes. Agent configuration writes preserve unrelated entries and comments,
create backups, use atomic replacement, and verify their result. Setup and
uninstall retain an existing `.rea.backup` rather than replacing the first snapshot.
Setup also retains valid environment overrides in REA's existing server entry,
such as `REA_MCP_INPUT_SCHEMA_PROFILE` and `REA_MCP_MAX_RESPONSE_BYTES`.
Detected provider settings replace only matching environment keys.
Setup and doctor report a malformed REA environment map or invalid runtime
setting before setup writes files. Repair the named setting in the client
configuration; setup does not silently discard the rest of the map.
After setup, REA reports which agents, analysis tools, and workflow files passed
its final checks. Restart any agent named in the completion message, then begin
your investigation. Failed steps and diagnostics remain in terminal history.
Select exact clients in scripts with repeatable `--client` flags. Each explicit
client skips interactive selection. Use `--all-detected` only when you intend
to configure every detected supported client. `--skill=false` omits the
workflow, and `--dry-run` returns a read-only plan with status `planned` and
exit code 0:
The short command can use a REA version installed in the current project. To
request the latest release explicitly, use:
```bash
rea setup --client codex --client cursor --skill=false --dry-run
npx rea-agents@latest setup
```
Prompt UI and progress are written to stderr so stdout remains available for
structured results and pipelines. `NO_COLOR=1` disables color. Use
`--accessible` for sequential, vertically rendered yes/no prompts. Implicit
interactive setup requires stdin, stdout, and stderr to all be terminals; when
any stream is redirected, setup stays non-interactive. Declining or cancelling
returns status `cancelled` with exit code 0.
REA runs the version npm selects. To update older agent registrations, run the
latest-version command and review its setup plan. For unattended package
downloads, add `--yes` before the package name; this does not approve REA's
setup changes.
For automation, `rea setup --json` reports the plan and a compact `.doctor`
readiness projection without applying it. Use `rea doctor --json` for full
health diagnostics and canonical tool catalog details. Pair
`--yes` with explicit scope such as `--client codex`, or use
`--all-detected` when the broad scope is intended. Without a scope flag,
`--yes` is limited to existing REA-owned registrations; it does not select all
detected clients. An unapproved actual apply reports `needs_confirmation` and
exits 1. Installing missing Hopper non-interactively additionally requires
`--install-hopper`:
For an intentional rollback, make the package request explicit:
```bash
rea setup --yes --all-detected --install-hopper --json
npm exec --yes --package=rea-agents@2.4.0 -- rea setup
```
### Skill destinations
Setup continues to pin persistent MCP registrations to the exact version that
performed setup. Running current setup later migrates unversioned or older
managed registrations through the normal reviewed setup transaction.
The bundled skill is installed in each selected client's personal skill directory.
See [client configuration](client-configuration.md) for client-specific roots,
profiles, and environment overrides. A mixed selection plans each distinct
destination. Selecting the skill without a client uses `~/.agents/skills`.
Setup leaves existing skill copies in other locations untouched.
With Bun, `bunx rea-agents setup` (or `bunx rea-agents@latest setup`) is the
equivalent entry point. Setup run through `npx` registers
`npx -y rea-agents@<version> mcp`; setup run through `bunx` or `bun x` registers
`bunx rea-agents@<version> mcp`. On Windows, setup wraps either command in
`cmd.exe /d /c` so clients can start the runner's command shim. Neither
registration points into the runner's temporary package cache.
`rea setup --skill-client claude_code --yes --json` refreshes and verifies the
selected skill destination independently of MCP registration selection. The
final `doctor.scope.skill_clients` records which skill destinations were
checked; `doctor.scope.clients` continues to describe required registrations.
An unselected shared skill does not affect a client-only refresh.
REA supports Node.js 22.x (>=22.19), 24.x (>=24.11), and 26+. Node.js 23, 25, and prereleases are unsupported. It uses the npm already paired with that runtime and never upgrades Node.js, npm, or Homebrew.
`doctor --skill --json` verifies the selected copies against the bundled
instructions and references. Consumers should use `identity.skill.state`,
`installed_version`, and `installed_tool_count` for skill readiness. The
obsolete `installed_catalog_digest` field has been removed; current catalog
identity remains available at `identity.catalog`.
When REA runs on Bun, the `rea doctor` `node` check reports the Bun version and
the Node.js compatibility version Bun declares, and passes when that
compatibility version is in the supported range. Bun does not enforce the V8
heap flags REA gives its owned helper processes, so Evidence that reports those
limits on Node.js records them as unavailable under Bun. On Windows, the owned
Job Object of each JavaScript helper (source analyzer, source-map codec and HAR
decoder) instead limits its committed memory to that helper's heap budget plus
a 512 MiB reserve for Bun itself, and Evidence reports that limit. This needs
the matching bundled Windows native artifact; an artifact without the control
refuses to start the helper rather than running it unlimited. CI tests Node.js
only.
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.
Running `npm install rea-agents` without `--global` installs the executable only
in the current project's `node_modules/.bin`; it does not make `rea` available
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.
## Check readiness for your task
Run `rea doctor` when you need diagnosis. It reads host prerequisites and agent
configuration without changing them. Without options, it audits every detected
registration, the installed skill and optional analysis engines; its overall
`healthy` value can be false while your chosen workflow works.
Select the part you want to check:
| Task | Readiness check |
| ----------------------------------- | ------------------------------------------------------------------------ |
| Static JavaScript/Electron analysis | Run `rea analyze-javascript-application PATH --json` directly. |
| One analysis engine | `rea doctor --provider ghidra --json` (or `hopper`, `ida`) |
| One agent registration | `rea doctor --client codex --json` (see [client IDs](#supported-agents)) |
| Installed workflow instructions | `rea doctor --skill --json` |
A scoped report has `scope.mode: "explicit"`. Its `scope_checks` determine
`healthy` and the exit status. Other checks appear in `informational_checks`;
`environment_healthy` summarizes the full audit. `--target` adds a target check,
but the report remains audit-wide unless a scope option is also supplied.
Follow the remediation for the failed check. If a native target has several
available providers, choose one with `--provider` on the CLI or `provider_id`
on `open_binary`. A `capability_unavailable` failure carries
`details.selection_reason`: `ambiguous` asks you to choose from
`details.candidate_ids`, while `provider_unavailable` asks you to repair the
selected engine. See [provider selection](cli.md#choose-a-provider).
## Diagnose, update, and remove
`rea doctor --json` is strictly read-only. `rea update` updates only the npm or Bun global installation that owns the running CLI. Source checkouts and package-runner copies must be updated through the mechanism that owns them; a fresh package-runner invocation can use `npx rea-agents@latest` or `bunx rea-agents@latest`. `rea uninstall` removes only REA-owned agent registrations and skill files; `--purge-data` additionally removes REA cache and state paths.
The optional curl wrapper installs only the global npm package:
```bash
rea update
rea uninstall
rea uninstall --purge-data
curl -fsSL https://raw.githubusercontent.com/morluto/rea/main/install.sh | bash
```
Uninstall preserves Hopper, Node.js, Evidence files, captures, unrelated skills
and other MCP servers. Purging removes only REA's cache and state under
`~/.rea`. A client configuration that is malformed, unreadable, or at an unsafe
path stops the operation before anything is removed, and a client that fails
while being updated stops the remaining removals. A purge path that is a
symbolic link is retained and reported rather than followed. Uninstall checks
REA's managed shared and Claude Code personal skill locations. See the
[CLI guide](cli.md#output-and-exit-status) for exit statuses.
It prints the version, runtime, npm command, and destination before installing. When a controlling terminal exists it starts `rea setup`; otherwise it prints the command to run later.
### Update the owning installation
Pass options with `bash -s --`:
`rea update` installs the exact resolved
release into the npm prefix or Bun global directory that owns the running
package, then checks the new executable's version before reporting success. It
does not reopen onboarding. For npm installations, release lookup and
installation both use npm's configured registry. Bun global updates require
Bun 1.2.17 or later, which introduced `bun info`. The updater checks `bun --version`
first and stops with an instruction to upgrade Bun manually if the version is
older or cannot be parsed; it does not upgrade Bun itself.
For supported Bun global installations, `bun info` and
`bun add --global --ignore-scripts` use Bun's configured registry
and run inside the owning Bun global directory (`BUN_INSTALL_GLOBAL_DIR`, else
`$BUN_INSTALL/install/global`, else `$XDG_CACHE_HOME/.bun/install/global`,
else `~/.bun/install/global`), never in the caller's current project. A Bun
global directory without its `package.json` is not treated as an owned
installation, because Bun would install into the nearest ancestor project
instead.
Its maintenance plan selects only existing REA registrations and an already
installed REA skill. Run the returned scoped setup command to review and approve
those changes, then restart affected agents. The plan is returned in terminal,
non-TTY, and JSON modes without applying configuration changes.
```bash
curl -fsSL https://raw.githubusercontent.com/morluto/rea/main/install.sh |
bash -s -- --dry-run
```
Supported options are `--version <semver>`, `--dry-run`, `--no-setup`, `--no-prompt`, and `--verbose`. Neither `--no-prompt` nor a non-interactive shell grants permission to install external dependencies.
## Released package and main
@@ -256,8 +143,8 @@ readiness for one task instead of auditing every integration, see
## Supported agents
Setup can configure these clients for REA's local MCP server. Grok Bot uses a manual
hosted connector; see [its configuration](client-configuration.md#other-client-settings).
Setup can configure these clients for REA's local MCP server. Grok Bot is
listed after the table because its connector is not one of these files:
| Client | `--client` value |
| ------------------ | ---------------- |
@@ -278,24 +165,356 @@ hosted connector; see [its configuration](client-configuration.md#other-client-s
| OMP | `omp` |
| Pi | `pi` |
| Hermes | `hermes` |
| Qoder | `qoder` |
| Trae | `trae` |
| ZCode | `zcode` |
| DeepSeek Harness | `dsh` |
`dsh` is main-only until a release after 6.4.0. The registry check above does
not cover it.
See [client configuration and troubleshooting](client-configuration.md) for
configuration paths, profiles, trust policies, and schema-limit workarounds.
For GitHub Copilot CLI 1.0.95, `gpt-4.1` model metadata can block ordinary
chat with REA's full input-schema profile before sending a model request
(`compaction_static_context_blocked`; [#1554](https://github.com/morluto/rea/issues/1554)).
For the native offline OpenAI-compatible BYOK adapter, full-profile chat and
analysis also passed with a distinct `COPILOT_PROVIDER_MODEL_ID` such as
`rea-gpt-4.1`, `COPILOT_PROVIDER_WIRE_MODEL=gpt-4.1`, and that distinct ID selected
through `copilot --model rea-gpt-4.1`. The local fixture requested
`COPILOT_PROVIDER_MAX_PROMPT_TOKENS=1000000`; configure the limit supported by
your backend. This keeps every full schema and the actual wire model intact.
It does not establish the effective client budget or fix the built-in-ID path.
The existing compact profile passed native chat and analysis with the complete
tool inventory on Linux using a loopback model fixture. After setup, add
`"REA_MCP_INPUT_SCHEMA_PROFILE": "compact"` to the `env` object of the
`mcpServers.rea` entry in Copilot's `mcp-config.json`, preserving its other
settings, then restart the client. Compact advertisements can reduce nested
schema constraints; REA still validates complete canonical inputs. Full-profile
`gpt-5.4` metadata is also verified locally. Live model API acceptance and
Windows remain unverified; see [native client verification](testing.md).
Claude Code normally defers MCP tool definitions through tool search. It
[turns tool search off](https://code.claude.com/docs/en/mcp#configure-tool-search)
when `ANTHROPIC_BASE_URL` points to a non-first-party host, such as DeepSeek's
Anthropic-compatible endpoint. It then sends every REA tool's name, description
and input schema with every request
([#2019](https://github.com/morluto/rea/issues/2019)). On main at 04089d5be,
with 172 tools, that payload measured about 496 KB with the default profile and
about 290 KB with `compact`. By the o200k and cl100k tokenizers, that is roughly
120k and 68k tokens. Compaction cannot remove tool definitions. If they nearly
fill the window Claude Code assumes, the context refills after every compaction
and Claude Code reports that autocompact is thrashing. To avoid this:
- Make Claude Code assume the model's actual context window. DeepSeek's Claude
Code guide selects `deepseek-flash[1m]`; the `[1m]` suffix makes Claude Code
assume a one-million-token window. For other unrecognized model IDs, set
`CLAUDE_CODE_MAX_CONTEXT_TOKENS` to the window the provider documents.
- If the endpoint forwards `tool_reference` blocks, set `ENABLE_TOOL_SEARCH=true`
to restore deferred loading. DeepSeek's Anthropic API guide does not list
`tool_reference` among its supported content blocks, so this setting may cause
its requests to fail.
- To shrink the upfront catalog, add
`"REA_MCP_INPUT_SCHEMA_PROFILE": "compact"` to the `env` object of the
`mcpServers.rea` entry in `~/.claude.json` (`$CLAUDE_CONFIG_DIR/.claude.json`
when that variable is set), then restart Claude Code. Setup keeps this
override.
The sizes above come from REA's own `tools/list`. A live Claude Code session
against DeepSeek's API is unverified.
For [Pi](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/mcp.md),
setup writes a `type: "stdio"` entry under `mcpServers.rea` in the user-level
`~/.pi/agent/mcp.json` and installs the bundled skill under `~/.agents/skills`.
Use `rea setup --client pi --dry-run --json` to inspect the plan, then
`rea setup --client pi --yes --json` to approve it. Check the registration with
`rea doctor --client pi --json`. Pi reads `mcp.json` as strict JSON, like its
own loader: comments, trailing commas, a byte-order mark, or an empty existing
file are invalid, and setup reports them instead of rewriting the file. Repair
such a file to plain JSON first, then rerun setup.
Setup follows Pi's `PI_CODING_AGENT_DIR`: unset or empty selects the default;
`~` and `~/` expand to the home directory; absolute paths and file URLs select
that directory; relative paths stay relative to the command's working directory.
On Windows, native paths, `~\`, and Git Bash/MSYS, Cygwin, and WSL drive paths
are normalized as Pi does. Run REA and Pi from the same working directory when
using a relative override. Pi has no profiles: `OMP_PROFILE`, `PI_PROFILE`,
`PI_CONFIG_DIR`, and OMP's `enabledServers`/`disabledServers` lists do not affect
Pi registration. Doctor accepts an omitted `type` for stdio but reports a
non-stdio type as invalid; `enabled: false` stays disabled.
REA configures only the user scope. Pi also reads `.pi/mcp.json` in trusted
projects; a same-name project entry can replace the user entry or override its
enabled state and exposure. Check that file if the user registration is aligned
but unavailable in a project. An extension that registers `/mcp` can replace
Pi's built-in MCP support and use its own configuration instead. Run `/reload`
in an existing Pi session after changing servers outside the session.
For Qwen Code, setup registers `rea` in the `mcpServers` table of the
user-level `~/.qwen/settings.json`, or `$QWEN_HOME/settings.json` when configured.
Setup and doctor follow Qwen Code's tilde and working-directory-relative home
overrides. Qwen Code also discovers personal skills in `~/.agents/skills`,
where setup installs the bundled workflow.
Gemini CLI uses `$GEMINI_CLI_HOME/.gemini/settings.json` when that home override
is nonempty, including its shared personal skills at
`$GEMINI_CLI_HOME/.agents/skills`. Setup and doctor check MCP allow/exclude
policies from system defaults, user settings, trusted workspace settings, and
system overrides. Workspace trust follows `GEMINI_CLI_TRUST_WORKSPACE`,
`GEMINI_RESTRICTED_MODE`, the effective `security.folderTrust.enabled` setting,
and the selected `trustedFolders.json` (including
`GEMINI_CLI_TRUSTED_FOLDERS_PATH`). Settings in an untrusted workspace do not
participate. A workspace or system `mcpServers.rea` replaces the entire user
entry; setup stops if the winning definition conflicts with its planned entry.
Review those files manually: setup never edits administrator/workspace settings
or grants workspace trust. Trust supplied only by a running IDE is outside this
standalone CLI check.
Codex treats an unset or empty `CODEX_HOME` as `~/.codex`. Devin honors
`XDG_CONFIG_HOME` for its `devin/mcp_config.json` on non-Windows systems.
For OMP, setup writes a `type: "stdio"` entry to the user-level
`~/.omp/agent/mcp.json`. It follows `PI_CONFIG_DIR` and
`PI_CODING_AGENT_DIR` (relative to the setup working directory), and the profile selected by `OMP_PROFILE` or
`PI_PROFILE` (`~/.omp/profiles/<name>/agent/mcp.json`). Setup also removes
`rea` from that file's `disabledServers` list, which would otherwise hide the
registration. Doctor treats an `enabled: false` entry as active when
`enabledServers` lists `rea`, as OMP does, unless `disabledServers` also lists
it. Run setup under each profile that should load REA.
For Hermes, setup writes a `mcp_servers.rea` entry to `config.yaml`, preserving
comments and unrelated settings. It resolves that file from `HERMES_HOME`, else
from the platform default Hermes itself uses — `%LOCALAPPDATA%\hermes` on
Windows, `~/.hermes` elsewhere — including any `HERMES_DATA_DIR_SUFFIX`. Hermes
connects an entry unless `enabled` is false, so setup states `enabled: true`.
Hermes personal skills install under the active Hermes home's `skills` directory.
Setup, doctor and uninstall follow the root's `active_profile` selection, as
plain Hermes CLI commands do. An explicit `HERMES_HOME` pointing to
`profiles/<name>` selects that named profile directly. An invalid, missing or
deleted sticky profile is reported instead of writing into the default home;
repair the profile or run `hermes profile use default` before retrying.
REA follows `HERMES_HOME` whitespace trimming, environment-variable expansion,
and home expansion before resolving that profile. Setup previews the resolved
configuration and skill destinations; doctor and uninstall use those same paths.
### DeepSeek Harness
See [the Cordis patch and launcher setup](client-configuration.md#deepseek-harness).
DeepSeek Harness registers MCP clients through a Cordis YAML patch sequence
rather than a `mcpServers` object. `rea setup --client dsh` appends (or
replaces) the REA entry in the home patch `$DSH_HOME/cordis.patch.yml`
(`~/.dsh/cordis.patch.yml` when `DSH_HOME` is unset), preserving unrelated
patches and comments. `rea doctor --client dsh` checks that same entry id.
`rea uninstall` removes it by scanning supported clients; uninstall takes no
`--client` flag. The home patch applies to every Harness profile, so the
registration is written once and no per-profile edit is needed. The written
entry is:
```yaml
- insert:
- id: rea-mcp
name: "@deepseek-ai/dsh-mcp-client"
config:
serverName: rea
transport: stdio
command: /absolute/path/to/node
args: ["/absolute/path/to/rea/scripts/rea.mjs", mcp]
```
Setup preserves caller-owned Cordis expressions and replaces launcher fields
with literal values that doctor can verify. It refuses to edit an expression
that produces the entire REA config, or a group-targeted REA insertion. Use a
literal config and a root-level insertion as shown above.
For a global npm installation, the launcher is under
`$(npm root -g)/rea-agents/scripts/rea.mjs`. Restart Harness after setup; it
exposes tools as `mcp__rea__<tool_name>`. Run `rea setup --skill --dry-run`,
review the destination, then `rea setup --skill --yes` to install the workflow
in `~/.agents/skills` (`$DSH_AGENTS_HOME/skills` when configured); Harness
discovers that directory, and its native `skill` tool can load
`reverse-engineer-anything`.
REA's optional [native client verification](testing.md#end-to-end-integration-and-golden-evidence)
checks headless chat, skill loading, all tool input schemas and actual analysis
using the installed Harness and a local model fixture. This establishes the
Harness integration, with live DeepSeek API compatibility remaining unverified.
See the [Harness MCP guide](https://github.com/deepseek-ai/deepseek-harness/blob/639ed015397290b3745d163aafe02ffee4aa3f84/packages/mcp/mcp-client/README.md)
for its native configuration contract.
### Other client settings
See [OpenCode, Grok Build, and Grok Bot settings](client-configuration.md#other-client-settings).
For OpenCode, setup writes the V1 `mcp.rea` entry, which OpenCode V1 and V2
both load. If the configuration already uses OpenCode V2's native
`mcp.servers` table, setup registers REA there instead and replaces any earlier
`mcp.rea` entry from REA. Setup honors `OPENCODE_CONFIG_DIR` and
`OPENCODE_CONFIG`, preferring the later-loaded JSONC file when both JSON and
JSONC exist. The ordinary XDG global configuration still participates when a
custom directory is selected. Doctor checks the merged user registration; uninstall removes
REA-owned entries from every applicable user file so an older entry cannot
become active again. Malformed applicable files block setup before changes.
Grok Build loads `[mcp_servers.rea]` from `$GROK_HOME/config.toml`, or from
`~/.grok/config.toml` when `GROK_HOME` is unset or empty. Setup edits that server
table, `[mcp_servers.rea.env]`, and a root `disabled_mcp_servers` entry that
names `rea`. It sets `startup_timeout_sec = 30` and leaves every other name
in that list. The shared skill installed under `~/.agents/skills` is already
on Grok Build's skill path.
Grok Bot (`grok_bot`) is detected from `~/.grokbot`, or from `SAND_DATA_ROOT`
when that value is an absolute path. A relative or empty `SAND_DATA_ROOT`
stays on `~/.grokbot`. That directory is not the connector store. Grok Bot
keeps connectors in the signed-in account and runs them on its hosted
computer. It does not import `mcp.json` from the data directory, and it does
not attach a stdio server running on this machine. Setup does not call the
account connector API, does not write a registration file, and does not report
the data directory as aligned. Ask the Grok Bot chat to add a custom MCP
server named `rea` that runs on the Bot's computer:
```bash
npx -y rea-agents@<version> mcp
```
Do not put credentials in that command or its arguments. `rea doctor --client grok_bot`
reports this manual step. `rea uninstall` does not remove the account connector.
## Review setup changes
`rea setup` first offers the supported agents in a multi-select. Existing REA
registrations are selected by default. Newly detected clients remain available
but unselected: detection gives setup context, not permission to add a new
registration. Clients without a detected configuration can still be selected.
Explicit `--client` flags skip this question.
Setup adds MCP access for selected clients. It installs REA's bundled workflow
with those integrations by default; use `--skill=false` to omit it. If no agent
is selected, setup offers the workflow separately for CLI use, with No as the
default. Hopper is a separate optional choice: setup shows its proposed
installation or connection and requires its own explicit approval. It can also
save verified paths for an existing Ghidra installation.
The bundled skill is installed where each selected client discovers personal
skills: Claude Code uses `~/.claude/skills` (or
`$CLAUDE_CONFIG_DIR/skills` when configured). Gemini CLI uses `.agents/skills`
under its selected home; Antigravity 2.0 uses `~/.gemini/config/skills`.
Other integrations, including Qwen Code, use `~/.agents/skills`.
A mixed selection plans each distinct destination. Selecting the skill without a client uses the shared
directory. Setup leaves existing skill copies in other locations untouched.
`rea setup --skill-client claude_code --yes --json` refreshes and verifies the
selected skill destination independently of MCP registration selection. The
final `doctor.scope.skill_clients` records which skill destinations were
checked; `doctor.scope.clients` continues to describe required registrations.
An unselected shared skill does not affect a client-only refresh.
`doctor --skill --json` verifies the selected copies against the bundled
instructions and references. Consumers should use `identity.skill.state`,
`installed_version`, and `installed_tool_count` for skill readiness. The
obsolete `installed_catalog_digest` field has been removed; current catalog
identity remains available at `identity.catalog`.
After selection, review the plan's exact paths and changes and approve before
REA writes files or installs Hopper. You can cancel at any prompt.
Before applying changes, REA checks your current configuration. The plan lists:
- an existing Hopper installation, a verified existing Ghidra installation, or the official Hopper package it proposes to install;
- each detected agent configuration path;
- each selected REA skill destination;
- external software, network origins, integrity evidence, and package-manager
commands.
Malformed or unsafe existing configuration blocks the whole transaction before
Hopper installation or any file write. Declining or pressing Ctrl-C makes no
changes. Agent configuration writes preserve unrelated entries and comments,
create backups, use atomic replacement, and verify their result. Setup and
uninstall retain an existing `.rea.backup` rather than replacing the first snapshot.
Setup also retains valid environment overrides in REA's existing server entry,
such as `REA_MCP_INPUT_SCHEMA_PROFILE` and `REA_MCP_MAX_RESPONSE_BYTES`.
Detected provider settings replace only matching environment keys.
Setup and doctor report a malformed REA environment map or invalid runtime
setting before setup writes files. Repair the named setting in the client
configuration; setup does not silently discard the rest of the map.
After setup, REA reports which agents, analysis tools, and workflow files passed
its final checks. Restart any agent named in the completion message, then begin
your investigation. Failed steps and diagnostics remain in terminal history.
Select exact clients in scripts with repeatable `--client` flags. Each explicit
client skips interactive selection. Use `--all-detected` only when you intend
to configure every detected supported client. `--skill=false` omits the
workflow, and `--dry-run` returns a read-only plan with status `planned` and
exit code 0:
```bash
rea setup --client codex --client cursor --skill=false --dry-run
```
Prompt UI and progress are written to stderr so stdout remains available for
structured results and pipelines. `NO_COLOR=1` disables color. Use
`--accessible` for sequential, vertically rendered yes/no prompts. Implicit
interactive setup requires stdin, stdout, and stderr to all be terminals; when
any stream is redirected, setup stays non-interactive. Declining or cancelling
returns status `cancelled` with exit code 0.
For automation, `rea setup --json` reports the plan and a compact `.doctor`
readiness projection without applying it. Use `rea doctor --json` for full
health diagnostics and canonical tool catalog details. Pair
`--yes` with explicit scope such as `--client codex`, or use
`--all-detected` when the broad scope is intended. Without a scope flag,
`--yes` is limited to existing REA-owned registrations; it does not select all
detected clients. An unapproved actual apply reports `needs_confirmation` and
exits 1. Installing missing Hopper non-interactively additionally requires
`--install-hopper`:
```bash
rea setup --yes --all-detected --install-hopper --json
```
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. `rea update` installs the exact resolved
release into the npm prefix or Bun global directory that owns the running
package, then checks the new executable's version before reporting success. It
does not reopen onboarding. For npm installations, release lookup and
installation both use npm's configured registry. Bun global updates require
Bun 1.2.17 or later, which introduced `bun info`. The updater checks `bun --version`
first and stops with an instruction to upgrade Bun manually if the version is
older or cannot be parsed; it does not upgrade Bun itself.
For supported Bun global installations, `bun info` and
`bun add --global --ignore-scripts` use Bun's configured registry
and run inside the owning Bun global directory (`BUN_INSTALL_GLOBAL_DIR`, else
`$BUN_INSTALL/install/global`, else `$XDG_CACHE_HOME/.bun/install/global`,
else `~/.bun/install/global`), never in the caller's current project. A Bun
global directory without its `package.json` is not treated as an owned
installation, because Bun would install into the nearest ancestor project
instead.
Its maintenance plan selects only existing REA registrations and an already
installed REA skill. Run the returned scoped setup command to review and approve
those changes, then restart affected agents. The plan is returned in terminal,
non-TTY, and JSON modes without applying configuration changes.
## Check readiness for your task
Run `rea doctor` when you need diagnosis. It reads host prerequisites and agent
configuration without changing them. Without options, it audits every detected
registration, the installed skill and optional analysis engines; its overall
`healthy` value can be false while your chosen workflow works.
Select the part you want to check:
| Task | Readiness check |
| ----------------------------------- | ------------------------------------------------------------------------ |
| Static JavaScript/Electron analysis | Run `rea analyze-javascript-application PATH --json` directly. |
| One analysis engine | `rea doctor --provider ghidra --json` (or `hopper`, `ida`) |
| One agent registration | `rea doctor --client codex --json` (see [client IDs](#supported-agents)) |
| Installed workflow instructions | `rea doctor --skill --json` |
A scoped report has `scope.mode: "explicit"`. Its `scope_checks` determine
`healthy` and the exit status. Other checks appear in `informational_checks`;
`environment_healthy` summarizes the full audit. `--target` adds a target check,
but the report remains audit-wide unless a scope option is also supplied.
Follow the remediation for the failed check. If a native target has several
available providers, choose one with `--provider` on the CLI or `provider_id`
on `open_binary`. A `capability_unavailable` failure carries
`details.selection_reason`: `ambiguous` asks you to choose from
`details.candidate_ids`, while `provider_unavailable` asks you to repair the
selected engine. See [provider selection](cli.md#choose-a-provider).
## Hopper
@@ -317,8 +536,8 @@ The Hopper launcher action used by REA creates a document from an executable;
its supported command-line interface does not attach to an already-open
document. While another live REA session owns the same target and loader
profile, a second session reports the owning run ID instead of opening a
duplicate document. On macOS, closing the owning REA session releases this guard;
Hopper keeps its document open. A later REA session can therefore open another
duplicate document. Closing the owning REA session releases this guard; Hopper
keeps its document open. A later REA session can therefore open another
document for the same target. REA does not currently identify, focus, or reuse
that existing GUI document, and the supported launcher exposes no attach or
reuse action for it.
@@ -341,14 +560,8 @@ Hopper application per user across cooperating REA processes. A competing
CLI or MCP session receives the owning session ID before Hopper is launched,
for both the same target and a different target. Switch targets through that
MCP session, or close it before starting another session. Closing the owner
releases the reservation and stops REA's owned demo application and private
display; the headless Linux demo does not retain documents after MCP shutdown.
Its helper watches a private lifetime pipe, so an owner crash or SIGKILL also
stops those children, without relying on a reusable PID or a process-name scan.
A later session recovers the dead owner's stale lease after child cleanup;
private runtime files can remain when REA itself was killed. This does not attach to
or claim ownership of manually opened Hopper applications. An application left
running by an older REA version must still be closed before starting a new session.
releases the reservation. This does not attach to or claim ownership of
manually opened Hopper applications.
Stale lease recovery is serialized. If an interrupted recovery leaves its
reservation directory, the diagnostic identifies that exact path. Stop REA
@@ -437,13 +650,33 @@ code or signal and bounded output in `details.launcher`. An exit can precede
output-stream closure; `output_closed: false` keeps that uncertainty explicit.
Later requests retain the known exit instead of reducing it to socket loss.
An external GUI's helper exit does not establish that the GUI itself exited.
For cursor navigation, string decoding, symbol-name limits, and regex matching,
see [Hopper analysis behavior](native-investigation.md#hopper-analysis-behavior).
Cursor navigation returns the observed object start when Hopper snaps an interior
address; adjacent-object navigation rejects unmapped inputs and document ends.
Native API text rejects NUL characters and unpaired Unicode surrogates before
annotation changes. Renames preserve unselected label owners; use a batch with
all affected addresses to move or swap existing labels explicitly. Every rename
destination must be mapped, and native symbol names must fit Hopper's 1024 UTF-16
code-unit limit. Oversized names fail before any batch edits; bookmarks and
literal string results are not subject to that symbol-name limit. Rename success
requires exact final readback. New bookmarks must point into mapped memory;
existing legacy bookmarks outside it can still be removed.
String results read each native typed object's complete bytes, retain the original
provider display in `provider_value`, and report its encoding, byte length, and
termination. `encoding_status: inferred` distinguishes REA's decoding from an
observed source encoding. Hopper can split long literals into adjacent
unterminated objects; search matches each object's decoded bytes independently.
Undecodable objects retain native display text with `decoding.available: false`
and a reason, so one uncertain object does not block unrelated inspections.
Function dossiers retain this same string evidence. Native call edges retain
Hopper's partial `CallReference` classification and exact endpoints; detailed
reference flags remain unavailable rather than being invented.
Regex searches use ECMAScript Unicode syntax in a cancellable worker with a
five-second matching deadline. Deadline or cancellation stops matching while
leaving the Hopper API available. Literal mode retains Unicode casefold matching.
Closing or switching a target closes its bound Hopper document, shuts down REA's
bridge and removes its temporary socket directory. The macOS Hopper application
and unrelated documents remain open; the owned Linux demo application stops.
A `cleanup_incomplete`
bridge and removes its temporary socket directory while preserving the Hopper
application and unrelated documents. A `cleanup_incomplete`
result identifies resources whose cleanup could not be verified.
REA retains unresolved cleanup ownership and any confirmed shutdown phases.
After addressing the reported failure, retry `close_binary` on the same
@@ -499,8 +732,7 @@ operations and twelve function-analysis operations. These cover metadata,
decompilation, assembly, resolved calls, typed references, xrefs, function
dossiers, instructions, recovered data types, measured load mappings, loaded
memory bytes, and observed file offsets. Independent load-image attestation
supports DOS MZ, explicitly selected COM, and explicit raw-binary imports;
PE returns measurements with an unsupported attestation status.
supports DOS MZ and explicitly selected COM; PE returns its measurements with that limitation.
On Linux and macOS, `annotate_native_function` also edits a function name and/or
entry comments atomically and returns refreshed analysis, and `set_address_name`
and `set_addresses_names` name a function entry or any other mapped address
@@ -553,7 +785,7 @@ Ghidra's default analysis settings, and loads its packaged Java
bridge via `-scriptPath`; it never opens an existing user project. Linux and
macOS use a current-user-only local bridge socket and descriptor. The
project remains under the selected temporary directory. If its Unix socket
pathname would exceed the host's byte limit, REA allocates a separate owner-only
pathname would exceed the host's byte limit, REA allocates a separate mode-0700
socket directory under `/tmp` and removes it on close, cancellation, or failure.
Diagnostics retain the actual endpoint and both owned directories.
On Linux and macOS, REA starts the inspected JVM directly using Ghidra's own LaunchSupport
@@ -610,39 +842,12 @@ rea doctor --json
The copy step requires the destination to be absent and preserves an existing
decompiler. This recipe is specific to macOS x64: the
[Ghidra 12.1.4 Makefile](https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1.4_build/Ghidra/Features/Decompiler/src/decompile/cpp/Makefile)
explicitly selects `-arch x86_64` on Darwin. For a Gradle
explicitly selects `-arch x86_64` on Darwin. For other architectures or a Gradle
build, follow the matching release's
[native component instructions](https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1.4_build/GhidraDocs/GettingStarted.md#building-native-components).
REA accepts the matching executable under either `os/<platform>/` or
`build/os/<platform>/`; it does not build the component during setup or diagnosis.
### macOS arm64 native decompiler
On Apple Silicon the same source build works with explicit overrides; no
Makefile edits and no Rosetta are needed. The Darwin block in the
[Ghidra 12.1.4 Makefile](https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_12.1.4_build/Ghidra/Features/Decompiler/src/decompile/cpp/Makefile)
pins `-arch x86_64`, but `ARCH_TYPE` and `OSDIR` are ordinary make variables,
and command-line assignments replace them for every compile and link rule:
```bash
cd "$GHIDRA_INSTALL_DIR/Ghidra/Features/Decompiler/src/decompile/cpp"
make ghidra_opt ARCH_TYPE="-arch arm64" OSDIR=mac_arm_64
decompiler_dir="$GHIDRA_INSTALL_DIR/Ghidra/Features/Decompiler/os/mac_arm_64"
mkdir -p "$decompiler_dir"
test ! -e "$decompiler_dir/decompile" && test ! -L "$decompiler_dir/decompile" &&
install -m 755 ghidra_opt "$decompiler_dir/decompile"
rea doctor --json
```
Verified end to end on macOS 15.6 arm64 with Apple clang 17 and the stock
bison 2.3, against Ghidra 12.1.4: the build produces a Mach-O arm64
`ghidra_opt`, the doctor check `ghidra-native_decompiler` turns healthy with
"reports mach-o arm64, which matches darwin/arm64", and `rea decompile` on an
arm64 Mach-O returns decompiled C through the headless provider. The JDK is
not needed for the make step, only for the Ghidra provider. If your toolchain
rejects the inherited `-mmacosx-version-min=10.6` flag, retry the make with
`ADDITIONAL_FLAGS="-w"`.
### Ghidra import language and analysis seeds
Ghidra detects the language from the executable header. To set it (for example, Borland C++ PE images):
@@ -777,6 +982,25 @@ read-only operations, digest identity, and runtime cleanup. The separate
ordinary user. It requires the built Windows native bundle and an existing
Ghidra/JDK installation; neither is inferred from startup alone.
## Diagnose, update, and remove
`rea doctor --json` is strictly read-only. `rea update` updates only the npm or Bun global installation that owns the running CLI. Source checkouts and package-runner copies must be updated through the mechanism that owns them; a fresh package-runner invocation can use `npx rea-agents@latest` or `bunx rea-agents@latest`. `rea uninstall` removes only REA-owned agent registrations and skill files; `--purge-data` additionally removes REA cache and state paths.
```bash
rea update
rea uninstall
rea uninstall --purge-data
```
Uninstall preserves Hopper, Node.js, Evidence files, captures, unrelated skills
and other MCP servers. Purging removes only REA's cache and state under
`~/.rea`. A client configuration that is malformed, unreadable, or at an unsafe
path stops the operation before anything is removed, and a client that fails
while being updated stops the remaining removals. A purge path that is a
symbolic link is retained and reported rather than followed. Uninstall checks
REA's managed shared and Claude Code personal skill locations. See the
[CLI guide](cli.md#output-and-exit-status) for exit statuses.
## MCP Registry
REA is published in the official MCP Registry as `io.github.morluto/rea`. Registry
@@ -809,71 +1033,3 @@ writes the same package-runner shape, or `bunx rea-agents@<version> mcp` when
setup runs through `bunx`, and pins it to the exact version that performed
setup. Run current setup to refresh an older registration, then restart the
client.
## Package runners and global installation
A package-runner invocation can use a REA version installed in the current project. To
request the latest release explicitly, use:
```bash
npx rea-agents@latest setup
```
REA runs the version npm selects. To update older agent registrations, run the
latest-version command and review its setup plan. For unattended package
downloads, add `--yes` before the package name; this does not approve REA's
setup changes.
For an intentional rollback, make the package request explicit:
```bash
npm exec --yes --package=rea-agents@2.4.0 -- rea setup
```
Setup continues to pin persistent MCP registrations to the exact version that
performed setup. Running current setup later migrates unversioned or older
managed registrations through the normal reviewed setup transaction.
With Bun, `bunx rea-agents setup` (or `bunx rea-agents@latest setup`) is the
equivalent entry point. Setup run through `npx` registers
`npx -y rea-agents@<version> mcp`; setup run through `bunx` or `bun x` registers
`bunx rea-agents@<version> mcp`. On Windows, setup wraps either command in
`cmd.exe /d /c` so clients can start the runner's command shim. Neither
registration points into the runner's temporary package cache.
REA supports Node.js 22.x (>=22.19), 24.x (>=24.11), and 26+. Node.js 23, 25, and prereleases are unsupported. It uses the npm already paired with that runtime and never upgrades Node.js, npm, or Homebrew.
When REA runs on Bun, the `rea doctor` `node` check reports the Bun version and
the Node.js compatibility version Bun declares, and passes when that
compatibility version is in the supported range. Bun does not enforce the V8
heap flags REA gives its owned helper processes, so Evidence that reports those
limits on Node.js records them as unavailable under Bun. On Windows, the owned
Job Object of each JavaScript helper (source analyzer, source-map codec and HAR
decoder) instead limits its committed memory to that helper's heap budget plus
a 512 MiB reserve for Bun itself, and Evidence reports that limit. This needs
the matching bundled Windows native artifact; an artifact without the control
refuses to start the helper rather than running it unlimited. CI tests Node.js
only.
Running `npm install rea-agents` without `--global` installs the executable only
in the current project's `node_modules/.bin`; it does not make `rea` available
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.
The optional curl wrapper installs only the global npm package:
```bash
curl -fsSL https://raw.githubusercontent.com/morluto/rea/main/install.sh | bash
```
It prints the version, runtime, npm command, and destination before installing. When a controlling terminal exists it starts `rea setup`; otherwise it prints the command to run later.
Pass options with `bash -s --`:
```bash
curl -fsSL https://raw.githubusercontent.com/morluto/rea/main/install.sh |
bash -s -- --dry-run
```
Supported options are `--version <semver>`, `--dry-run`, `--no-setup`, `--no-prompt`, and `--verbose`. Neither `--no-prompt` nor a non-interactive shell grants permission to install external dependencies.
+3 -6
View File
@@ -156,12 +156,9 @@ to the comparison Evidence in a live session.
`compare_source_to_bundle` compares one cryptographically committed
`HistoricalSourceGraph` with authenticated application-graph Evidence. The
stable scoring model reports every admitted signal and weight: exact source
digest, source-map original path, exact current path, path suffix, Unicode-
equivalent path, basename, and language extension. Exact digest wins over
location inference; weak basename, extension, and Unicode-equivalence evidence
never forces a mapping. Unicode-equivalent spellings are candidate evidence
only because distinct filesystem paths can preserve those spellings as separate
files; multiple canonical-equivalent candidates remain unknown.
digest, source-map original path, exact current path, path suffix, basename, and
language extension. Exact digest wins over location inference; weak basename
or extension evidence never forces a mapping.
Each historical source file is classified as `unchanged`, `modified`,
`removed`, `split`, `merged`, `duplicated`, or `unknown`. Multiple equally
+168 -189
View File
@@ -1,14 +1,19 @@
# JavaScript artifact reconstruction
Inspect a local Electron/JavaScript directory or ASAR without executing its code.
`analyze_javascript_application` and the CLI routes below return an Evidence
record with the [application graph](javascript-application-graph.md), static
Electron observations, statistics, limitations, and coverage.
REA can project an operator-supplied Electron/JavaScript application directory
or ASAR into [JavaScript Application Graph](javascript-application-graph.md)
without executing application code. The target-free
`analyze_javascript_application` MCP tool, dedicated
`rea analyze-javascript-application` CLI command, and generic
`rea analyze PATH` directory/ASAR route expose the same application
service and return an Evidence envelope containing the graph and an Electron
boundary summary.
Start with the [public workflow](#public-workflow), select sources when useful,
then [read the analysis](#read-the-analysis). Use [application workflows](javascript-application-workflows.md)
for tracing and comparisons, or [partial recovery](#recover-partial-analysis)
when an operation is interrupted.
The resulting Evidence can be combined with passive web or Electron capture
Evidence through
[`reconcile_javascript_runtime`](javascript-runtime-reconciliation.md). That
second operation does not rerun static analysis or contact CDP; it preserves
separate static, runtime, and cross-layer inference authorities.
## Public workflow
@@ -100,7 +105,141 @@ only reduces delivery; source selection reduces text acquisition and analysis.
Explicit native provider or snapshot routing rejects `--source-path` rather
than ignoring it.
## Read the analysis
## ASAR integrity
ASAR inventory checks Electron integrity metadata for embedded archive entries
and supplied `.asar.unpacked` companion files. An integrity failure identifies
the logical path, declared and calculated SHA-256 values, and whether the entry
was unpacked. By default, a mismatch is returned as a failure with its artifact
context. Application analysis can explicitly select `record-and-continue` to
analyze observed bytes while retaining each contradiction's declared and
observed hashes and `observed-untrusted` trust. Such results mark application
graph coverage partial and include every contradicted path in the limitations.
Mismatched nested ASARs stay opaque rather than being expanded. An unpacked
entry whose companion bytes were not supplied remains `unavailable`.
An unpacked entry whose companion bytes were not supplied remains
`unavailable`. REA continues analyzing embedded JavaScript and records the
missing native/resource bytes as unknown. See [what is reconstructed](#what-is-reconstructed)
for the inventory fields and [MCP integrity handling](mcp-contracts.md#integrity-record-and-continue)
for the tool-result contract.
## Large results
Application analysis projects semantic relationships one source file at a time.
After projection, it retains only the lexical module facts and exported return
shapes needed to build application relationships. Full source IR does not stay
resident for every file together. Callable ownership and contained-reference
queries use per-file range indexes, while call sites use exact-range lookups.
Existing node budgets and coverage reporting remain in effect.
Progress identifies the source file being parsed and projected. Cancellation is
checked between files and throughout result transfer. The owned analyzer can
be stopped while its synchronous parser or semantic extractor is active;
the CLI/MCP process remains available for control requests.
Graph and Evidence identifiers hash canonical JSON incrementally, without
assembling a single string for the whole graph. The canonical bytes and existing
identifiers remain unchanged. The opt-in regression check is
`npm run verify:javascript:digests`;
it hashes a value larger than the running Node engine's single-string limit.
Both application CLI routes stream complete JSON and JSONL output in bounded
chunks, including field filters and `--full-output`. They wait for each stdout
write instead of constructing or reparsing a document-sized string. The opt-in
`npm run verify:javascript:output` checks the actual CLI formatting boundary with
a temporary output file larger than the running engine's string limit, verifies
its bytes and digest, and removes it. Use `-- jsonl` for the compact JSONL check.
Each check needs space for one output file plus a 1 GiB free-space reserve.
Other CLI formats and `--token-count` still assemble whole strings.
Field selection remains useful when the caller needs a
smaller view, for example `--format json --filter-output
evidence_id,normalized_result.statistics`. Streaming output does not bound the
memory needed to construct the analysis graph itself.
JavaScript source parsing, static analysis and semantic projection run in one
owned analysis process, reused sequentially across files. Target code is never
executed. The analyzer defaults to 1024 MiB of V8 old-space and a 300000 ms
deadline per source, including startup and fact transfer. Select
`max_heap_mb` and `analysis_timeout_ms` through MCP, or `--max-heap-mb` and
`--analysis-timeout-ms` on the dedicated CLI command. These choices control the
analyzer; the caller's `NODE_OPTIONS` still controls the CLI/MCP process heap.
V8 old-space limits do not impose a process RSS limit. When REA runs on Bun,
the analyzer ignores the V8 heap flags; resource failures then report
`worker_heap_limit_bytes` as null instead of a requested or V8-reported limit.
On Windows, the analyzer's owned Job Object instead limits its committed
memory to `max_heap_mb` plus a 512 MiB reserve for Bun itself (1536 MiB by
default). Reaching it fails the current source with the same memory resource
failure and reports `worker_process_memory_limit_bytes`, also a coverage limit;
the next source starts a new analyzer. Bun elsewhere enforces no analyzer limit.
The default semantic capacities are 100000 nodes across the application and
20000 per source. Large bundles may explicitly select `max_semantic_nodes` and
`max_semantic_nodes_per_file` (CLI: `--max-semantic-nodes` and
`--max-semantic-nodes-per-file`), each from 1 to 1000000. The per-file offer is
also bounded by the remaining application capacity. Raising these controls does
not bypass worker heap, execution deadline or parent result admission. Truncated
coverage reports both effective node ceilings; omitted relationships remain
unknown.
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
remaining inventory does not multiply the reserve. Streamed file transfers keep the default 512 MiB
allowance, and can grow with the parent's offered retention budget (8x byte
expansion), up to 2 GiB. Individual records remain bounded to 8 MiB. The parent
still independently checks actual bytes, record overhead, digests and source
identities before adopting results.
A source that exhausts the analyzer heap does not terminate the CLI/MCP
process. Completed static facts are retained, other files can still be analyzed,
and unexamined semantic relationships remain explicit unknowns. The parent
also checks transfer expansion and accumulated results against its remaining
heap before accepting semantic facts. A resource-limited result has partial
coverage, the observed limits and an `analyze-javascript-source` unknown scope
with the specific failure, including captured diagnostics when available.
Resource failures do not increment syntax parse failures. There is no fixed
source-length cutoff.
Static observations also need memory when expanded into nodes, relationships
and Evidence. If that expansion does not fit, the file node retains
`static_analysis` and any admitted `semantic_module_analysis` observations,
including their exact values and source locations. Use the public modules item
view to read them. The graph marks those unexpanded relationships as unknown.
If cumulative result capacity is exhausted, analysis stops; inventoried but
unexamined files remain present with explicit unknown scopes.
A timeout stops the remaining analysis and returns typed failure details with
completed partial Evidence. MCP failure details return
`partial_observation: { kind: "retained-evidence", evidence_id: "..." }`
after recording succeeds, so `inspect_analysis_view` can open that analysis
directly without serializing the entire partial graph into the error response.
CLI failure output retains the complete partial Evidence.
Cancellation after source analysis begins likewise retains completed facts,
including cancellation during analyzer cleanup, graph construction, or Evidence
sealing. REA finishes projecting those owned facts cooperatively to return partial
Evidence. An SDK client may reject its cancelled request before receiving that
reply. On the same MCP connection, inspect the Evidence bundle
and use the retained analysis ID with `inspect_analysis_view`. Owned analyzer
cleanup is verified before its private files are released. Cleanup uncertainty
is reported separately and retains ownership for retry.
CLI workflows parse larger JSON input files incrementally from one verified
regular-file handle, without constructing a document-sized string. Smaller
files retain native JSON parsing. Both paths require strict JSON and valid
UTF-8, and return one complete value; the assembled object still needs memory.
An individual JSON string exceeding the native length limit or the available
heap headroom for assembly returns
`resource_constraint` with `input_reason: "too-large"`. Supply a smaller valid
value; for Evidence workflows, re-analyze a smaller selection of the original
target and use its complete Evidence. Splitting JSON text or trimming Evidence
fields does not produce a valid workflow input.
Evidence bundle and analysis snapshot file readers still decode whole
documents. Their runtime string-limit failures report a resource constraint
with the selected path, observed bytes and UTF-16 limit, rather than malformed
JSON.
`analyze_javascript_application` returns the complete analysis Evidence by
default. Select `"detail": "summary"` to retain that complete Evidence in the
@@ -112,82 +251,18 @@ workflows as a retained reference. The summary does not repeat or truncate the
analysis; a server without session retention refuses summary detail with
`capability_unavailable`. CLI output is unchanged and always complete.
With a connected MCP `client` and the caller-selected absolute `inputPath`, this
recipe analyzes once and pages module identities using the returned ID:
```js
const analysis = await client.callTool({
name: "analyze_javascript_application",
arguments: { input_path: inputPath, detail: "summary" },
});
if (analysis.isError) throw new Error(JSON.stringify(analysis.content));
const parentId =
analysis.structuredContent.normalized_result.parent_evidence_id;
const modules = await client.callTool({
name: "inspect_analysis_view",
arguments: {
source: { kind: "retained-evidence", evidence_id: parentId },
view: { kind: "page", collection: "modules", offset: 0, limit: 16 },
},
});
if (modules.isError) throw new Error(JSON.stringify(modules.content));
```
Select a returned module's exact `node_id` for an item view. A path can identify
several graph roles; module items preserve their recorded properties and source
locations. Follow `coverage.next_offset` when another page matters. For feature
tracing, version comparison, and retained-input examples, use the
[application workflows](javascript-application-workflows.md).
For supplied passive browser or Electron observations, use
[runtime reconciliation](javascript-runtime-reconciliation.md). It compares
existing Evidence without rerunning static analysis or contacting CDP.
## ASAR integrity
ASAR inventory checks Electron integrity metadata for embedded archive entries
and supplied `.asar.unpacked` companion files. An integrity failure identifies
the logical path, declared and calculated SHA-256 values, and whether the entry
was unpacked. By default, a mismatch is returned as a failure with its artifact
context. Application analysis can explicitly select `record-and-continue` to
analyze observed bytes while retaining each contradiction's declared and
observed hashes and `observed-untrusted` trust. Such results mark application
graph coverage partial and include every contradicted path in the limitations.
Mismatched nested ASARs stay opaque rather than being expanded.
An unpacked entry whose companion bytes were not supplied remains
`unavailable`. REA continues analyzing embedded JavaScript and records the
missing native/resource bytes as unknown. The occurrence keeps
`hash_status: unavailable`; no content-addressed child artifact is created for
those missing bytes. See [MCP integrity handling](mcp-contracts.md#integrity-record-and-continue)
for the tool-result contract.
## Large results
Use MCP `detail: "summary"` for a large application, then read selected views of
the retained analysis. Summary changes delivery only. To reduce source parsing,
select exact [source paths](#select-sources-before-analysis).
If a complete response exceeds the transport budget, use its retained Evidence
ID for a summary, module page, or item, or export the bundle. See
[MCP tool results](mcp-contracts.md#tool-results) for delivery limits, export, and
matching server/client buffer settings. Follow-up results also need to fit that
budget. [Analyzer limits](#analyzer-and-result-admission) control analysis memory,
source deadlines, and semantic capacity separately.
## Recover partial analysis
A source timeout stops the remaining analysis and returns completed facts as
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.
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)
to find the record. CLI failure output contains the complete partial Evidence.
Owned analyzer cleanup is verified before private files are released; uncertain
cleanup retains ownership for retry and is reported separately.
MCP prepares the complete repeated response incrementally against the pinned
SDK's 10 MiB stdio receive-buffer budget. Oversized results return an actionable
transport constraint and the exact same-session Evidence reference. Use
`inspect_analysis_view` with the retained Evidence ID for a summary, one
module, or a stable page of module identities. Use `trace_application_feature`
once a module, route, or string seed is known, or `export_evidence_bundle` to
write the complete canonical bundle without a document-sized allocation.
Same-session analysis reads reuse authenticated immutable snapshots; foreign
inline Evidence is still parsed and authenticated.
See [MCP tool results](mcp-contracts.md#tool-results) for larger client buffers
and `REA_MCP_MAX_RESPONSE_BYTES`. Follow-up results remain complete and can also
exceed the transport budget.
## What is reconstructed
@@ -204,6 +279,14 @@ execute them.
JavaScript and HTML source ranges retain an initial UTF-8 BOM as one UTF-16
code unit, matching the original bytes identified by the artifact digest.
If an ASAR declares an unpacked companion entry but the corresponding
`<archive>.unpacked` file is absent from the operator-supplied artifact set, REA
keeps the ASAR occurrence with `hash_status: unavailable`, records an explicit
limitation, and does not create a content-addressed child artifact for those
missing bytes. This allows static JavaScript/Electron reconstruction to proceed
for the embedded files while preserving the missing native/resource bytes as an
unknown instead of silently treating them as absent or verified.
Plain `.ts` artifact sources use TypeScript syntax without JSX, including
angle-bracket type assertions. `.tsx` and `.jsx` retain JSX parsing.
@@ -433,110 +516,6 @@ and inventoried containment edge is retained. If parsing or artifact safety
boundaries omit input, coverage reports that omission; when an exact omission
count is not knowable, `omitted_count` is `null` rather than a guessed value.
### Analyzer and result admission
Application analysis projects semantic relationships one source file at a time.
After projection, it retains only the lexical module facts and exported return
shapes needed to build application relationships. Full source IR does not stay
resident for every file together. Callable ownership and contained-reference
queries use per-file range indexes, while call sites use exact-range lookups.
Existing node budgets and coverage reporting remain in effect.
Progress identifies the source file being parsed and projected. Cancellation is
checked between files and throughout result transfer. The owned analyzer can
be stopped while its synchronous parser or semantic extractor is active;
the CLI/MCP process remains available for control requests.
Graph and Evidence identifiers hash canonical JSON incrementally, without
assembling a single string for the whole graph. The canonical bytes and existing
identifiers remain unchanged. The opt-in regression check is
`npm run verify:javascript:digests`;
it hashes a value larger than the running Node engine's single-string limit.
Both application CLI routes stream complete JSON and JSONL output in bounded
chunks, including field filters and `--full-output`. They wait for each stdout
write instead of constructing or reparsing a document-sized string. The opt-in
`npm run verify:javascript:output` checks the actual CLI formatting boundary with
a temporary output file larger than the running engine's string limit, verifies
its bytes and digest, and removes it. Use `-- jsonl` for the compact JSONL check.
Each check needs space for one output file plus a 1 GiB free-space reserve.
Other CLI formats and `--token-count` still assemble whole strings.
Field selection remains useful when the caller needs a
smaller view, for example `--format json --filter-output
evidence_id,normalized_result.statistics`. Streaming output does not bound the
memory needed to construct the analysis graph itself.
JavaScript source parsing, static analysis and semantic projection run in one
owned analysis process, reused sequentially across files. Target code is never
executed. The analyzer defaults to 1024 MiB of V8 old-space and a 300000 ms
deadline per source, including startup and fact transfer. Select
`max_heap_mb` and `analysis_timeout_ms` through MCP, or `--max-heap-mb` and
`--analysis-timeout-ms` on the dedicated CLI command. These choices control the
analyzer; the caller's `NODE_OPTIONS` still controls the CLI/MCP process heap.
V8 old-space limits do not impose a process RSS limit. When REA runs on Bun,
the analyzer ignores the V8 heap flags; resource failures then report
`worker_heap_limit_bytes` as null instead of a requested or V8-reported limit.
On Windows, the analyzer's owned Job Object instead limits its committed
memory to `max_heap_mb` plus a 512 MiB reserve for Bun itself (1536 MiB by
default). Reaching it fails the current source with the same memory resource
failure and reports `worker_process_memory_limit_bytes`, also a coverage limit;
the next source starts a new analyzer. Bun elsewhere enforces no analyzer limit.
The default semantic capacities are 100000 nodes across the application and
20000 per source. Large bundles may explicitly select `max_semantic_nodes` and
`max_semantic_nodes_per_file` (CLI: `--max-semantic-nodes` and
`--max-semantic-nodes-per-file`), each from 1 to 1000000. The per-file offer is
also bounded by the remaining application capacity. Raising these controls does
not bypass worker heap, execution deadline or parent result admission. Truncated
coverage reports both effective node ceilings; omitted relationships remain
unknown.
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
remaining inventory does not multiply the reserve. Streamed file transfers keep the default 512 MiB
allowance, and can grow with the parent's offered retention budget (8x byte
expansion), up to 2 GiB. Individual records remain bounded to 8 MiB. The parent
still independently checks actual bytes, record overhead, digests and source
identities before adopting results.
A source that exhausts the analyzer heap does not terminate the CLI/MCP
process. Completed static facts are retained, other files can still be analyzed,
and unexamined semantic relationships remain explicit unknowns. The parent
also checks transfer expansion and accumulated results against its remaining
heap before accepting semantic facts. A resource-limited result has partial
coverage, the observed limits and an `analyze-javascript-source` unknown scope
with the specific failure, including captured diagnostics when available.
Resource failures do not increment syntax parse failures. There is no fixed
source-length cutoff.
Static observations also need memory when expanded into nodes, relationships
and Evidence. If that expansion does not fit, the file node retains
`static_analysis` and any admitted `semantic_module_analysis` observations,
including their exact values and source locations. Use the public modules item
view to read them. The graph marks those unexpanded relationships as unknown.
If cumulative result capacity is exhausted, analysis stops; inventoried but
unexamined files remain present with explicit unknown scopes.
### Large local JSON inputs
CLI workflows parse larger JSON input files incrementally from one verified
regular-file handle, without constructing a document-sized string. Smaller
files retain native JSON parsing. Both paths require strict JSON and valid
UTF-8, and return one complete value; the assembled object still needs memory.
An individual JSON string exceeding the native length limit or the available
heap headroom for assembly returns
`resource_constraint` with `input_reason: "too-large"`. Supply a smaller valid
value; for Evidence workflows, re-analyze a smaller selection of the original
target and use its complete Evidence. Splitting JSON text or trimming Evidence
fields does not produce a valid workflow input.
Evidence bundle and analysis snapshot file readers still decode whole
documents. Their runtime string-limit failures report a resource constraint
with the selected path, observed bytes and UTF-16 limit, rather than malformed
JSON.
## Verification boundary
The source-owned fixture covers an extracted directory, a direct ASAR with an
+8 -11
View File
@@ -1,31 +1,28 @@
# JavaScript static/runtime reconciliation
REA can combine an existing static JavaScript Application Graph with one or
more browser, Electron, or Node/Electron V8 Inspector observations while
preserving their different authorities. The `reconcile_javascript_runtime` MCP tool and
more passive browser, Electron page, or Node/Electron V8 Inspector captures without collapsing their different
authorities. The `reconcile_javascript_runtime` MCP tool and
`rea reconcile-javascript-runtime` CLI command accept Evidence records and
return derived Evidence containing a combined JavaScript Application Graph
and explicit match, ambiguity, mismatch, and unknown classifications.
The operation performs no filesystem, browser, or Electron I/O. It accepts only
semantically verified Evidence produced by `analyze_javascript_application`,
`inspect_web_page`, `inspect_electron_page`, `observe_javascript_runtime`, or
`capture_electron_scenario`; matching operation names alone
`inspect_web_page`, `inspect_electron_page`, or
`observe_javascript_runtime`; matching operation names alone
is insufficient. Provider identity, predicate type, subject digest, target
parameters, and normalized-result schemas are checked before reconciliation.
`capture_electron_scenario` supplies target-only partial observations. It does
not establish loaded-script coverage; see [Electron observation](electron-observation.md).
## Workflow
1. Run `analyze_javascript_application` against exactly one application layer.
Optional cache or assets directories can be analyzed independently and
supplied as additional layers.
2. Run `inspect_web_page`, `inspect_electron_page`, or the attach-only
`observe_javascript_runtime`, or supply existing `capture_electron_scenario`
Evidence with the partial scope above. Capturing script sources is optional,
but a source capture provides the strongest byte identity.
`observe_javascript_runtime`. Capturing script sources
is optional, but a source capture provides the strongest byte
identity.
3. Pass the resulting Evidence records to `reconcile_javascript_runtime`.
Browser URLs normally need an explicit URL-prefix mapping. Extracted
Electron and V8 Inspector file locations are mapped automatically when runtime files remain
@@ -107,7 +104,7 @@ nodes. REA evaluates compatible static candidates conservatively:
Every successful cross-layer `observed_as` edge has
`authority: cross-layer-reconciliation` and `state: inferred`. The underlying
artifact/AST observations and runtime observations remain unchanged and
artifact/AST observations and passive-CDP observations remain unchanged and
retain their own Evidence links.
## Loaded, resident, and not observed
+61 -116
View File
@@ -26,61 +26,6 @@ current tool set.
The canonical tool inventory is the
[build-generated catalog](mcp-contracts.md#generated-catalog).
## Inspect an assembly
```bash
rea inspect-managed-artifact /absolute/path/Assembly.dll --json
rea inspect-managed-members /absolute/path/Assembly.dll --json
```
Use the artifact result to identify the assembly and its metadata coverage.
Member results retain build-local tokens, signatures, CIL bodies, and decoded
relationships. Use an exact reported `full_name` with `--type` when a focused
inspection is needed; see [selected member inspection](#selected-member-inspection).
Compare separate builds with [member comparison](#member-comparison), preserving
their paths, digests, and selection scope.
### Metadata overview and retained rows
The existing CLI and omitted/complete MCP detail return complete metadata
inventories. For identity and classification questions, select
`inspect_managed_artifact` with
`{"path":"/absolute/path/Assembly.dll","detail":"summary"}` on the first call.
This keeps the complete source in the session and returns a distinct linked
`inspect_analysis_view` overview with complete PE/CLI, classification and its
evidence, metadata status, module/MVID, assembly, frameworks, returned-row counts,
coverage/issues and limitations. No assembly is loaded or executed.
Use `normalized_result.parent_evidence_id` to page original rows:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": {
"kind": "managed",
"collection": "attributes",
"offset": 0,
"limit": 16
}
}
```
Collections are `references`, `resources` and `attributes`; rows retain their
original values, nulls, order, metadata tokens and offsets. Pages retain source
metadata status and coverage. Exhaustion covers the returned parent collection,
not all possible metadata, and empty rows under partial/unavailable metadata do
not establish absence. Tokens are build-local and require the recorded artifact
SHA-256 and known module MVID for cross-observation matching.
Retained views do not repeat the parser or require the source file to remain
available. Portable views use the authenticated original Evidence inline,
including the existing `inspect-analysis-view` CLI. Session record lifetime and
export/import semantics remain unchanged. A server without Evidence retention
rejects selected summary before analysis; complete delivery remains available.
## Shipped scope
The canonical parser admits PE/CLI bytes and their metadata/CIL without loading
@@ -108,12 +53,6 @@ CIL decoding, and projected inspection records have a separate conservative
output occurrences still consume that budget. These are inspection resource
policies, not PE format limits or a hard bound on total V8 heap use.
Path-based member comparison uses the same per-input snapshot policy and
inspects its two selected paths sequentially, retaining each inspection rather
than both full byte snapshots. The limit therefore remains a per-file resource
admission rule, not an aggregate comparison limit. Comparison Evidence keeps
the caller-selected paths as its parameters and artifact locations.
Input overflow returns a resource constraint. Decode or projection overflow
reports `resource-limit` with unavailable or partial coverage; omitted facts do
not become empty observations. Ambiguous PE section mappings are rejected
@@ -149,39 +88,19 @@ assembly. Older member Evidence without `selection` remains readable.
## Analysis objective
Start by identifying the artifact with `inspect_managed_artifact`, then inspect
its types and CIL with `inspect_managed_members`. Use [member comparison](#member-comparison)
for another build, and [managed/native boundary rules](#managed-native-boundaries)
when matching declared native calls to supplied native Evidence. Static inspection
does not load or execute the assembly. Reconstructed structure and unresolved
native/runtime questions retain their own authority and coverage.
REA's managed-code track is intended to answer five different questions without
collapsing them:
## Member comparison
1. What exact artifact and managed deployment form is this?
2. What do its admitted metadata and CIL bytes state?
3. What source-like or behavioral structure can be reconstructed or inferred?
4. Which findings survive an exact-build check or a cross-build structural
comparison?
5. Which remaining questions require native analysis or runtime evidence that
static inspection cannot supply?
Names and semantic labels do not establish durable member identity. Comparison
preserves observed differences, structural inferences, and unknowns separately.
Cross-version matching first prefers exact CIL/signature identity. When that
does not match, it pairs an exact declared type, method name, and raw signature
before trying structural body shape. The exact-signature key uses names only
as part of that full tuple; names alone never select a pair. Duplicate tuples
remain ambiguous rather than being paired by token order. Fields follow the
same exact tiers. The raw signature is exact whether or not REA decoded it, so
undecoded signatures pair by that tuple too, but they never enter structural
rounds. An unmatched member is therefore reported as `unknown`, not added or
removed, when its own signature was not decoded or when the other side has an
unpaired member, one-sided or ambiguous, with the same declared type and name
whose signature was not decoded.
For a matched method, an unavailable or partial body makes body-shape facets
unknown while preserving observed signature differences. Structural identity
compares normalized signatures, the limited decoded-CIL tuple fingerprint,
constants, and bounded shape context. It reports all candidates at the winning
score and remains ambiguous when the evidence does not distinguish them. The
digest does not itself remap metadata tokens.
Tokens are always remapped through observed structure. A caller cannot carry
`0x06001234` into a new MVID and assume it names the same method.
The ordinary workflow ends at question four. Static analysis never loads or
executes the target.
## NativeAOT metadata recovery
@@ -203,40 +122,24 @@ lists supported OS/architecture targets and deployment limitations, while its
[native library guide](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/libraries)
describes exported shared-library entry points.
REA offers a built-in read-only snapshot parser for x64 PE/RTR 9.1 metadata and
an optional Linux headless Ghidra adapter for annotations and broader recovery.
The adapter requires a locally built `REA_GHIDRA_NATIVEAOT_JAR`; REA does not
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 supports an optional headless adapter for the Ghidra NativeAOT analyzer.
Supply a locally built `REA_GHIDRA_NATIVEAOT_JAR`; REA does not install the
extension or its toolchain. The verified boundary is .NET 8.0.22 RTR 9.1,
x86-64 ELF and native Windows PE targets analyzed on Linux x64 with Ghidra
12.1.4 and JDK 21. Other layouts, architectures, and hosts are unsupported.
See [NativeAOT recovery](ghidra-nativeaot.md) for build/configuration, recovered
metadata, derived-memory provenance, and the real verification lane.
REA's experimental Windows Ghidra boundary admits native x86 and x86-64 PE
applications and DLLs for static analysis. This does not establish Windows
NativeAOT metadata-recovery coverage.
For NativeAOT analysis, preserve the selected native artifact's path and digest
and report recovered type data with its returned provenance. Linking those types
and report recovered type data as provider observations. Linking those types
to native function addresses requires verified
provider evidence; names or vtable similarity alone do not prove that a native
function implements a specific managed method.
<div id="managed-native-boundaries"></div>
## Managed/native boundary rules
`verify_managed_native_boundaries` compares declared P/Invoke module and entry
point identities with supplied native export or function evidence. Name/module
matches establish declaration links; they do not establish that a call executed.
Metadata tokens are not native addresses. Native body mapping for C++/CLI,
ReadyToRun, NativeAOT, and IL2CPP requires separately verified format and provider
support. The managed static tools do not recover those mappings. The optional
[Ghidra NativeAOT extension](ghidra-nativeaot.md) has its own supported boundary.
Declared import inventory supports a bounded positive claim. Its absence does
not exclude dynamic resolution, generated code, protected code, native helpers,
or server-side behavior.
## Evidence record shape
Member comparison, application graph projection, and managed/native verification
@@ -320,6 +223,48 @@ For example, a decoded `nop; ret` body serializes exactly as
This vector specifies the tuple order, `null` handling, absence of whitespace,
UTF-8 encoding, and lowercase hexadecimal output.
## Member comparison
Names and semantic labels do not establish durable member identity. Comparison
preserves observed differences, structural inferences, and unknowns separately.
Cross-version matching first prefers exact CIL/signature identity. When that
does not match, it pairs an exact declared type, method name, and raw signature
before trying structural body shape. The exact-signature key uses names only
as part of that full tuple; names alone never select a pair. Duplicate tuples
remain ambiguous rather than being paired by token order. Fields follow the
same exact tiers. The raw signature is exact whether or not REA decoded it, so
undecoded signatures pair by that tuple too, but they never enter structural
rounds. An unmatched member is therefore reported as `unknown`, not added or
removed, when its own signature was not decoded or when the other side has an
unpaired member, one-sided or ambiguous, with the same declared type and name
whose signature was not decoded.
For a matched method, an unavailable or partial body makes body-shape facets
unknown while preserving observed signature differences. Structural identity
compares normalized signatures, the limited decoded-CIL tuple fingerprint,
constants, and bounded shape context. It reports all candidates at the winning
score and remains ambiguous when the evidence does not distinguish them. The
digest does not itself remap metadata tokens.
Tokens are always remapped through observed structure. A caller cannot carry
`0x06001234` into a new MVID and assume it names the same method.
## Managed/native boundary rules
`verify_managed_native_boundaries` compares declared P/Invoke module and entry
point identities with supplied native export or function evidence. Name/module
matches establish declaration links; they do not establish that a call executed.
Metadata tokens are not native addresses. Native body mapping for C++/CLI,
ReadyToRun, NativeAOT, and IL2CPP requires separately verified format and provider
support. The managed static tools do not recover those mappings. The optional
[Ghidra NativeAOT extension](ghidra-nativeaot.md) has its own supported boundary.
Declared import inventory supports a bounded positive claim. Its absence does
not exclude dynamic resolution, generated code, protected code, native helpers,
or server-side behavior.
## Tool and packaging boundary
The production parser is REA-owned TypeScript and ships with the existing Node
+304 -415
View File
@@ -1,265 +1,14 @@
# MCP runtime contracts
Use this reference to call REA tools and interpret their replies on one MCP
connection. Start with [tool results](#tool-results), [retained Evidence](#retained-application-evidence-inputs),
and [session discovery](#identity-and-discovery). See [cancellation](#progress-and-cancellation)
for partial-result recovery and [first-query deadlines](#ghidra-first-query-deadlines-and-recovery)
when a cold provider exceeds the client's wait.
## Generated catalog
## Tool results
Evidence-producing tools return the complete canonical Evidence record in both
text and structured content. Read `structuredContent.normalized_result` for the
operation result and `structuredContent.evidence_id` for its identity.
`raw_result` holds a provider representation distinct from that result, such
as an upstream tool's original report, and is `null` when there is none. The same
record is retained in the session bundle. `analysis_profile` is always present:
a concrete profile object or `null`; either value participates in semantic
identity. Records omitting this field are rejected. Pass the returned Evidence
directly to a compatible comparison tool: `analyze_function` Evidence can be passed
directly to `compare_functions`, and `inspect_artifact` Evidence to
`compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
retained session history or an explicit bundle for transfer.
Evidence and bundle imports reject unsupported fields in their envelopes,
identities, manifests and other fixed metadata before authentication. Imports
leave retained session state unchanged when validation fails. Keep application
metadata in the supported JSON payloads (`parameters`, `raw_result`,
`normalized_result`, or analysis-profile parameters), where keys are preserved.
Tool execution failures return `isError: true` and the complete canonical
`{ "error": ... }` diagnostic as JSON in text `content`. Read that diagnostic
for the error code, target details, partial observations, and remediation.
Failures omit `structuredContent`, since each advertised `outputSchema`
describes successful results. Successful replies retain their schema-validated
structured data and matching text projection. Oversized errors are retained
as Evidence before delivery of a bounded diagnostic with an export reference;
if retention is unavailable or fails, the diagnostic reports that reason.
`get_call_graph` returns a `graph` keyed by traversal depth and a top-level
`limitations` array with deduplicated execution caveats. Each node keeps its
relationship coverage and read-specific `limitations`, alongside observed
`calls`. When a provider does not classify its caveats, they remain on that
node and coverage is `unknown`. An empty call list with partial or unknown
coverage is not proof that the function has no calls.
`trace_call_path` reports each limited expansion in `residual_unknowns` and
sets `truncated: true`; any path already supported by observed edges remains
visible. When a requested goal is not reached but an expansion is unresolved,
`goal_status` is `unknown`; `not_reached` means traversal exhausted without
unresolved relationship reads. Cancellation remains a tool error.
REA prepares complete MCP results within the pinned stdio client's 10 MiB
receive-buffer budget, including both text and structured representations and
room for the JSON-RPC envelope. Tool errors carry only their text
representation, so only that text counts against the budget. Response budget settings are captured at startup;
restart or recreate the server to apply changes. If a result cannot fit, REA returns
`resource_constraint` with `details.resource: "transport"` before constructing
a document-sized string. Analysis Evidence remains complete in the current
session. Its exact reference is reported in
`details.reported_limits.evidence_reference`; call `inspect_analysis_view` with
that reference for a summary, one section/module, or a stable page, or call
`export_evidence_bundle` with a destination path. Complete
bundle exports stream canonical JSON into an atomically published file.
For oversized native function Evidence, `details.reported_limits.continuation`
contains a ready-to-call `inspect_analysis_view` request for the retained
pseudocode's first page. Use its `name` and `arguments` directly, then follow
`normalized_result.coverage.next_offset` for subsequent pages. The suggested
limit is the view contract's default, not a guarantee that arbitrary source or
metadata fits; reduce the limit or export when needed. Continuations are
offered for completed `analyze_function` results only after session recording is
acknowledged; the complete result and its retention reference remain intact.
A broad follow-up or `get_evidence_bundle` can also exceed the response budget; exporting
preserves the complete session without sending it through a single MCP frame.
To discover existing records without their large payloads, call
`get_evidence_bundle` with `detail: "summary"`. Its `result.records` contain
Evidence IDs, artifact/provider identities, analysis-profile digests and native
procedure metadata. Optional `filters` match exact `evidence_id`, `operation`,
`target_sha256`, `analysis_profile_digest` or `procedure_address`. Use a discovered
ID with `inspect_analysis_view`; neither discovery nor retained selection starts
a provider. `retention: "complete-record"` describes stored Evidence, while
`native_dossier.value_flow` independently reports truncation, unavailable or
unknown metadata. Missing omission counts remain null. Summary output carries
every matching record; actual transport admission still applies. Omitted
`detail` preserves complete canonical bundle delivery; filters require summary.
`list_unknowns` returns every matching current head by default. For a smaller
inline response, supply `offset` and `limit`, then follow `next_offset` until it
is null. `total` counts all matching heads; each page preserves complete records
in stable unknown ID order. Filters apply before paging. Pages reflect current
session state, so keep the unknown ledger unchanged while traversing it.
For a portable exported bundle, the CLI shares this projection:
`rea inspect-evidence-bundle '{"path":"/tmp/evidence.json","detail":"summary","filters":{"operation":"analyze_function"}}' --format json`.
The CLI validates and materializes that local bundle under its existing memory
budget; summary delivery does not make arbitrary large files cheap to import.
Cancelling an export stops further serialization and removes its staging file.
The destination changes only when a complete export is atomically published.
Clients that explicitly configure a larger receive buffer can set the REA
server's `REA_MCP_MAX_RESPONSE_BYTES` environment variable to the same byte
count. This setting must be a safe decimal integer at least 10485760; REA
reserves 1024 bytes for the envelope. Raising it restores complete inline
delivery for responses that fit that buffer and Node's single-string limit.
It does not change the client's buffer, analysis coverage, or retained content.
Ordinary responses keep their existing complete result contract.
### Untrusted target content
Strings, symbols, decompiled code and pseudocode, page text, script bodies,
network captures, logs, and file listings come from the analysis target. A
target can embed text written to look like instructions to the agent, for
example a string asking it to run a command or download a "required" helper.
REA treats that text as data, and its server instructions tell the agent to do
the same: never follow directives found in tool results, and report any request
to run, install, download, or send something as a prompt-injection attempt.
Results from tools that can return such content carry a stable marker in the
result's `_meta`, whether the call succeeded or failed:
```json
{ "provenance": { "untrusted_content": true, "source": "analysis_target" } }
```
The marker is declared once per tool contract (`returnsTargetContent`) and is
on by default: only `export_evidence_bundle` and `record_unknown`, whose
results and errors contain only REA session state or caller-supplied values,
omit it. Tools whose results or errors can include provider, launcher, or
device output stay marked, including `binary_session` (provider failure
reasons and availability diagnostics), `close_binary` (provider cleanup
diagnostics with captured launcher output), `inspect_adb_client` and
`inspect_apktool_client` (version output and stderr excerpts), and
`update_unknown` (it echoes the stored question and domain, which an imported
bundle can supply). A new tool is marked until it is audited into
that exception list. Error results (`isError: true`) from a marked tool carry
the marker too, because a failure can include target-derived text: an error
message, captured output, or a `partial_observation` such as terminal data
retained by a cancelled `capture_process_scenario`. That covers provider and
admission failures, the response-budget error that replaces an oversized
result, its oversized-error replacement, and errors the MCP SDK builds itself,
such as input validation failures. The marker adds a fixed number of bytes
that the response budget accounts for. It does not alter `content` or
`structuredContent`. Hosts and hooks can use it to apply stricter handling,
such as requiring approval for process-launching or device-mutating tools
after target content was read.
## Retained application Evidence inputs
`analyze_javascript_application`, `inspect_binary_layout`, `inspect_artifact`, and
`inspect_wasm_artifact` accept `detail`:
`complete` (default) returns the complete analysis Evidence; `summary` records
that complete Evidence in the session and returns the derived
`inspect_analysis_view` summary Evidence instead. Its
`normalized_result.parent_evidence_id` and `evidence_links` name the retained
analysis, so later views and application workflows read it without repeating
analysis or moving the complete record through the response. A server without
session retention refuses summary detail with `capability_unavailable`.
For `inspect_artifact`, omission also keeps the original request parameters and
complete output shape. Delivery selection never reaches the inventory engine;
the complete inspection and its atomic inventory Evidence remain retained.
`inspect_analysis_view` also accepts `api-surface` for retained HAR capture Evidence,
grouping request lines by method, origin and format-rule path template. Templated
segments are inferences. Because paging follows the full grouping, every page is
inferred Evidence whenever any group is templated, and derived Evidence only when
no group was templated.
See [derived API surfaces](web-network-captures.md#derived-api-surface).
`inspect_analysis_view` projects a caller-selected view of already completed
`inspect_binary_layout`, `analyze_javascript_application`, or `analyze_function`
Evidence. Native views select procedure, pseudocode, assembly, basic blocks,
comments, callers/callees, references, unresolved calls, referenced strings and
names, the native API record, and high-pcode facets without starting a provider. Native offset
and limit default to 0 and 64; pseudocode uses UTF-16 code units and never
splits surrogate pairs, while other pages count rows. Unavailable facts and
provider limitations remain explicit. Source is
an exact same-session retained reference or portable inline Evidence. Views are
a summary, a layout mitigations or linkage facet, one section/symbol/module, or
a stable page with a caller-selected positive `limit`. Module pages include
JavaScript assets, bundled modules, and source modules. Select an exact
`node_id` when a path is ambiguous or unavailable. Module items retain their
recorded property values and source locations; summaries include parent
application and semantic coverage. The result carries a digest of the selected
facts. Actual serialized size determines MCP transport admission: reduce the
page size or export retained Evidence if the view is too large.
Completed `inspect_artifact` and atomic `inventory_artifact` Evidence also
support summary and inventory views. A summary reports the manifest's expected
counts separately from available record counts, observed entry kinds, inventory
Evidence IDs and inspection coverage. An inventory view selects `nodes`,
`occurrences`, `edges`, or `integrity_contradictions`, with `offset` and `limit`
defaulting to 0 and 64. For occurrences, optional `logical_paths` matches exact
recorded strings: omission selects all available records; `[]` selects none.
These selectors do not reopen the artifact or resolve filesystem paths.
`source_complete` records whether the available inventory passes the complete
graph checks. Exhausting a page from a partial source does not establish that
unreturned paths are absent. Views carry their own Evidence IDs and preserve
links to the original parent; complete producer output and historical inline
Evidence input parsing retain their existing shapes.
Completed `inspect_wasm_artifact` Evidence supports a summary and
`view: {kind: "wasm", facet: "exports", offset: 0, limit: 64}`. Other facets
are `sections`, `imports`, `candidates`, `glue`, `wat`, `headers`, `details`, and
the singleton `tool_profile` (offset 0). Arrays retain original WABT forms and
records. Text facets page by UTF-16 code units and preserve complete Unicode
characters. Summaries report the selected artifact's identity, validation,
available counts, decoded WAT digest/length and exact tool profile. Runtime
execution and network acquisition remain `not-performed`. A valid WAT digest
is checked at the owning model boundary for current output and portable input.
The original producer still returns complete Evidence by default. When its
complete MCP reply exceeds the frame, use the exact reported retained
reference with these views, or export the complete source. Views do not run
WABT again and do not turn decoded WAT into original source.
For counts, validation and WAT identity, select `detail: "summary"` on the first
`inspect_wasm_artifact` call. It retains the original complete source without
attempting oversized delivery, and returns the same summary with an exact
`parent_evidence_id` for later export or facet reads. Delivery detail does not
reach WABT or change the original source Evidence ID.
`trace_application_feature`, `trace_javascript_semantics`,
`compare_application_versions`, `compare_source_to_bundle`, and
`compare_javascript_export_shapes` accept complete inline application Evidence
or an exact reference to a record already retained by the current connection:
```json
{
"name": "trace_application_feature",
"arguments": {
"application": {
"kind": "retained-evidence",
"evidence_id": "ev_<64 lowercase hex characters>"
},
"seed": { "kind": "module", "value": "search.js", "match": "exact" }
}
}
```
Use the `evidence_id` returned by `analyze_javascript_application` (or another
compatible application-graph producer). Comparisons accept this form in `left`
and `right`; each side can independently be inline or retained. Native
observation arrays continue to take complete inline Evidence. Results and their
Evidence remain complete inline, and both input forms pass the same semantic,
identity, authority, and provenance checks without running the producer again.
References belong to the current connection's Evidence ledger. Opening another
target preserves retained records; `close_binary` clears them, even when no
binary is active. A fresh connection has its own ledger. A missing reference
reports its exact ID and `details.reason: "missing"`; the server cannot infer
whether it was never recorded, cleared, or retained by another connection.
Supply complete inline Evidence, repeat its producer, or import an exported
Evidence bundle before referencing that imported record. Export a bundle before
closing if the investigation needs it later.
CLI application workflows continue to read portable inline Evidence from files
and run the same analysis workflows; a standalone CLI invocation cannot resolve
another MCP connection's retained records. No additional lookup call, provider
selection, or approval step is required for a same-session follow-up.
CLI `inspect-artifact` continues to return complete portable Evidence. Save that
JSON to a file and use `inspect-analysis-view` with inline source Evidence for
later inventory summaries or pages; a one-shot CLI session cannot retain a
parent for another invocation.
Run `npm run docs:generate` in a source checkout to generate the machine-readable
catalog at `docs/public/product-catalog.json`. Documentation deployments serve
the same file at [/rea/product-catalog.json](/rea/product-catalog.json). PR CI retains it with the packaged
skill and portable conformance projections in the `generated-docs` artifact.
These outputs describe the exact source revision being built; they are not
checked-in snapshots. For a running server, `binary_session` remains the
authoritative source of catalog identity and tool availability.
## Identity and discovery
@@ -274,6 +23,94 @@ are currently unavailable. Opening or closing a target or observing a provider
health transition leaves that catalog unchanged and does not emit
`notifications/tools/list_changed`.
Advertised input and output schemas contain no reachable recursive references.
Schemas share repeated definitions through schema-local references while
preserving complete nested fields and validation rules. Input properties retain
their descriptions and literal examples.
Hosts forward input schemas to the model with every request, so advertised
examples never copy complete producer Evidence. An embedded Evidence record is
shown as its exact `{"kind":"retained-evidence","evidence_id":"ev_..."}`
reference where the tool accepts one. An example that can only carry inline
Evidence stays in the canonical contract and its executable tests, but is not
advertised. Every advertised example is a distinct valid canonical input.
Root object unions are presented as
one object without root `anyOf`, `oneOf`, or `allOf` for model API compatibility.
The projection merges properties, retains shared required fields and
group-specific field dependencies, and describes the accepted input groups.
Canonical runtime validation enforces the exact union, including exclusions
that the advertised projection does not express. Tests validate the schemas
after SDK conversion and check advertised validation and actual calls.
Individual model APIs can impose additional nesting limits; complete producer
captures can exceed ten structural levels.
### Compact input schema profile
Some function-calling providers reject a request while any single tool's
`parameters` schema exceeds a literal serialized size cap; Moonshot clients
such as kimi-cli fail every request while the default catalog is attached
([#1484](https://github.com/morluto/rea/issues/1484)). Setting the server's
`REA_MCP_INPUT_SCHEMA_PROFILE` environment variable to `compact` renders every
advertised input schema within a 13,312-byte budget, measured to sit below
Moonshot's observed cap (community measurements: a 13.7 KB schema is accepted
while a ~15 KB one is rejected). The setting is read at startup; restart the
server to apply changes, as with `REA_MCP_MAX_RESPONSE_BYTES`. The default
value `full` keeps the complete advertisement unchanged.
The compact profile renders the same tool set, output schemas, annotations,
and canonical server-side validation. It changes only the advertised input
JSON Schema:
- Annotation prose leaves the advertised form: nested property descriptions,
literal examples, defaults, and titles are dropped. The root keeps its
description because it states the accepted input groups.
- Schema-local references are inlined within the budget. Kimi Code expands
references before sending provider requests, so sharing definitions cannot
establish the provider-facing size. Expansion stops at the budget before
allocating an oversized presentation. Unconstrained JSON fields advertise
all JSON value types explicitly so Kimi cannot infer string for Evidence
objects or arrays.
- The few schemas whose validation structure alone exceeds the budget
(`compare_web_captures`, `build_reconstruction_obligation_ledger`,
`evaluate_reconstruction_coverage`, `project_managed_application_graph`,
`compare_application_versions`, `capture_browser_scenario`) are advertised
in a reduced form: property names, reference-resolved types (including union
alternatives), first-level guidance, and the root's required-field constraints,
with nested validation detail elided. The
canonical schema still rejects malformed calls server-side, so callers
following the reduced advertisement receive the canonical typed error
instead of silent acceptance.
Boundary tests pin every advertised compact schema to the budget, keep them
valid JSON Schema that still accepts every canonical example, and hold the
set of six reduced presentations as contracts evolve. Client verification
also checks provider-facing sizes and canonical examples after conversion by
the actual Kimi Code CLI; local captures do not establish Moonshot acceptance.
Self-contained output schemas advertise a content-bound `$id`, including their
declared dialect. SDK validators can reuse compiled schemas across complete
catalog refreshes and equivalent tool outputs; changing the schema changes its
identity. Explicit schema IDs and relative external reference bases are
preserved. This keeps every tool and validation rule in discovery and does not
change the SDK's catalog invalidation or availability checks.
`compare_web_captures` accepts exactly one of two input shapes:
- Passive: `before` and `after` each contain `inspection`, the complete
`normalized_result` from `inspect_web_page`. Each may also contain `webmcp`,
the complete `normalized_result` from `discover_webmcp_tools`, or null.
- Scenario: `before_scenario` and `after_scenario` contain complete
`normalized_result` objects from `capture_browser_scenario`. Optional
`normalization` defaults to `{ "rules": [] }`.
The advertised schema includes complete nested capture fields and rejects
incomplete pairs and structurally malformed captures. Mixed comparison families
can pass advertised validation; the SDK rejects them against the canonical
input schema before invoking the handler. Domain validation additionally checks
relationships such as event sequence references and retained counts; JSON
Schema does not express those cross-field invariants.
Call `binary_session` with `{}` and read `result.tool_availability` to choose a
callable operation for the current target, provider, host, and negotiated client
capabilities. The default result contains the complete inventory in groups that
@@ -335,6 +172,15 @@ inventories, and do not claim that no short-lived descendant existed.
## Progress and cancellation
Tool execution failures return `isError: true` and the complete canonical
`{ "error": ... }` diagnostic as JSON in text `content`. Read that diagnostic
for the error code, target details, partial observations, and remediation.
Failures omit `structuredContent`, since each advertised `outputSchema`
describes successful results. Successful replies retain their schema-validated
structured data and matching text projection. Oversized errors are retained
as Evidence before delivery of a bounded diagnostic with an export reference;
if retention is unavailable or fails, the diagnostic reports that reason.
REA accepts ordinary `tools/call` progress tokens. The numeric `progress` counts
emitted status observations and strictly increases, including when a waiting
phase has completed no additional work. Updates are rate-bounded to at most one
@@ -370,13 +216,8 @@ during graph/result sealing, cross-graph binding checks, Evidence JSON validatio
and canonical hashing. Its final result validation reuses exact graphs whose
owned constructors validated and completely sealed them; imported graphs still
receive full schema and commitment checks.
Cancellation before completion returns `cancelled` instead of a successful
result. Completed facts can be retained as new partial Evidence; prior Evidence
also stays usable. Read the error's `partial_observation` reference on the same
MCP connection. If the SDK stopped waiting before that reply arrived, use
`get_evidence_bundle` with `detail: "summary"` and an operation filter to find
the partial record, then open it with `inspect_analysis_view`. Cancellation
before any facts are completed may leave no partial record.
Cancellation observed before completion returns `cancelled` and prevents the
provisional result from entering the session ledger; prior Evidence stays usable.
Single-file parsing, graph construction, and validation of imported graphs
still run synchronously, so control messages can wait for those
phases to release the event loop. A rejected client promise alone does not
@@ -388,48 +229,6 @@ through provider cleanup, including repeated delivery by package runners.
Existing controlled-process cleanup and provider shutdown rules still apply;
REA never kills a process it cannot prove it owns.
## Request scope and local effects
Each tool request names the target and lifecycle it will use. Browser calls
carry a loopback CDP endpoint and target ID, with optional origin filters;
process and Electron scenarios carry the executable, arguments, actions, and
cleanup behavior; artifact tools carry the input path and requested operation.
REA runs the declared request directly and does not infer a broader target or
action from it.
REA does not require permission grants or per-call approval flags. Setup still
prints its plan and requires confirmation before changing configuration or
installing Hopper. MCP clients control their own confirmation UI.
Tool annotations describe effects and are hints, not authorization controls
([MCP ToolAnnotations](https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations)).
`readOnlyHint` includes session state: an analysis call that records additive
Evidence is marked non-read-only even when it leaves the target unchanged.
`destructiveHint` is true when a tool may discard data (overwriting or clearing
analyst metadata, replacing files, dropping session state), runs or drives code
REA does not own (`executesForeignCode`: process, LLDB, Electron, browser, and
native UI scenarios), or changes an attached Android device (`mutatesDevice`:
push, install, uninstall, start, and stop). Ordinary Evidence recording is not
destructive. The effect record in `binary_session` and the generated catalog
carries each flag separately.
Effect metadata covers possible behavior across supported inputs: DMG inventory
can launch `hdiutil` and create an owned temporary mount directory; extraction
creates a fresh output directory on every call. Comparing supplied web captures
or PNG artifacts uses local data without contacting the browser.
Host requirements remain in force. macOS may deny Accessibility,
Screen Recording, or native mounting; provider tools require their selected
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.
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.
## Ghidra first-query deadlines and recovery
A successful MCP initialize handshake establishes the REA connection.
@@ -529,6 +328,161 @@ automatically. A provider timeout, installation failure, or host permission
denial needs its own reported recovery; increasing a client deadline alone does
not fix those failures.
## Tool results
Custom clients upgrading from 6.1 should follow the
[6.2 migration guide](migration-6.2.md#mcp-results-and-evidence).
Evidence-producing tools return the complete canonical Evidence record in both
text and structured content. Read `structuredContent.normalized_result` for the
operation result and `structuredContent.evidence_id` for its identity.
`raw_result` holds a provider representation distinct from that result, such
as an upstream tool's original report, and is `null` when there is none. The same
record is retained in the session bundle. `analysis_profile` is always present:
a concrete profile object or `null`; either value participates in semantic
identity. Records omitting this field are rejected. Pass the returned Evidence
directly to a compatible comparison tool: `analyze_function` Evidence can be passed
directly to `compare_functions`, and `inspect_artifact` Evidence to
`compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
retained session history or an explicit bundle for transfer.
`get_call_graph` returns a `graph` keyed by traversal depth and a top-level
`limitations` array with deduplicated execution caveats. Each node keeps its
relationship coverage and read-specific `limitations`, alongside observed
`calls`. When a provider does not classify its caveats, they remain on that
node and coverage is `unknown`. An empty call list with partial or unknown
coverage is not proof that the function has no calls.
`trace_call_path` reports each limited expansion in `residual_unknowns` and
sets `truncated: true`; any path already supported by observed edges remains
visible. Tool errors remain in their existing error or failure fields.
REA prepares complete MCP results within the pinned stdio client's 10 MiB
receive-buffer budget, including both text and structured representations and
room for the JSON-RPC envelope. Tool errors carry only their text
representation, so only that text counts against the budget. Response budget settings are captured at startup;
restart or recreate the server to apply changes. If a result cannot fit, REA returns
`resource_constraint` with `details.resource: "transport"` before constructing
a document-sized string. Analysis Evidence remains complete in the current
session. Its exact reference is reported in
`details.reported_limits.evidence_reference`; call `inspect_analysis_view` with
that reference for a summary, one section/module, or a stable page, or call
`export_evidence_bundle` with a destination path. Complete
bundle exports stream canonical JSON into an atomically published file.
For oversized native function Evidence, `details.reported_limits.continuation`
contains a ready-to-call `inspect_analysis_view` request for the retained
pseudocode's first page. Use its `name` and `arguments` directly, then follow
`normalized_result.coverage.next_offset` for subsequent pages. The suggested
limit is the view contract's default, not a guarantee that arbitrary source or
metadata fits; reduce the limit or export when needed. Continuations are
offered for completed `analyze_function` results only after session recording is
acknowledged; the complete result and its retention reference remain intact.
A broad follow-up or `get_evidence_bundle` can also exceed the response budget; exporting
preserves the complete session without sending it through a single MCP frame.
To discover existing records without their large payloads, call
`get_evidence_bundle` with `detail: "summary"`. Its `result.records` contain
Evidence IDs, artifact/provider identities, analysis-profile digests and native
procedure metadata. Optional `filters` match exact `evidence_id`, `operation`,
`target_sha256`, `analysis_profile_digest` or `procedure_address`. Use a discovered
ID with `inspect_analysis_view`; neither discovery nor retained selection starts
a provider. `retention: "complete-record"` describes stored Evidence, while
`native_dossier.value_flow` independently reports truncation, unavailable or
unknown metadata. Missing omission counts remain null. Summary output carries
every matching record; actual transport admission still applies. Omitted
`detail` preserves complete canonical bundle delivery; filters require summary.
For a portable exported bundle, the CLI shares this projection:
`rea inspect-evidence-bundle '{"path":"/tmp/evidence.json","detail":"summary","filters":{"operation":"analyze_function"}}' --format json`.
The CLI validates and materializes that local bundle under its existing memory
budget; summary delivery does not make arbitrary large files cheap to import.
Cancelling an export stops further serialization and removes its staging file.
The destination changes only when a complete export is atomically published.
Clients that explicitly configure a larger receive buffer can set the REA
server's `REA_MCP_MAX_RESPONSE_BYTES` environment variable to the same byte
count. This setting must be a safe decimal integer at least 10485760; REA
reserves 1024 bytes for the envelope. Raising it restores complete inline
delivery for responses that fit that buffer and Node's single-string limit.
It does not change the client's buffer, analysis coverage, or retained content.
Ordinary responses keep their existing complete result contract.
## Retained application Evidence inputs
`analyze_javascript_application` and `inspect_binary_layout` accept `detail`:
`complete` (default) returns the complete analysis Evidence; `summary` records
that complete Evidence in the session and returns the derived
`inspect_analysis_view` summary Evidence instead. Its
`normalized_result.parent_evidence_id` and `evidence_links` name the retained
analysis, so later views and application workflows read it without repeating
analysis or moving the complete record through the response. A server without
session retention refuses summary detail with `capability_unavailable`.
`inspect_analysis_view` also accepts `api-surface` for retained HAR capture Evidence,
grouping request lines by method, origin and format-rule path template. Templated
segments are inferences. Because paging follows the full grouping, every page is
inferred Evidence whenever any group is templated, and derived Evidence only when
no group was templated.
See [derived API surfaces](web-network-captures.md#derived-api-surface).
`inspect_analysis_view` projects a caller-selected view of already completed
`inspect_binary_layout`, `analyze_javascript_application`, or `analyze_function`
Evidence. Native views select procedure, pseudocode, assembly, basic blocks,
comments, callers/callees, references, unresolved calls, referenced strings and
names, the native API record, and high-pcode facets without starting a provider. Native offset
and limit default to 0 and 64; pseudocode uses UTF-16 code units and never
splits surrogate pairs, while other pages count rows. Unavailable facts and
provider limitations remain explicit. Source is
an exact same-session retained reference or portable inline Evidence. Views are
a summary, a layout mitigations or linkage facet, one section/symbol/module, or
a stable page with a caller-selected positive `limit`. Module pages include
JavaScript assets, bundled modules, and source modules. Select an exact
`node_id` when a path is ambiguous or unavailable. Module items retain their
recorded property values and source locations; summaries include parent
application and semantic coverage. The result carries a digest of the selected
facts. Actual serialized size determines MCP transport admission: reduce the
page size or export retained Evidence if the view is too large.
`trace_application_feature`, `trace_javascript_semantics`,
`compare_application_versions`, `compare_source_to_bundle`, and
`compare_javascript_export_shapes` accept complete inline application Evidence
or an exact reference to a record already retained by the current connection:
```json
{
"name": "trace_application_feature",
"arguments": {
"application": {
"kind": "retained-evidence",
"evidence_id": "ev_<64 lowercase hex characters>"
},
"seed": { "kind": "module", "value": "search.js", "match": "exact" }
}
}
```
Use the `evidence_id` returned by `analyze_javascript_application` (or another
compatible application-graph producer). Comparisons accept this form in `left`
and `right`; each side can independently be inline or retained. Native
observation arrays continue to take complete inline Evidence. Results and their
Evidence remain complete inline, and both input forms pass the same semantic,
identity, authority, and provenance checks without running the producer again.
References belong to the current connection's Evidence ledger. Opening another
target preserves retained records; `close_binary` clears them, even when no
binary is active. A fresh connection has its own ledger. A missing reference
reports its exact ID and `details.reason: "missing"`; the server cannot infer
whether it was never recorded, cleared, or retained by another connection.
Supply complete inline Evidence, repeat its producer, or import an exported
Evidence bundle before referencing that imported record. Export a bundle before
closing if the investigation needs it later.
CLI application workflows continue to read portable inline Evidence from files
and run the same analysis workflows; a standalone CLI invocation cannot resolve
another MCP connection's retained records. No additional lookup call, provider
selection, or approval step is required for a same-session follow-up.
## Aggregate native context
`get_navigation_context` composes the selected document, current address, and
@@ -542,6 +496,48 @@ unsupported facets are local `unavailable` outcomes. Use `current_document`,
`current_address`, and `current_procedure` for direct single-field lookups; use
the aggregate tools when you need related context together.
## Request scope and local effects
Each tool request names the target and lifecycle it will use. Browser calls
carry a loopback CDP endpoint and target ID, with optional origin filters;
process and Electron scenarios carry the executable, arguments, actions, and
cleanup behavior; artifact tools carry the input path and requested operation.
REA runs the declared request directly and does not infer a broader target or
action from it.
REA does not require permission grants or per-call approval flags. Setup still
prints its plan and requires confirmation before changing configuration or
installing Hopper. MCP clients control their own confirmation UI.
Tool annotations describe effects and are hints, not authorization controls
([MCP ToolAnnotations](https://modelcontextprotocol.io/specification/2025-06-18/schema#toolannotations)).
`readOnlyHint` includes session state: an analysis call that records additive
Evidence is marked non-read-only even when it leaves the target unchanged.
`destructiveHint` is true when a tool may discard data (overwriting or clearing
analyst metadata, replacing files, dropping session state), runs or drives code
REA does not own (`executesForeignCode`: process, LLDB, Electron, browser, and
native UI scenarios), or changes an attached Android device (`mutatesDevice`:
push, install, uninstall, start, and stop). Ordinary Evidence recording is not
destructive. The effect record in `binary_session` and the generated catalog
carries each flag separately.
Effect metadata covers possible behavior across supported inputs: DMG inventory
can launch `hdiutil` and create an owned temporary mount directory; extraction
creates a fresh output directory on every call. Comparing supplied web captures
or PNG artifacts uses local data without contacting the browser.
Host requirements remain in force. macOS may deny Accessibility,
Screen Recording, or native mounting; provider tools require their selected
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.
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.
## Integrity record-and-continue
Artifact integrity fails closed by default. A request can explicitly select
@@ -570,110 +566,3 @@ writing the archive header, so their declared hashes no longer match. Electron
does not check unpacked companions against those hashes at runtime. Integrity
failures for such entries name this cause and the operation to rerun with
`record-and-continue`; REA does not exempt unpacked entries silently.
## Schema advertisement
Advertised input and output schemas contain no reachable recursive references.
Schemas share repeated definitions through schema-local references while
preserving complete nested fields and validation rules. Input properties retain
their descriptions and literal examples.
When a host forwards input schemas to the model, their examples consume context.
REA's advertised examples therefore never copy complete producer Evidence.
An embedded Evidence record is shown as its exact `{"kind":"retained-evidence","evidence_id":"ev_..."}`
reference where the tool accepts one. An example that can only carry inline
Evidence stays in the canonical contract and its executable tests, but is not
advertised. Every advertised example is a distinct valid canonical input.
Root object unions are presented as
one object without root `anyOf`, `oneOf`, or `allOf` for model API compatibility.
The projection merges properties, retains shared required fields and
group-specific field dependencies, and describes the accepted input groups.
Canonical runtime validation enforces the exact union, including exclusions
that the advertised projection does not express. Tests validate the schemas
after SDK conversion and check advertised validation and actual calls.
Individual model APIs can impose additional nesting limits; complete producer
captures can exceed ten structural levels.
### Compact input schema profile
Some function-calling providers reject a request while any single tool's
`parameters` schema exceeds a literal serialized size cap; Moonshot clients
such as kimi-cli fail every request while the default catalog is attached
([#1484](https://github.com/morluto/rea/issues/1484)). Setting the server's
`REA_MCP_INPUT_SCHEMA_PROFILE` environment variable to `compact` renders every
advertised input schema within a 13,312-byte budget, measured to sit below
Moonshot's observed cap (community measurements: a 13.7 KB schema is accepted
while a ~15 KB one is rejected). The setting is read at startup; restart the
server to apply changes, as with `REA_MCP_MAX_RESPONSE_BYTES`. The default
value `full` keeps the complete advertisement unchanged.
The compact profile renders the same tool set, output schemas, annotations,
and canonical server-side validation. It changes only the advertised input
JSON Schema:
- Annotation prose leaves the advertised form: nested property descriptions,
literal examples, defaults, and titles are dropped. The root keeps its
description because it states the accepted input groups.
- Schema-local references are inlined within the budget. Kimi Code expands
references before sending provider requests, so sharing definitions cannot
establish the provider-facing size. Expansion stops at the budget before
allocating an oversized presentation. Unconstrained JSON fields advertise
all JSON value types explicitly so Kimi cannot infer string for Evidence
objects or arrays.
- The few schemas whose validation structure alone exceeds the budget
(`compare_web_captures`, `build_reconstruction_obligation_ledger`,
`evaluate_reconstruction_coverage`, `project_managed_application_graph`,
`compare_application_versions`, `capture_browser_scenario`) are advertised
in a reduced form: property names, reference-resolved types (including union
alternatives), first-level guidance, and the root's required-field constraints,
with nested validation detail elided. The
canonical schema still rejects malformed calls server-side, so callers
following the reduced advertisement receive the canonical typed error
instead of silent acceptance.
Boundary tests pin every advertised compact schema to the budget, keep them
valid JSON Schema that still accepts every canonical example, and hold the
set of six reduced presentations as contracts evolve. Client verification
also checks provider-facing sizes and canonical examples after conversion by
the actual Kimi Code CLI; local captures do not establish Moonshot acceptance.
### Output schemas
Self-contained output schemas advertise a content-bound `$id`, including their
declared dialect. SDK validators can reuse compiled schemas across complete
catalog refreshes and equivalent tool outputs; changing the schema changes its
identity. Explicit schema IDs and relative external reference bases are
preserved. This keeps every tool and validation rule in discovery and does not
change the SDK's catalog invalidation or availability checks.
### Comparison input shapes
`compare_web_captures` accepts exactly one of two input shapes:
- Passive: `before` and `after` each contain `inspection`, the complete
`normalized_result` from `inspect_web_page`. Each may also contain `webmcp`,
the complete `normalized_result` from `discover_webmcp_tools`, or null.
- Scenario: `before_scenario` and `after_scenario` contain complete
`normalized_result` objects from `capture_browser_scenario`. Optional
`normalization` defaults to `{ "rules": [] }`.
The advertised schema includes complete nested capture fields and rejects
incomplete pairs and structurally malformed captures. Mixed comparison families
can pass advertised validation; the SDK rejects them against the canonical
input schema before invoking the handler. Domain validation additionally checks
relationships such as event sequence references and retained counts; JSON
Schema does not express those cross-field invariants.
## Generated catalog
Custom clients upgrading from 6.1 should follow the
[6.2 migration guide](migration-6.2.md#mcp-results-and-evidence).
Run `npm run docs:generate` in a source checkout to generate the machine-readable
catalog at `docs/public/product-catalog.json`. Documentation deployments serve
the same file at [/rea/product-catalog.json](/rea/product-catalog.json). PR CI retains it with the packaged
skill and portable conformance projections in the `generated-docs` artifact.
These outputs describe the exact source revision being built; they are not
checked-in snapshots. For a running server, `binary_session` remains the
authoritative source of catalog identity and tool availability.
-6
View File
@@ -91,12 +91,6 @@ identifiers only; they do not retrieve or replace the inline Evidence result.
Completion sources are live projections of the current session:
Document and procedure completion in a binary session reads an already-ready
provider; it does not start analysis. A cold provider, a target transition, or
unavailable inventory can return no suggestions. Run an analysis query first
when you need inventory from a provider that supplies it. An empty completion
list does not establish that the target has no procedures.
| Argument family | Source and filtering |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Document | Current provider `list_documents` result. |
+122 -179
View File
@@ -1,34 +1,132 @@
<div id="native-ui-and-dispatch-investigation"></div>
# Native UI and dispatch investigation
# Native binary investigation
REA joins static resources, native metadata and code facts while keeping runtime
observations separate. Every result reports its evidence, target identity,
coverage and unknowns. The CLI and MCP use the same application workflows.
Use a native provider to discover functions, inspect instructions and pseudocode,
follow references, and examine database types. Static resources and runtime
observation complement that analysis when they answer a specific question.
## Static inspection
## Start with a function
`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
subject format describes the input container: `mach-o-universal` for FAT files,
including those with one slice. The normalized result describes the selected
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.
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;
architecture inventory locations remain available.
Choose an installed provider from [setup](installation.md#hopper). For Ghidra:
Hopper's `address_to_file_offset` combines the native image-relative mapping with
original-file coordinates only after checking the source against the session's
SHA-256. FAT tables and embedded Mach-O headers come from that same hashing pass.
A changed or nonregular source reports `artifact_changed`; an unreadable or
missing source reports its access or filesystem failure. Those errors retain the native offset,
loaded header and provider source path in `details.partial_observation`, with the
original-file coordinate explicitly unavailable. Restore the original bytes or
reopen the changed executable to obtain verified coordinates. Snapshot replay
remains historical evidence for its recorded artifact identity.
```bash
rea inspect /absolute/path/to/program --provider ghidra --json
rea search /absolute/path/to/program entry --kind procedures --provider ghidra --json
```
A selected Hopper database's digest identifies the database rather than its
original executable. Original-file mapping is unavailable for that selection;
native mapping facts remain in partial evidence, and `read_bytes` still reads
the loaded database. Open the original executable to verify source coordinates.
Select an exact name or address from the returned inventory, then use it with
`rea function PATH PROCEDURE --provider ghidra --json` for a function dossier,
`rea instructions` for assembly, or `rea decompile` for pseudocode. Do not assume
that every target names its entry function `entry`. MCP uses `open_binary` and
focused tools such as `list_procedures` and `analyze_function` on the same session.
Native Xcode command execution uses shared process supervision with a 60-second
deadline and a 64 MiB aggregate stdout/stderr budget. Timeout, cancellation,
stream failure, and output exhaustion retain the captured output, exit details,
and cleanup outcome in the error result. Truncated output is never parsed as a
complete observation.
| Question | Section |
| ------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| Which instructions, calls, references, or types are present? | [Native primitives](#native-instruction-call-and-type-primitives) |
| How can I select a name beginning with a dash? | [CLI selectors](#exact-cli-selectors) |
| What static path connects these functions? | [Bounded traces](#bounded-static-traces) |
| Which UI resources or dispatch metadata are present? | [Static inspection](#static-inspection) |
| What did the declared runtime scenario observe? | [Desktop](#native-desktop-observation) or [call observation](#native-call-observation) |
| What can this provider and host establish? | [Provider boundaries](#provider-and-verification-boundaries) |
- `trace_dylib_resolution` / `rea trace-dylib-resolution <app-or-mach-o>`
parses Mach-O load commands in TypeScript and follows dyld's path expansion
for every executable in an app bundle, or for one Mach-O within its directory.
It reports each `@rpath`, `@loader_path` and `@executable_path` candidate with
its outcome. Paths outside the analyzed root, including shared-cache system
libraries, stay undetermined. See
[Apple application analysis](apple-application-analysis.md#dylib-load-resolution).
- `inspect_asset_catalog` / `rea inspect-asset-catalog <app>` reads compiled
`Assets.car` metadata through macOS `assetutil --info`. Catalog digests, raw
rendition fields, pagination and exact UI resource-name matches are returned.
Image extraction and undocumented rendition interpretation are unsupported.
- `inspect_keyed_archive` / `rea inspect-keyed-archive <plist>` reads XML or
binary Foundation keyed archives without instantiating classes. For an active
app, provide its relative archive path as the second CLI argument or MCP
`path`. Results retain original `$objects` indices, named `$top` roots,
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.
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. 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. `verify:interface-builder` compiles
a source-owned AppKit XIB with `ibtool`. Storyboards require an installed
iOS platform; unsupported archive forms remain explicit.
XML plist archives accept UTF-8 and BOM-marked UTF-16 in either byte order.
App bundle `Info.plist` executable resolution uses the same decoder as keyed
archives and Interface Builder. The decoder consumes an initial
BOM and rejects malformed byte sequences, unsupported encoding declarations,
and declarations that disagree with the detected encoding. It never substitutes
UTF-8 for a declared encoding it cannot process. Archive and evidence digests
still identify the original serialized bytes. Bundle resolution reports
malformed bytes and unsupported encodings against the original plist path
before looking up the executable. Interface Builder decoding
limits aggregate input archives to 32 MiB.
Before decoding, it also bounds the serialized structure: expanded binary
plist references, NIB table records, XML elements and text, plus their
projected representations must fit the 256 MiB aggregate decode budget.
NIB string values, data, property names and class names are charged at each
projected JSON occurrence, including when the archive reuses one source
value. Binary plist data projection also accounts for the temporary byte
copy made by the pinned decoder projection. These are format-derived
representation reservations, not exact heap measurements or a process-wide
heap ceiling.
Archives beyond either aggregate budget are omitted with their paths and an
explicitly partial `archive_decode` facet; previously decoded documents and
their identities remain available.
- `inspect_native_dispatch_metadata` /
`rea inspect-native-dispatch-metadata <app-or-binary>` prefers a validated macOS Mach-O byte reader. It decodes
64-bit little-endian Objective-C class/metaclass records, superclass pointers,
absolute/relative method entries, ivar offsets/sizes/alignment and protocol
declarations. It also decodes simple Swift conformances, static synchronous
witness slots, signed-relative pointers and non-generic, non-resilient class
vtable descriptors. Records include exact virtual addresses/file offsets and
artifact evidence. Vtable indexes are metadata word offsets; witness indexes
start after the conformance header. Names unavailable in metadata remain null.
Pointers are decoded through the image's fixups:
- `LC_DYLD_CHAINED_FIXUPS` rebases and binds, including the authenticated
arm64e formats;
- legacy `LC_DYLD_INFO` bind opcodes.
So an external superclass resolves from its `_OBJC_CLASS_$_` bind (for
example `NSObject`). The `pointer_fixups` coverage facet names the mechanism.
Class properties preserve each encoded attribute as a raw `{name, value}`
pair, for example `{ name: "N", value: "" }`, and report atomicity on the
property: `N` means `nonatomic`; a complete typed attribute string without
`N` means the Objective-C default `atomic`;
missing or incomplete attribute metadata leaves `atomicity` and any
unestablished read-only value null. `is_meta_class`, `is_root_class`, and
`ivar_count` are also nullable when the selected provider exposes only symbol
names. Class implementation methods have null `is_required` and `is_optional`
fields because those facts apply to protocol declarations; decoded protocol
method lists retain their observed required/optional values. Class properties
and `__objc_catlist` categories are also decoded. Categories record the
extended class, local or external, plus
their methods, protocols and properties; category methods appear as
implementations with a `category`. Swift field-offset globals that are only
initialized at runtime stay unresolved. Generic, resilient, async and
coroutine tables, and inherited overrides, have explicit unsupported or
partial coverage. Other providers retain the
existing symbol-based inventory with its narrower coverage.
## Exact CLI selectors
@@ -174,37 +272,6 @@ array semantics are not inferred. The real lane uses a native DWARF 4 object
with a struct containing a union, enum and recursive pointer; a stripped linked
binary may have no corresponding recovered layout.
Ghidra serializes at most 20,000 fields or enum members per inspected type.
Check `total_fields` and `truncated` before treating the returned layout as
complete. These fields describe omissions from the response, independently of
whether Ghidra recovered the original source layout.
### Hopper analysis behavior
Cursor navigation returns the observed object start when Hopper snaps an interior
address; adjacent-object navigation rejects unmapped inputs and document ends.
Native API text rejects NUL characters and unpaired Unicode surrogates before
annotation changes. Renames preserve unselected label owners; use a batch with
all affected addresses to move or swap existing labels explicitly. Every rename
destination must be mapped, and native symbol names must fit Hopper's 1024 UTF-16
code-unit limit. Oversized names fail before any batch edits; bookmarks and
literal string results are not subject to that symbol-name limit. Rename success
requires exact final readback. New bookmarks must point into mapped memory;
existing legacy bookmarks outside it can still be removed.
String results read each native typed object's complete bytes, retain the original
provider display in `provider_value`, and report its encoding, byte length, and
termination. `encoding_status: inferred` distinguishes REA's decoding from an
observed source encoding. Hopper can split long literals into adjacent
unterminated objects; search matches each object's decoded bytes independently.
Undecodable objects retain native display text with `decoding.available: false`
and a reason, so one uncertain object does not block unrelated inspections.
Function dossiers retain this same string evidence. Native call edges retain
Hopper's partial `CallReference` classification and exact endpoints; detailed
reference flags remain unavailable rather than being invented.
Regex searches use ECMAScript Unicode syntax in a cancellable worker with a
five-second matching deadline. Deadline or cancellation stops matching while
leaving the Hopper API available. Literal mode retains Unicode casefold matching.
## Bounded static traces
`trace_native_ui_action` / `rea trace-native-ui-action <target> <seed>` accepts
@@ -255,130 +322,6 @@ scaled ADD/BR instructions and the recovered target set. It reads exactly the
proven count and preserves unknowns for other forms. Real ELF and host ARM64
Mach-O fixtures check each case against source-owned return values.
## Static inspection
`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
subject format describes the input container: `mach-o-universal` for FAT files,
including those with one slice. The normalized result describes the selected
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.
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;
architecture inventory locations remain available.
Hopper's `address_to_file_offset` combines the native image-relative mapping with
original-file coordinates only after checking the source against the session's
SHA-256. FAT tables and embedded Mach-O headers come from that same hashing pass.
A changed or nonregular source reports `artifact_changed`; an unreadable or
missing source reports its access or filesystem failure. Those errors retain the native offset,
loaded header and provider source path in `details.partial_observation`, with the
original-file coordinate explicitly unavailable. Restore the original bytes or
reopen the changed executable to obtain verified coordinates. Snapshot replay
remains historical evidence for its recorded artifact identity.
A selected Hopper database's digest identifies the database rather than its
original executable. Original-file mapping is unavailable for that selection;
native mapping facts remain in partial evidence, and `read_bytes` still reads
the loaded database. Open the original executable to verify source coordinates.
Native Xcode command execution uses shared process supervision with a 60-second
deadline and a 64 MiB aggregate stdout/stderr budget. Timeout, cancellation,
stream failure, and output exhaustion retain the captured output, exit details,
and cleanup outcome in the error result. Truncated output is never parsed as a
complete observation.
- `trace_dylib_resolution` / `rea trace-dylib-resolution <app-or-mach-o>`
parses Mach-O load commands in TypeScript and follows dyld's path expansion
for every executable in an app bundle, or for one Mach-O within its directory.
It reports each `@rpath`, `@loader_path` and `@executable_path` candidate with
its outcome. Paths outside the analyzed root, including shared-cache system
libraries, stay undetermined. See
[Apple application analysis](apple-application-analysis.md#dylib-load-resolution).
- `inspect_asset_catalog` / `rea inspect-asset-catalog <app>` reads compiled
`Assets.car` metadata through macOS `assetutil --info`. Catalog digests, raw
rendition fields, pagination and exact UI resource-name matches are returned.
Image extraction and undocumented rendition interpretation are unsupported.
- `inspect_keyed_archive` / `rea inspect-keyed-archive <plist>` reads XML or
binary Foundation keyed archives without instantiating classes. For an active
app, provide its relative archive path as the second CLI argument or MCP
`path`. Results retain original `$objects` indices, named `$top` roots,
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.
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. 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. `verify:interface-builder` compiles
a source-owned AppKit XIB with `ibtool`. Storyboards require an installed
iOS platform; unsupported archive forms remain explicit.
XML plist archives accept UTF-8 and BOM-marked UTF-16 in either byte order.
App bundle `Info.plist` executable resolution uses the same decoder as keyed
archives and Interface Builder. The decoder consumes an initial
BOM and rejects malformed byte sequences, unsupported encoding declarations,
and declarations that disagree with the detected encoding. It never substitutes
UTF-8 for a declared encoding it cannot process. Archive and evidence digests
still identify the original serialized bytes. Bundle resolution reports
malformed bytes and unsupported encodings against the original plist path
before looking up the executable. Interface Builder decoding
limits aggregate input archives to 32 MiB.
Before decoding, it also bounds the serialized structure: expanded binary
plist references, NIB table records, XML elements and text, plus their
projected representations must fit the 256 MiB aggregate decode budget.
NIB string values, data, property names and class names are charged at each
projected JSON occurrence, including when the archive reuses one source
value. Binary plist data projection also accounts for the temporary byte
copy made by the pinned decoder projection. These are format-derived
representation reservations, not exact heap measurements or a process-wide
heap ceiling.
Archives beyond either aggregate budget are omitted with their paths and an
explicitly partial `archive_decode` facet; previously decoded documents and
their identities remain available.
- `inspect_native_dispatch_metadata` /
`rea inspect-native-dispatch-metadata <app-or-binary>` prefers a validated macOS Mach-O byte reader. It decodes
64-bit little-endian Objective-C class/metaclass records, superclass pointers,
absolute/relative method entries, ivar offsets/sizes/alignment and protocol
declarations. It also decodes simple Swift conformances, static synchronous
witness slots, signed-relative pointers and non-generic, non-resilient class
vtable descriptors. Records include exact virtual addresses/file offsets and
artifact evidence. Vtable indexes are metadata word offsets; witness indexes
start after the conformance header. Names unavailable in metadata remain null.
Pointers are decoded through the image's fixups:
- `LC_DYLD_CHAINED_FIXUPS` rebases and binds, including the authenticated
arm64e formats;
- legacy `LC_DYLD_INFO` bind opcodes.
So an external superclass resolves from its `_OBJC_CLASS_$_` bind (for
example `NSObject`). The `pointer_fixups` coverage facet names the mechanism.
Class properties preserve each encoded attribute as a raw `{name, value}`
pair, for example `{ name: "N", value: "" }`, and report atomicity on the
property: `N` means `nonatomic`; a complete typed attribute string without
`N` means the Objective-C default `atomic`;
missing or incomplete attribute metadata leaves `atomicity` and any
unestablished read-only value null. `is_meta_class`, `is_root_class`, and
`ivar_count` are also nullable when the selected provider exposes only symbol
names. Class implementation methods have null `is_required` and `is_optional`
fields because those facts apply to protocol declarations; decoded protocol
method lists retain their observed required/optional values. Class properties
and `__objc_catlist` categories are also decoded. Categories record the
extended class, local or external, plus
their methods, protocols and properties; category methods appear as
implementations with a `category`. Swift field-offset globals that are only
initialized at runtime stay unresolved. Generic, resilient, async and
coroutine tables, and inherited overrides, have explicit unsupported or
partial coverage. Other providers retain the
existing symbol-based inventory with its narrower coverage.
## Native desktop observation
`observe_native_ui` captures one explicitly selected existing PID/window ID.
-130
View File
@@ -1,130 +0,0 @@
# Recorded packet capture inspection
`inspect_packet_capture` answers which selected protocol fields TShark observes
in an existing capture. Network, USB or Bluetooth recordings can use the same
field/filter interface when the installed TShark supports their encapsulation
and dissectors. This tool does not acquire traffic, open an interface or control
a device. HAR/SAZ/mitmproxy web-capture workflows remain separate.
Supply an existing TShark 4.x installation **on Linux**, with util-linux
`prlimit` available at `/usr/bin/prlimit`. Override its absolute path with
`REA_TSHARK_PRLIMIT_COMMAND` if required. Unsupported hosts, including macOS
and Windows, are refused before inspection because this integration requires
an enforced address-space limit:
```sh
export REA_TSHARK_COMMAND=/absolute/path/to/tshark
rea inspect-packet-capture /artifacts/device.pcapng \
--fields ip.addr --fields udp.port --fields data.data \
--display_filter 'udp' --format json
```
The corresponding MCP call is:
```json
{
"name": "inspect_packet_capture",
"arguments": {
"path": "/artifacts/device.pcapng",
"fields": ["ip.addr", "udp.port", "data.data"],
"display_filter": "udp"
}
}
```
`frame.number` is always included. Repeated values are ordered string arrays,
for example `"ip.addr": ["192.0.2.1", "192.0.2.2"]`. Missing fields remain
absent; they are not converted to zero or empty arrays. Export-only index/score
metadata is discarded. No payload bytes are automatically added; select a
supported byte field such as `data.data` or `@data` when needed.
Selectors are limited before argv expansion: at most 1,024 fields and 1,024
`decode_as` rules, 8,192 UTF-16 code units per selector, and 32 KiB total encoded
selector arguments (UTF-8 text, terminators, option names and argv pointers).
This leaves headroom below Linux's [execve argument/environment limits](https://man7.org/linux/man-pages/man2/execve.2.html);
an unusually large inherited environment can still prevent launching.
Output is paged after filtering: `match_limit` defaults to 50 and `match_offset`
to 0. The result retains original frame numbers and reports `output_window`
with the matching count within the input read scope, returned count and
`has_more`. Request later pages with the offset, or explicit `match_limit: null`
(CLI `--all_matches`) for all remaining matches. Paging does not shorten
input reading or change two-pass reassembly. Producer output must still fit its
resource limit; use selected fields, a display filter or an input-packet limit
when dissection output is too large. Each call checks the recording's current
digest, so pages from different source digests must not be combined.
Additional selections:
- `display_filter`: Wireshark display-filter syntax; omitted means no filter.
- `decode_as`: explicit dissector overrides, such as `["udp.port==5555,dns"]`.
Repeat `--decode_as` in the CLI for multiple overrides.
- `packet_limit`: optional maximum **input packets read before filtering**.
A limit of 1 can therefore yield zero matching packets even when later frames
match. Omitted means read to EOF within resource limits. The report records
`to-eof` or `up-to-input-packet-limit`, never inferring total capture size from
the returned packet count.
- `two_pass`: defaults to true for fields that need later packets and reassembly
dependencies. MCP may set false; CLI uses `--no-two_pass` for a single pass.
See the [TShark manual](https://www.wireshark.org/docs/man-pages/tshark.html)
for field names, display filters, decode-as syntax and pass semantics. Invalid
fields or filters return producer diagnostics. An empty result does not prove
absence of traffic outside the selected recording, filter or read range.
Dissector results are observations, not independently verified device behavior.
Evidence includes source path/digest/size, exact selections, typed packet fields,
configured and resolved executable paths/digests/full version banner, arguments and stderr. Warnings remain
visible even on exit zero. `tool.version_diagnostics` also retains warnings from
the separate version probe. Post-run identity failures identify the affected
private copy, executable or limiter; resource-signal errors retain the signal
and effective ceilings. Two-pass mode cannot recover missing capture bytes.
Each call uses a private read-only capture copy and an empty personal
configuration directory (`WIRESHARK_CONFIG_DIR`), with name resolution disabled.
The executable, resource limiter and private input copy are rechecked after execution. Owned
processes, file descriptors and private files are cleaned up; failed cleanup retains ownership and
completed observations for retry. The one-shot CLI awaits a cleanup retry while
preserving the original failure and completed Evidence. Completed observations
remain in the MCP session after cancellation or cleanup failure; bounded
post-run integrity checks finish before honoring a late abort. Source files
are never passed to TShark.
Installed libraries, global configuration and plugins remain trusted, are not
fully fingerprinted, and can influence dissection. This is not an OS sandbox.
Input is limited to 32 MiB before reading, each command to 30 seconds, and
combined stdout/stderr to 4 MiB during collection. Output overflow fails instead
of returning truncated success. Before execution, `prlimit` enforces **1 GiB
address space per process**, **64 MiB per file**, **30 CPU seconds** and no core
dumps. Stricter inherited soft/hard limits are preserved; Evidence records the effective
ceilings. Both limits are set before execution, so dissector allocations and
compressed-capture expansion cannot exceed the per-process address-space cap.
These are not aggregate process-memory or filesystem quotas. The selected
limiter is trusted; its path, digest and arguments are retained in Evidence.
No arbitrary process flags are accepted.
## Verification
```sh
npm run build:cached
REA_TSHARK_COMMAND=/absolute/path/to/tshark node scripts/verify-packet-capture.mjs
```
The verifier generates its own Ethernet/IPv4/UDP/DNS and Bluetooth HCI PCAPs.
It exercises real compiled CLI/MCP parity, advertised schemas, repeated/missing
fields, filtering, decode-as, both pass modes, a packet limit before matching
frames, Evidence persistence, failure diagnostics, source identity and cleanup.
An optional positional REA entrypoint verifies an installed package.
The real-tool lane requires Linux and TShark 4.x. A separate kernel-limit
regression checks the inherited soft/hard limits and verifies an oversized
allocation is refused before it can consume memory. The Ubuntu workflow uses
its distribution package; check its outcome before claiming that build verified.
The earlier macOS check does not establish the current bounded integration,
which deliberately refuses unsupported hosts. Other formats (including PCAPNG),
USB, BLE ATT and actual physical capture are not established by these fixtures.
Each provider admits one inspection at a time, including acquisition and cleanup.
An occupied provider returns a retryable capacity error before acquiring another
file or worker. Closing the provider stops new admission and drains accepted work;
failed cleanup remains owned and can be retried.
-118
View File
@@ -1,118 +0,0 @@
# Packet capture summaries
REA summarizes already saved pcap/pcapng files through caller-selected Wireshark
4.x `tshark` and `capinfos`. Use `inspect_packet_capture` for selected fields,
filters and decode-as rules; use this family for address, DNS, SNI, protocol-stack
and URI inventories. It does not acquire traffic or fetch recorded targets.
## Supply tools
```sh
export REA_TSHARK_COMMAND=/absolute/path/tshark
export REA_CAPINFOS_COMMAND=/absolute/path/capinfos
# Linux only; default /usr/bin/prlimit
export REA_TSHARK_PRLIMIT_COMMAND=/absolute/path/prlimit
rea inspect-pcap-client
rea inspect-pcap-capture /captures/session.pcapng --json
```
Without explicit tool commands, this family resolves them through PATH and
records that selection source. Client inspection reads no capture file. Capture
inspection requires Linux with util-linux prlimit or Windows with owned Job
Objects. macOS capture inspection returns a capability gap because the new
native memory boundary is unverified; its version probes remain available.
Tools and installed libraries/plugins are caller-trusted. An empty private
personal Wireshark configuration is used; this is not an OS sandbox.
## Inspect only the needed facts
MCP `inspect_pcap_capture` accepts `path` and optional `detail: "summary"`.
Complete delivery remains the default. Summary commits and retains the same
complete Evidence, returning identity, capture metadata, observed counts,
retained counts, source coverage and diagnostic lengths without large lists.
Then use its `normalized_result.parent_evidence_id` with
`inspect_analysis_view` source kind `retained-evidence`:
```json
{"kind":"pcap","facet":"endpoints","offset":0,"limit":20}
{"kind":"pcap","facet":"dns-queries","offset":0,"limit":20}
{"kind":"pcap","facet":"dns-addresses","query":"example.com","offset":0,"limit":20}
{"kind":"pcap","facet":"tls-sni","offset":0,"limit":20}
{"kind":"pcap","facet":"diagnostics","stream":"tshark","offset":0,"limit":4096}
```
Other row facets are `protocols`, `http-uris` and `unattributed-addresses`.
Defaults are offset 0 and limit 64. DNS question pages give address counts;
select one exact retained question to page its addresses. Diagnostic windows
count UTF-16 code units; other windows count rows. Missing/ambiguous selectors
fail. Unknown legacy diagnostics remain unknown, not an observed empty stream.
Portable CLI views use the existing `inspect-analysis-view` workflow with inline
complete Evidence. Views never reread the source or launch Wireshark and work
after the original file is deleted. Page exhaustion covers the retained facet;
it does not establish network completeness or recover missing traffic.
## Interpret provenance and coverage
`target.sha256` binds observations to an admitted stable capture snapshot. Both
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.
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.
Ambiguous addresses remain in a separate inventory. Protocol distribution counts
exact `frame.protocols` stack strings. TLS SNI is recorded handshake metadata,
not process identity or proof of the destination's authenticity.
All examined inventories are retained within the resource budget; no fixed
200/100/50-item truncation is applied. HTTP transport credentials are excluded
without rewriting other URI bytes; ambiguous credential spans cause omission.
Counts preserve distinct observed source URIs before omission or coalescing.
`coverage: "partial"` records unresolved DNS attribution or URI item loss;
component credential exclusion is also counted explicitly. Diagnostics retain
both tool stderr streams. Recorded fields do not establish decrypted payloads,
causality, process identity, absence of unrecorded traffic or current deployments.
## Resources and lifecycle
One inspection is admitted at a time per provider. Concurrent calls return a
capacity error; close drains active work before releasing resources. Captures
are streamed into a read-only owned snapshot with a 2 GiB disk budget. Native
capture commands enforce Linux address-space ceilings of at most 1 GiB,
300 CPU seconds, 64 MiB per file and no core dumps, preserving stricter inherited
limits. Windows uses a 1 GiB committed-memory limit for each owned tool tree.
These are not aggregate machine or filesystem quotas.
TShark output is bounded at 8 MiB; its known five-level selected-field shape and
128 MiB graph-expansion estimate are checked before allocation. Retained facts
have a separate 16 MiB estimate. Capinfos output is limited to 64 KiB. Command
wall deadlines are 300 s for dissection, 60 s for metadata and 20 s for probes.
Native ownership preparation has its own bounded lifecycle.
Malformed/oversized output returns no partial success. Unvalidated partial JSON
is not returned as facts. Cancellation reaches probes, acquisition, commands and
projection. Cleanup failure returns a typed error, retains completed Evidence
when available, and retains owned resources for retry on close.
## Verification scope
Current follow-up verification uses Linux/Node 24.18.0 and Wireshark 4.0.17.
Private real recorded corpora are checked against independent raw-frame/IP
parsing and Python aggregation, public CLI/stdio MCP parity, SDK schemas, source
hashes and retained views. Synthetic native tools separately test malformed
output, cancellation, source/snapshot mutation, capacity and cleanup; they do
not establish real Wireshark or other-platform behavior.
The original proposal reported Linux 4.6.6, macOS/Windows 4.6.9 verification on
its earlier implementation. Those reports do not verify the new final memory
boundary. Actual Windows/Bun Wireshark execution is unverified here; macOS
capture support needs a separate enforceable-bound decision.
```sh
npm run verify:pcap -- --pcap /absolute/saved-capture.pcapng
```
This verifier exercises built CLI/stdio MCP, schemas, artifact identity and
cleanup. Without `--pcap`, capture inspection is reported as unverified. Private
captures, keys and provider runtime files are not committed.
+67 -134
View File
@@ -40,17 +40,7 @@ this helper before reporting macOS capture as available.
## Capture a command
For a small first capture, save this as `scenario.json`:
```json
{
"executable": "node",
"arguments": ["-e", "console.log('ready')"],
"timeout_ms": 5000
}
```
Run the scenario through the CLI:
Write a JSON scenario and pass its path to the CLI:
```sh
rea capture-process ./scenario.json --json > capture.json
@@ -61,85 +51,6 @@ format is TOON. The file contains the complete capture Evidence record.
Choose an output file distinct from the scenario input: shell redirection opens
and truncates the output before REA reads the scenario.
Read the result's terminal observations, exit/settlement status, and cleanup
outcome. [Scenario and result details](#scenario-and-result-details) describe
limits, normalization, filesystem coverage, and incomplete observations.
## Compare two captures
Compare saved capture Evidence with:
```sh
rea compare-process-captures authority.json reconstruction.json
```
The comparison checks terminal, interaction, exit, filesystem, and
process observations under a shared comparison contract. It reports observed
differences with their locations, while residual unknowns or truncated
observations prevent a complete-equivalence claim. Matching scenario
commitments do not reveal whether redacted sensitive inputs were equal.
For scenarios where independent scheduling can change event order, the CLI
also accepts an optional trace-specification JSON file as the third argument.
That specification must state the exact events and ordering constraints to
accept; it does not discard unmatched observations or make timestamps into
causal evidence. Trace comparison returns `unknown` when a capture lacks the
required complete event journal or contains relevant residual unknowns.
Each capture carries commitments for the selected scenario, executable,
comparison contract, and normalization rules. The comparison contract covers
the working directory, explicit environment, filesystem observation paths,
terminal size, scripted events, timeouts, limits, and normalization; the
executable and its arguments may differ. Comparison rejects captures whose
comparison contracts differ and names the differing fields, so run both
scenarios from the same absolute working directory and observation paths.
Captures are local Evidence files; keep
their source artifacts and invocation context available when interpreting a
difference.
## Hash a report independently of terminal output
Select the producer's report directory and give `file_bytes` enough room for
the complete files you need, including other files in those roots. For example,
save this scenario and run `rea capture-process ./scenario.json --json > capture.json`:
```json
{
"executable": "node",
"arguments": [
"-e",
"const fs=require('node:fs');fs.mkdirSync('reports',{recursive:true});fs.writeFileSync('reports/final.json',JSON.stringify({status:'complete',data:'X'.repeat(131072)}));console.log('x'.repeat(8192));"
],
"working_directory": ".",
"filesystem_observation_paths": ["./reports"],
"limits": { "output_bytes": 1024, "file_bytes": 262144 }
}
```
The report exceeds the terminal budget but fits the independent 256 KiB hash
budget. Its complete SHA-256 appears in `normalized_result.files_after` at
`root_0:final.json`; check `truncation_details.filesystem_after` for omissions
and actual bytes hashed. The verbose terminal output is truncated without
preventing the report digest. The same scenario object is the MCP
`capture_process_scenario` input. REA never returns a prefix hash as a full-file
digest: an insufficient remaining budget produces a null digest and an
explicit omission reason.
A digest binds the complete bytes observed at that checkpoint, not the
producer's notion of a finished report. A stable periodic or running report
can also have a complete digest. Choose the final file and verify the
producer's documented completion marker, exit outcome and settlement
observations before calling it final. `after_settlement` names a filesystem
checkpoint, not a guarantee that an application finished successfully or
that an unobserved writer will never change the file. REA checks opened-file
identity/state around hashing and reports observed changes or unavailable
files; cancellation stops the hash. If an external sealer produces a manifest,
keep its completion claims and digest separate from REA's checkpoint facts.
## Scenario and result details
### Progress
While the capture runs, REA writes live status to stderr as one JSON object per
line. Stdout stays the final Evidence document:
@@ -168,7 +79,7 @@ into the latest status, and stale live observations are discarded before final
cleanup status. Progress never copies child output. Child output remains in the
capture Evidence on stdout.
### Scenario with interactions
For example:
```json
{
@@ -417,51 +328,73 @@ as well. A newly started unreadable process can prevent verified cleanup even
after the selected command exits. REA preserves this uncertainty and leaves
that process untouched.
Reading those tokens requires compiling a small Swift helper with `xcrun swiftc`.
By default that compilation reuses Swift's shared module cache, while the
compiler's intermediate objects stay inside the per-run temporary root that REA
removes afterwards. Set `REA_DARWIN_MODULE_CACHE_PATH` to a writable directory
when a shared cache is unavailable, for example under an enforced write
boundary. REA creates the directory, passes it to the compiler as
`-module-cache-path`, and exports it as `CLANG_MODULE_CACHE_PATH` so the
Objective-C header modules the helper builds land there too. REA never removes
that directory: it outlives each run, so the first compilation into a new
directory pays a cold-cache build and later runs reuse it. An absent or empty
value keeps the shared default.
## Hash a report independently of terminal output
`xcrun` also maintains a separate tool-lookup cache. Its `--no-cache` option
refreshes entries and does not guarantee a write-free lookup. To avoid that
lookup while compiling REA's helper, set `REA_DARWIN_SWIFTC_PATH` to the absolute
path of an installed `swiftc` and `SDKROOT` to the absolute path of a compatible
macOS SDK. REA invokes that compiler directly with `-sdk` and the selected SDK;
an unset or empty compiler setting keeps the normal `xcrun swiftc` path. A
missing or relative SDK/compiler path fails with an actionable prerequisite
error before compilation. An incompatible installation reports the compiler's
bounded diagnostics; REA does not repair or replace the toolchain.
Select the producer's report directory and give `file_bytes` enough room for
the complete files you need, including other files in those roots. For example,
save this scenario and run `rea capture-process ./scenario.json --json > capture.json`:
For example, select paths from your existing Xcode or Command Line Tools
installation **before** entering an enforced write boundary:
```sh
export REA_DARWIN_SWIFTC_PATH="$(xcrun --find swiftc)"
export SDKROOT="$(xcrun --show-sdk-path)"
export REA_DARWIN_MODULE_CACHE_PATH="$PWD/rea-cache/modules"
export TMPDIR="$PWD/rea-cache/tmp"
mkdir -p "$TMPDIR"
rea analyze-javascript-application ./fixture --artifact-format directory
```json
{
"executable": "node",
"arguments": [
"-e",
"const fs=require('node:fs');fs.mkdirSync('reports',{recursive:true});fs.writeFileSync('reports/final.json',JSON.stringify({status:'complete',data:'X'.repeat(131072)}));console.log('x'.repeat(8192));"
],
"working_directory": ".",
"filesystem_observation_paths": ["./reports"],
"limits": { "output_bytes": 1024, "file_bytes": 262144 }
}
```
Keep the selected compiler and SDK paired. Permit REA's evidence/output paths
and its temporary directory as well as the caller-owned module cache. REA does
not create a sandbox or claim that these settings contain every write made by
arbitrary toolchains or analysis providers. They bypass REA's `xcrun` lookup
and select the helper's Swift/Clang cache without disabling ownership checks.
The caller-owned cache survives cancellation and cleanup; per-run compiler
intermediates and the compiled helper remain REA-owned temporary files.
The report exceeds the terminal budget but fits the independent 256 KiB hash
budget. Its complete SHA-256 appears in `normalized_result.files_after` at
`root_0:final.json`; check `truncation_details.filesystem_after` for omissions
and actual bytes hashed. The verbose terminal output is truncated without
preventing the report digest. The same scenario object is the MCP
`capture_process_scenario` input. REA never returns a prefix hash as a full-file
digest: an insufficient remaining budget produces a null digest and an
explicit omission reason.
The boundary must also permit process-table inspection. On macOS, `/bin/ps`
is setuid and a blanket sandbox may reject its launch with `spawn EPERM`.
REA then preserves ownership uncertainty and can report `cleanup_incomplete`;
it does not disable verification to continue. A sandbox that explicitly allows
this read-only process inspector is a separate prerequisite from the compiler
and cache settings.
A digest binds the complete bytes observed at that checkpoint, not the
producer's notion of a finished report. A stable periodic or running report
can also have a complete digest. Choose the final file and verify the
producer's documented completion marker, exit outcome and settlement
observations before calling it final. `after_settlement` names a filesystem
checkpoint, not a guarantee that an application finished successfully or
that an unobserved writer will never change the file. REA checks opened-file
identity/state around hashing and reports observed changes or unavailable
files; cancellation stops the hash. If an external sealer produces a manifest,
keep its completion claims and digest separate from REA's checkpoint facts.
## Compare two captures
Compare saved capture Evidence with:
```sh
rea compare-process-captures authority.json reconstruction.json
```
The comparison checks terminal, interaction, exit, filesystem, and
process observations under a shared comparison contract. It reports observed
differences with their locations, while residual unknowns or truncated
observations prevent a complete-equivalence claim. Matching scenario
commitments do not reveal whether redacted sensitive inputs were equal.
For scenarios where independent scheduling can change event order, the CLI
also accepts an optional trace-specification JSON file as the third argument.
That specification must state the exact events and ordering constraints to
accept; it does not discard unmatched observations or make timestamps into
causal evidence. Trace comparison returns `unknown` when a capture lacks the
required complete event journal or contains relevant residual unknowns.
Each capture carries commitments for the selected scenario, executable,
comparison contract, and normalization rules. The comparison contract covers
the working directory, explicit environment, filesystem observation paths,
terminal size, scripted events, timeouts, limits, and normalization; the
executable and its arguments may differ. Comparison rejects captures whose
comparison contracts differ and names the differing fields, so run both
scenarios from the same absolute working directory and observation paths.
Captures are local Evidence files; keep
their source artifacts and invocation context available when interpreting a
difference.
+1 -1
View File
@@ -61,7 +61,7 @@ Independent raw verification streams the complete private snapshot digest and
extent with bounded memory and supports cancellation during the read.
Hopper and IDA refuse raw-binary targets. Windows Ghidra P0 continues to admit
native PE applications and DLLs only; raw-binary targets are unsupported.
PE applications only.
## Limitations
+1 -1
View File
@@ -36,7 +36,7 @@ check project-owned conformance fixtures and fail-closed report behavior.
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `discover-classify` | target-free startup, artifact inventory, compatible workflow selection, and exact visible limits |
| `diagnose-environment` | broken runtime separated from analysis failure, version skew detected, and revision changed after recovery |
| `acquire-authority` | missing scope reported, narrow grant resumed, expansion reprompted, and denial launched nothing |
| `declare-request` | exact target, operation, and lifecycle are carried by the request before launch |
| `static-analysis` | native and JavaScript routing plus preserved ambiguity, truncation, unsupported syntax, and residual unknowns |
| `reactive-scenarios` | predicate-driven interaction, descendant settlement, Electron correlation, and cancellation cleanup Evidence |
| `compare-authority-candidate` | explicit partial-order/finite-trace semantics, primary divergence localization, and unknown for incomplete comparison |
-9
View File
@@ -218,15 +218,6 @@ release baseline and can propose an already-published version again.
After publication, open a PR from the release branch back to main. Preserve
main's later implementation changes and regenerate ignored build outputs from
the combined contracts with the released package version.
Before merging, check whether GitHub permits merge commits:
```bash
gh api repos/morluto/rea --jq .allow_merge_commit
```
If disabled, a maintainer must arrange an approved ancestry-preserving merge
path before synchronization can finish. Squash and rebase merges do not put the
released tag in main's ancestry. Do not substitute them for this step.
Review and test this synchronization PR, then use a merge commit so the release
tag remains in main's ancestry. Keep the released tag unchanged.
-108
View File
@@ -1,108 +0,0 @@
# Recorded signal decoding
`decode_signal_recording` answers what a selected protocol decoder observes in
an existing recording. It uses caller-supplied **sigrok-cli 0.7.2** with
libsigrokdecode on **Linux**. util-linux `prlimit` is required (default
`/usr/bin/prlimit`, overridable with absolute `REA_SIGROK_PRLIMIT_COMMAND`).
The limiter sets soft and hard address-space limits before the decoder starts.
macOS and Windows are refused because this adapter cannot enforce that limit on
those hosts. It does not acquire samples or communicate with hardware.
```sh
export REA_SIGROK_COMMAND=/absolute/path/to/sigrok-cli
rea decode-signal-recording /artifacts/uart.vcd \
--decoders uart:rx=RX:baudrate=9600 --input_format vcd \
--annotations uart=rx-data --format json
```
The corresponding MCP request is:
```json
{
"name": "decode_signal_recording",
"arguments": {
"path": "/artifacts/uart.vcd",
"decoders": "uart:rx=RX:baudrate=9600",
"input_format": "vcd",
"annotations": "uart=rx-data"
}
}
```
`decoders` uses sigrok's decoder stack and option/channel syntax. Channel names
must match the recording; REA does not guess wiring, baud rate or protocol.
Omitting `input_format` requests sigrok's autodetection. Omitting `annotations`
retains every annotation class. Both omitted selections are recorded as null.
See the [upstream manual](https://sigrok.org/wiki/Sigrok-cli) for formats,
decoder stacking and annotation selectors. No arbitrary command flags are accepted.
Output defaults to 50 literal LF-separated lines. Use `line_offset` and
`line_limit` for later pages, or MCP `line_limit: null` / CLI `--all_lines`
for all remaining output. `output_window` reports `total_lines`, `returned_lines`
and `has_more`; these count display lines, **not annotations or samples**.
Line endings, blank lines and text within the selected window stay unchanged.
REA does not parse display text into protocol facts, as explained by
[upstream's annotation output guidance](https://sigrok.org/wiki/Protocol_decoder_output).
Paging does not shorten decoding and producer output must still fit its limit.
Use annotation-class selection to reduce producer output. Calls independently
check the source digest; do not combine pages from different digests.
Each selector is limited to 8,192 UTF-16 code units, and total encoded selector
arguments (UTF-8, option prefixes, terminators and 64-bit argv pointers) to
32 KiB before launching. This reserves headroom below Linux execve's minimum
argument/environment budget; a large inherited environment may still exhaust it.
The returned Evidence includes the input path/digest, exact selections, tool
configured and resolved paths/digests, full version banner (including library versions), annotation text
with sample-number ranges, and stderr. For example, `1104-1938 uart-1: 52`
is producer display text over a sample range, not a timestamp or an independently
verified protocol fact. Text is retained verbatim; it is not parsed as a lossless
binary payload. Empty output does not establish absence of traffic. Warnings
remain visible even when sigrok exits zero, including `tool.version_diagnostics`
from the separate version probe. Post-run identity failures name the tool, limiter
or private copy involved, rather than blaming the admitted source. Resource-signal
failures retain the signal and effective limits without inferring its exact cause.
REA decodes a private, read-only copy of the recording, verifies that copy and
the selected executable and resource limiter after decoding, and removes the workspace after owned
process cleanup. Failed descriptor, process or workspace cleanup retains ownership for retry, and the one-shot
CLI awaits a retry without replacing the original failure or completed Evidence.
Completed observations remain in the MCP session after cancellation or cleanup
failure; bounded post-run integrity checks finish before honoring a late abort. The source file is
never passed to sigrok. Caller-supplied tools and their libraries/decoder modules
are trusted, and hashes identify bytes rather than publisher authenticity.
The input copy is bounded at 32 MiB before reading, each command has a 30-second
deadline, and combined stdout/stderr is bounded at 4 MiB during collection.
Oversized output fails rather than becoming truncated success. These limits do
not form an OS sandbox. Before execution, `prlimit` enforces **1 GiB address
space per process**, **64 MiB per file**, **30 CPU seconds** and no core dumps.
Stricter inherited soft/hard limits are preserved; Evidence records the effective
ceilings. Both limits are set before execution, so decoder allocations and compressed
recording expansion cannot exceed the per-process address-space cap. These are
not aggregate process-memory or filesystem quotas. The selected limiter is
trusted and its path, digest and arguments are retained in Evidence.
## Verification
```sh
npm run build:cached
REA_SIGROK_COMMAND=/absolute/path/to/sigrok-cli node scripts/verify-signal-recording.mjs
```
The verifier synthesizes a 9600-baud 8N1 UART VCD carrying `REA`, then checks
actual CLI/MCP parity, advertised schemas, stored Evidence, source hashes,
annotation filtering/autodetection, invalid decoder/input failures and cleanup.
An optional positional REA entrypoint verifies an installed package.
The real-tool lane requires Linux, sigrok-cli 0.7.2 and libsigrokdecode. A separate
kernel-limit regression checks the inherited soft/hard limits and verifies an
oversized allocation is refused before it can consume memory. Other formats,
decoders and physical acquisition are not established by the UART fixture.
The workflow result must be checked before claiming a specific Linux build
verified. The earlier macOS tool check does not establish the current bounded
integration, which deliberately refuses unsupported hosts.
One decode is admitted at a time, including acquisition and cleanup. Excess
requests receive a retryable capacity error before acquiring another file or
worker. Shutdown closes admission and drains accepted work; failed cleanup
remains owned and retryable.
-144
View File
@@ -1,144 +0,0 @@
# SQLite database snapshots
`inspect_sqlite_database` / `inspect-sqlite-database` inspects one explicitly
selected local SQLite database snapshot without an active native analysis
target. Use it to understand application storage, configuration or retained
database evidence. No separate SQLite installation is required.
This operation requires Node.js 24.x >=24.15 or 26+ with the native
`DatabaseSync.limits` API. The worker verifies that capability before querying
the copied database. Other REA features retain their published Node.js 22.x,
24.x or 26+ requirements.
`rea capabilities` reports `inspect_sqlite_database` availability and the
runtime requirement without opening a database. Unsupported runtimes show
`available: false`, `availability_code: "unsupported_version"`, and an upgrade
note while the inventory command still succeeds.
```sh
rea capabilities --json
rea inspect-sqlite-database ./application.sqlite --json
rea inspect-sqlite-database ./application.sqlite --table settings --column key --column value --row-limit 20 --json
```
```json
{
"name": "inspect_sqlite_database",
"arguments": {
"path": "/artifacts/application.sqlite",
"table": "settings",
"columns": ["key", "value"],
"row_limit": 20
}
}
```
MCP paths must be absolute filesystem paths on the current host. CLI paths
resolve against the operator's working directory. Select a quiescent snapshot:
stop the writer or obtain a consistent database/WAL pair using the application's
backup workflow before inspection. A file copy of a live pair does not establish
an atomic SQLite snapshot, even if no change is detected during inspection.
## Returned evidence
Without a table selection, the default `schema_scope` is `inventory`: compact
table metadata and index, view and trigger names, without SQL declarations or
column details. Selecting a table defaults to `selected_table`, which expands
that table and its indexes and triggers. Explicit `schema_scope: "database"`
(or CLI `--schema-scope database`) expands all stored declarations and supported
columns. `schema.completeness` refers to the reported scope; omitted column
details are marked `not_requested`. SQL declarations retain the original text. Virtual and
shadow tables are identified as such; their supported metadata coverage is
reported. If a virtual table cannot be resolved, possible backing tables have
`kind: "unknown"` and an explicit limitation; their rows are refused. Unrelated
ordinary tables remain selectable. Schema inventory does not execute views,
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. 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
the selected limit, returned count and whether more rows were observed. Row
order is unspecified; a truncated sample does not prove anything about omitted
records. View, virtual-table and shadow-table row reads are unsupported.
SQLite integers are decimal strings so every signed 64-bit value survives JSON
serialization. Real values retain their numbers; `"Infinity"`, `"-Infinity"`
and `"-0"` explicitly preserve infinities and negative zero through JSON.
Text returns the decoded string together with its bytes as hex and the database
encoding, preserving malformed text that the SQLite binding may replace for
display. Blobs are hex, and SQL NULL is a distinct tagged value.
Database and existing sibling `-wal` files have separate original SHA-256 and
byte counts. The Evidence subject identifies the original database file;
the WAL identity is also necessary to interpret pending committed data. The
SQLite engine version is reported with the observed result. Neither digest is
a claim that the database is healthy, complete or trusted.
## Source files and failures
REA copies the selected database and existing sibling WAL to an owned private
temporary directory before SQLite opens them. Source files are not opened by
SQLite, so its locks or shared-memory sidecars cannot modify the original
snapshot. Temporary copies and the owned worker are cleaned up on success,
failure and cancellation. Extension loading and schema trust are disabled.
Empty rollback journals and fully zeroed journal headers left by successful
`TRUNCATE` and `PERSIST` commits are accepted after stable identity checks.
Journal headers are checked both before and after acquisition; unchanged file
metadata alone does not establish that a journal remains inactive.
Other retained rollback journals are refused because recovery is outside this
profile. Journal files are never modified or copied into the worker snapshot.
A provider admits at most two inspections through acquisition, worker execution
and cleanup. Additional requests receive a typed capacity error before reading
files or creating workers; retry after an active inspection finishes. This
bounds simultaneous input buffering and private snapshot/worker counts.
The database and WAL together are limited to 256 MiB. SQLite values/records,
SQL statements and the complete worker JSON reply each have a 16 MiB limit.
The owned worker has a 256 MiB JavaScript heap limit and a 30-second inspection
deadline. SQLite native allocations are separate from the JavaScript heap;
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.
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
client/server response budget or using complete CLI JSON output.
A cancellation received after the worker has completed does not erase the
completed observation. If subsequent private-root cleanup fails, the error
retains the completed Evidence and the resource owner for cleanup retry. MCP
records that Evidence before delivering the error, which carries its retained
evidence ID for later retrieval or export.
Changed input identities, special files, malformed databases, unsupported
formats and resource failures are reported as errors with the selected path and
meaningful reason. Encrypted databases, database repair, arbitrary SQL,
cross-database queries and live capture are outside this inspection's coverage.
## Compatibility verification
Run `npm run test:sqlite` after changing the SQLite adapter or its shared
process, filesystem, CLI or MCP boundaries. It prepares the compiled runtime
and runs SQLite service, snapshot, inspection, cleanup and public CLI/MCP
tests. Directory-based selection includes new SQLite service and boundary
tests automatically. `npm run test:sqlite:run` runs the same cases when the
compiled runtime and generated test artifacts are already current.
The reusable SQLite CI workflow consumes the shared build artifact and tests
the latest Node 22.x unavailable-runtime diagnostics, the minimum supported
24.15.0 release, and the latest 24.x and 26.x releases. The repository-pinned
runtime also runs the full suite. CI's required gate waits for every selected
SQLite matrix job; a failed, cancelled, skipped or missing selected lane blocks
the gate. Workflow changes themselves select the build and compatibility lane.
PR checks run against GitHub's merge with the current base branch. A later
change to `main` can introduce failures outside SQLite; inspect the failing
job and recheck the updated merge before treating an earlier green run as
current verification. Compatibility checks detect regressions, but cannot
guarantee that an arbitrary future upstream change remains compatible.
+641 -304
View File
File diff suppressed because it is too large Load Diff
+4 -6
View File
@@ -48,12 +48,10 @@ satisfy. A plan without execution does not establish runtime behavior.
- Use strict inputs with explicit target identity and required fields. Preserve
meaningful target, action, capture, and output choices; remove ignored options
and repeated permission declarations.
- Return the requested facts inline with artifact/provider identity, source
locations, Evidence references, coverage, and relevant confidence and
limitations. Use supported selection, summaries or views when they answer
the question; preserve access to complete source Evidence and honor existing
contracts and requested detail. Missing coverage is unknown, not absence.
Avoid extra lookups solely to understand the answer or its provenance.
- Return complete evidence inline, with artifact/provider identity, source
locations, Evidence references, and relevant confidence and limitations.
Missing coverage is unknown, not absence. Avoid extra lookups solely to
understand the answer or its provenance.
- Keep observed, derived, and inferred relationships distinct. Preserve
unresolved edges and partial provider facts instead of requiring every
provider to supply the same metadata.
+1 -1
View File
@@ -77,5 +77,5 @@ Candidates are caller-selected files; their identity does not imply validation.
Both CLI and MCP use the same typed port and application service. MCP publishes
SDK-compatible schemas and records Evidence for `get_evidence_bundle` readback.
See [WABT provenance](https://github.com/morluto/rea/blob/main/third_party/wabt/README.md) and
See [WABT provenance](../third_party/wabt/README.md) and
[testing](testing.md#offline-wasm-artifacts) for real-tool verification.
+7 -212
View File
@@ -25,36 +25,6 @@ and original zero-based producer ordinals; duplicate or out-of-range selections
are input errors. Every record is validated before selection, so selecting one
entry does not hide a malformed entry elsewhere.
For agent discovery over MCP, request `detail: "summary"`. REA retains the
complete selected Evidence in the session and returns identity and counts.
Use `normalized_result.parent_evidence_id` with `inspect_analysis_view`:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": { "kind": "capture", "detail": "preview", "offset": 0, "limit": 20 }
}
```
Preview pages select recorded HTTP headline fields, event names/times when
present, original locations and byte descriptors; they omit headers, XML and
payload content. Choose `detail: "complete"` in that view for exact record
pages, including all sidecars. Offsets follow the parent's selected record
order; producer ordinals remain unchanged. `total_records` counts the original
capture while `retained_records` and page coverage count records in the parent.
An exhausted page does not establish absence from unselected records.
Views do not reopen the file or rerun its decoder. They remain historical
Evidence if the source changes or disappears; inspect the capture again to
observe new bytes. The inspection tool's default `detail: "complete"` preserves
existing inline delivery. For CLI use, save complete inspection JSON and pass
it as inline Evidence to `inspect-analysis-view`; the same summary and capture
page contracts apply. Large complete records can still exceed MCP's response
budget; export the retained Evidence when a single record cannot fit.
## Formats and upstream profiles
HAR uses unchanged `har-schema@2.0.0` draft-06 schemas, `ajv@8.20.0`,
@@ -87,80 +57,11 @@ tested upstream source is tag `v12.2.3`, commit
an explicit unsupported-profile diagnostic. Non-Linux native decoding is not
supported by this adapter.
## Reading Fiddler captures (`.saz`)
Fiddler Everywhere saves traffic in **Session Archive Zip (`.saz`)** files.
Inspect native SAZ directly, without installing Fiddler or converting to HAR:
```sh
rea inspect-web-network-capture /absolute/session.saz saz --json
rea inspect-web-network-capture /absolute/session.saz saz --record 0 --json
```
MCP uses the same `capture_path`, `format: "saz"`, and optional
`record_ordinals` fields as the examples above. REA pairs `raw/<id>_c.txt`
requests, `_s.txt` responses, and `_m.xml` metadata by filename stem. Archive
member names identify the source; zero-based ordinals follow each session's
first member in ZIP directory order, not its numeric ID or capture time.
HTTP fields and ordered duplicate headers are retained, with stored body bytes
in binary sidecars. Bodies are not dechunked or decompressed. Metadata is an
XML node tree; optional `_w.txt` and `_g.txt` files retain opaque WebSocket and
gRPC message bytes. Missing members remain null, distinct from empty bodies.
See Telerik's [SAZ format reference](https://www.telerik.com/fiddler/fiddler-everywhere/documentation/knowledge-base/fiddler-archives).
The existing ZIP reader verifies read members; expanded archive contents are
limited to 32 MiB in addition to the input/output budgets below. Encrypted
archives and unrecognized raw session members are unsupported. SAZ requires an
enforced decoder memory bound: Node's fixed heap, or the Windows Job Object
commit limit. Bun on hosts without that Job Object limit returns capability
unavailable before starting the SAZ decoder. Non-session
members are inventoried without decoding their content. Original files remain
unchanged. Linux verification includes independently checked public recorded
Mattermost captures from [FOREST](https://github.com/dfrc-korea/FOREST/tree/405c9154658a128ea203a6c10040cec55111ed03/api-results/dataset)
and the Fiddler author's [encoding corpus](https://github.com/ericlaw1979/Clearinet/blob/b6faf78cde1e72042980364f180ceb34b77d1434/Test/data/Encodings.saz),
plus synthetic malformed/limit fixtures. Their exporting product versions are
not authenticated. An interactive export from a current Fiddler Everywhere
installation and its live MCP server remain unverified. Support here is the
bounded documented raw HTTP/XML SAZ layout, not every product/version profile.
For visual inspection, use Everywhere's **Import Snapshot**, then **Inspectors**
and **Overview**. HAR remains an alternative: select sessions, choose
**Export > HTTPArchive**, and confirm `log.version` is `"1.2"`. Preserve the
original SAZ when exporting. See the [import/export instructions](https://www.telerik.com/fiddler/fiddler-everywhere/documentation/collaboration/exporting-and-importing).
## Fiddler Everywhere MCP and public skills
For agent-driven traffic debugging, connect Everywhere's MCP server separately
from REA. Run a current Everywhere release with MCP access (Trial, Pro, or
higher), internet access, and a compatible MCP client. Use
**Settings > MCP Server > Coding agent**, or **Manual setup** with the generated
API key. The default endpoint is `http://localhost:8868/mcp`. See Telerik's
[MCP setup guide](https://www.telerik.com/fiddler/fiddler-everywhere/documentation/agent-tools/fiddler-mcp-server)
and [agent-skills prerequisites](https://www.telerik.com/fiddler/fiddler-everywhere/documentation/agent-tools/agent-skills).
Telerik's [public skills](https://github.com/telerik/fiddler-agent-tools) cover
installation (`fiddler-download-setup`), connection setup, and traffic analysis:
```sh
npx skills add telerik/fiddler-agent-tools --skill fiddler-mcp-setup
npx skills add telerik/fiddler-agent-tools --skill fiddler-traffic-debugging
```
After setup, reload the agent client and use the connected server's advertised
tool names and schemas. Check status, list sessions, then inspect relevant
session IDs. Set `sessionsSource` to `LiveTraffic` for HTTP(S) traffic or
`AgentCalls` for enriched LLM calls; active filters affect the session list.
For an existing run, skip the skill's pre-capture steps that replace process
filters and clear sessions. The documented MCP session sources do not provide
a saved-snapshot selector; use the SAZ workflow above for saved files. REA does
not register or wrap the Fiddler MCP server.
## Reading the evidence
- `artifact` identifies the caller-selected file and stable snapshot digest.
- `records` preserve producer order/ordinals and original JSON pointers, byte
ranges, or SAZ member names. No live browser transaction or scenario IDs are invented.
- `records` preserve producer order/ordinals and original JSON pointers or byte
ranges. No live browser transaction or scenario IDs are invented.
- `reported` retains the producer's fields. HAR container metadata is returned
separately, with `log.entries` replaced by `null` and `records_pointer`
identifying the record collection. This is an inspection representation,
@@ -255,7 +156,7 @@ response fields, including HAR's `status: 0` and an empty `mimeType`, remain
unknown, not invented statuses or MIME types.
The view makes no handler-identity, schema or causality claim. It performs no
network activity. Native mitmproxy, SAZ and qlog captures return a typed unsupported error.
network activity. Native mitmproxy captures return a typed unsupported error.
Parents inspected with `sensitive_values`, or whose Evidence does not record
`sensitive_value_count`, return a typed unsupported error whose reason is the
canonical token `sensitive_values_unretained`. The view would write path
@@ -291,15 +192,14 @@ Complete evidence has a 32 MiB input, 96 MiB decoder reply and 64-level nesting
budget. Exceeding a budget returns no partial success.
Oversized selected captures return an input error identifying `capture_path`
and the byte budget; owned reply/output failures remain output or provider errors.
HAR, SAZ and qlog run in an owned
192 MiB Node old-generation heap with one V8 worker. Mitmproxy decoding applies
HAR runs in an owned
192 MiB Node old-generation heap with one V8 worker. Native decoding applies
Linux limits of 768 MiB address space, 30 seconds CPU and 96 MiB file output;
both commands have a 30-second wall deadline and independently supervised
process cleanup. Owned decoder diagnostics retain at most 1 MiB across stdout
and stderr; the collector drops overflow as it arrives, reports the limit
failure and verifies cleanup. Heap limits alone do not establish aggregate RSS limits.
SAZ and qlog refuse decoding when neither a Node heap limit nor a Windows Job Object bound can be enforced. Existing HAR availability is preserved.
When REA runs on Bun, the HAR/SAZ/qlog decoder runs on Bun, which ignores these V8 heap
When REA runs on Bun, the HAR decoder runs on Bun, which ignores these V8 heap
flags; its limitations and resource failures then omit the heap sizes. On
Windows, the decoder's owned Job Object instead limits its committed memory to
704 MiB, the 192 MiB budget plus a 512 MiB reserve for Bun itself. The
@@ -307,7 +207,7 @@ limitations state that limit, and reaching it returns `resource_constraint`
with `process_memory_limit_bytes`, whatever exit status Bun reports.
Observed decoder memory exhaustion returns `resource_constraint`, with the
selected capture, applicable limits and retained process diagnostics. HAR/SAZ/qlog's
selected capture, applicable limits and retained process diagnostics. HAR's
old-generation heap is fixed; inherited `NODE_OPTIONS` cannot raise it.
Record selection happens after complete decoding and does not reduce that
workload. Use a smaller capture exported by its producer or another decoder
@@ -334,108 +234,3 @@ Command cleanup failures retain the original status and both diagnostic streams;
the decoder's ownership preparation receives the same cancellation signal.
MCP advertises the same strict named input contract used by the application. Historical inspection delegates argument validation to that shared application boundary so accepted explicit-sensitive declarations also cover invalid argument names and other correction details. The SDK receives raw arguments through its Standard Schema interface; malformed inputs still fail before decoder or filesystem effects and return the normal structured REA error. Protocol-envelope validation remains owned by MCP.
## Retained aioquic qlog
Select `format: "qlog"` through `inspect_web_network_capture`, or:
```bash
rea inspect-web-network-capture /absolute/origin.qlog qlog --json
rea inspect-web-network-capture /absolute/origin.qlog qlog --record 95 --record 0 --json
```
The initial profile is **aioquic 1.5.0, JSON qlog 0.3**: one JSON object with
`qlog_format: "JSON"`, `qlog_version: "0.3"`, `traces` containing object events
with `name`, finite numeric `time` and object `data`. JSON-SEQ, JSONL, columnar
array events and other versions are unsupported. Duplicate JSON members,
malformed UTF-8, invalid interpreted QUIC integers and excessive nesting fail
without partial success, including in events outside the selected ordinals.
Well-formed event subsets and missing frame metadata remain inspectable.
Unknown extensions are retained; this is not validation of every qlog schema.
Choosing the format selects the interpretation profile; the file does not
necessarily report or authenticate an aioquic version. The profile's clock
uses Unix-epoch milliseconds, verified in aioquic 1.5.0's `QuicLoggerTrace`
`log_event`/`encode_time`. The `qlog.clock.basis` and Evidence analysis profile
state that assumption explicitly. Numeric lexemes survive independently of
safe JSON-number projections; decimal spelling does not establish physical
clock precision or monotonicity.
Every event has a global ordinal from trace/event source traversal and its
original `/traces/T/events/E` pointer. This order is not a global time sort.
Trace index and the selected artifact identify a connection observation;
reported ODCID is preserved without claiming global uniqueness. Streams are
scoped by trace, stream ID and sent/received direction. Control/QPACK streams
are retained, so counting streams does not count HTTP requests.
`qlog` is a typed facet required exactly for this format. Its scope is
`all-recorded-events-before-selection`: selection changes returned event
records while facts cite the original ordinals across the entire recorded
file. The container retains trace metadata with each events array replaced
by null; there is no single events pointer shared by all traces.
| Fact | Basis and limits |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Original event and loss declaration | Observed endpoint report; `recovery:packet_lost` does not prove actual network loss. Missing packet number/type remains unknown. |
| STREAM ranges and byte totals | Derived per trace and direction from reported offsets and lengths using exact integer arithmetic. `unique_bytes` unions intervals; `frame_length_sum` includes overlaps; `repeated_bytes` is their difference. Overlap alone does not prove retransmission or equal contents. |
| FIN final sizes | Reported offset plus length where FIN is true; multiple conflicting sizes remain visible. A final size does not establish complete coverage or a received body. |
| Incomplete fact records | Ordinals with omitted/redacted interpretable frame metadata; usable fields in other records survive. An empty list does not establish complete logging or capture. |
| HTTP bodies and causality | `body_bytes: "not-reported"`; lengths and headers are metadata, with no reconstructed body, hash, timing causality or live process attribution. |
QUIC integer fields interpreted here accept exact nonnegative JSON integer
values through `2^62 - 1`, including equivalent exponent notation. Offsets plus
lengths must fit that range. Derived sums are decimal strings and are not
rounded to JavaScript numbers. A missing offset is unknown, never defaulted to
zero. Ranges can start above zero or contain gaps. Packet headers, HTTP events,
raw lengths and unknown extensions remain producer evidence rather than being
normalized into invented HAR requests.
The adapter excludes authorization/proxy authorization/cookie/set-cookie
values in known HTTP frame events, reset tokens in transport parameters and
NEW_CONNECTION_ID frames, and NEW_TOKEN frame tokens. Known URL header userinfo
and explicit sensitive values follow the shared exclusions. Ordinary extension
fields and token-looking query text remain retained. Explicit declarations also
cover normalized numeric projections, derived totals and trace pointers; facts
that cannot be safely shown are omitted with incomplete-record coordinates.
No keylog, PCAP, live URL or recorded target is opened by the qlog decoder.
To repeat the real-provider lane with **local caller-supplied evidence** from
the educational aioquic 1.5.0 experiment (one origin trace, known 32,803-byte
stream coverage and one 1,169-byte repeated range in the loss case):
```bash
npm run verify:web:qlog -- /absolute/control/origin.qlog /absolute/loss/origin.qlog /absolute/new-report.json
```
This lane checks built CLI/stdio MCP parity, SDK-converted JSON Schemas,
artifact digests, original event count, selection scope, retained parent lookup,
credential exclusions and the known control/loss facts. The report is created
exclusively and contains no keys or captured credential values. It is a
fixture-specific verification, not a general loss detector. CI uses synthetic
format inputs for malformed cases and limits; those tests do not establish
producer provenance. PCAP parsing and correlation remain outside this stage.
### Focused qlog views
Use MCP `inspect_web_network_capture` with `format: "qlog", detail: "summary"`
for identity, profile, scope and retained-fact counts. Then pass its
`normalized_result.parent_evidence_id` to `inspect_analysis_view` as a
`retained-evidence` source.
```json
{"kind":"qlog","facet":"traces","offset":0,"limit":10}
{"kind":"qlog","facet":"streams","trace_index":0,"offset":0,"limit":10}
{"kind":"qlog","facet":"contributions","trace_index":0,"stream_id":"0","direction":"sent","offset":0,"limit":20}
```
Trace pages omit nested lists and give their counts. Stream pages preserve
exact byte totals but omit contributions, ranges and final-size lists. For
those lists select `contributions`, `ranges` or `final-sizes` with all three
stream selectors. `loss-declarations` and `incomplete-records` need only
`trace_index`. Offsets count rows in that retained facet; defaults are 0 and 64. Missing or ambiguous selectors fail rather than choosing a connection.
These views page already interpreted facts without decoding again or opening
the source, and work after its deletion. Facts still cover all recorded events
before parent record selection. Their exhaustion does not prove logging or
network completeness. Event preview/complete pages remain available through
kind `capture`, with original numeric lexemes and producer ordinals preserved.
+5 -11
View File
@@ -48,14 +48,9 @@ its own descriptor. It does not duplicate script bytes.
- Passive sources are the Debugger-exposed text encoded as UTF-8, with the
verified source digest and source-map declaration retained. Unavailable or
explicitly non-JavaScript sources remain unavailable.
- Scenario sources use observed requests classified as `script`, associated
with one response event and the bytes returned by Playwright's
`Response.body()` API for its response object. URLs never select the response.
Playwright may load the request URL again with credentials when CDP has no
response body, so transaction and event references do not verify that
exported bytes came from the original network transaction. The capture and
export manifest retain this limitation. Binary and empty retained bytes are
written exactly.
- Scenario sources use observed requests classified as `script`, matched to
completed response bytes by transaction and event identity. URLs never select
the response. Binary and empty retained bytes are written exactly.
- Ordinary query-free `.js`, `.mjs`, and `.cjs` URL paths are arranged under a
directory for each origin, preserving their relative module layout when it
is unambiguous.
@@ -67,9 +62,8 @@ its own descriptor. It does not duplicate script bytes.
## Interpretation and limits
Export does not fetch URLs or execute JavaScript. Retained Debugger sources and
response bytes do not establish execution or a complete website. Scenario
response bytes preserve Playwright's body API result; see the source-body
identity limitation above. Declared
response bytes do not establish execution or a complete website. Response bytes
are browser-decoded bytes; they do not represent transfer encoding. Declared
redaction is preserved and can change JavaScript syntax; passive captures do
not report a byte-redaction flag, so that value remains unknown.
+2 -4
View File
@@ -21,10 +21,8 @@ additional permission flag or degraded mode is required.
- the 25 read-only Ghidra inventory, memory, and function-analysis operations.
Loaded memory reads and file offsets preserve Ghidra's observed source mappings.
PE load-image inspection returns an explicit unsupported attestation status.
Independent verification covers admitted DOS MZ, explicit COM, and explicit
[raw-binary imports](raw-binary.md) on their supported hosts. This does not
extend Windows P0 admission beyond native PE. For x64 PE
PE load-image inspection returns an explicit unsupported attestation status;
independent load-image verification currently supports DOS MZ only. For x64 PE
NativeAOT RTR 9.1, the read-only snapshot parser can report metadata through
`inspect_native_load_image` and `inspect_native_data_type` without a JAR or
database mutation. A real Windows-host NativeAOT Ghidra run is still required
-597
View File
@@ -1,597 +0,0 @@
# Analysis efficiency measurements
Tracks the experiments for [#2016](https://github.com/morluto/rea/issues/2016).
The production CLI/MCP contracts and defaults remain the compatibility baseline.
Downloaded artifacts, runtime copies, exported Evidence, transcripts and detailed
JSON measurements belong outside the checkout. This document keeps the measured
findings, verification scope and revision references; the scripts and `corpus.json`
keep the reproduction inputs. Generated `results/` is ignored.
Follow-up: [latest-main capability audit](latest-main-audit.md) records the
Flutter, SQLite, TShark and sigrok priorities and the first shipped Dart AOT
baseline, preserving existing controls before introducing another selector.
Follow-up: [Dart AOT summary and retained string pools](flutter-aot-summary.md)
records real LocalSend delivery pairs and old Evidence continuation, preserving
ABI selection, snapshot identity, original lower bounds and partial coverage.
Follow-up: [SQLite existing-control measurements](sqlite-existing-controls.md)
tests QGIS's shipped GeoPackage through the existing column selection, preserving
full selected-table schema and typed cells before considering another API.
Follow-up: [native PE/DOS entry views and real model verification](native-entry-views.md)
records the post-merge native continuation, including a small-function case where
four selected replies cost more bytes than the complete dossier.
Follow-up: [EVM descriptor and real-template controls](evm-descriptor.md) extends
the offline corpus with digest-pinned Uniswap runtime templates and an independent
published ABI selector oracle, preserving unknown deployment/immutable metadata.
Follow-up: [EVM interface summary delivery](evm-interface-summary.md) records
the opt-in retained view, old-client/Evidence migration checks and repeated SDK
and real-model pairs, including mixed token/time results and strict-answer limits.
Follow-up: [task-scoped preset lifecycle verification](preset-lifecycle.md) checks
real Ghidra profile/snapshot boundaries, startup cancellation and retained cleanup
retry while preserving defaults and distinguishing verification from performance.
Follow-up: [EVM descriptor lifecycle acceptance](evm-lifecycle.md) verifies actual
worker replies, late SDK cancellation, permission-induced cleanup failures,
healthy WASM peers and old CLI parity with explicit runtime and platform scope.
Follow-up: [managed artifact delivery and retained views](managed-artifact-summary.md)
records two shipped assembly checks, previous-runtime portable Evidence, and four
actual Codex trials. Selected replies shrink substantially; observed model input
tokens increase and latency is mixed, so model-token savings are not claimed.
Follow-up: [model tool context and per-response usage](model-context.md) separates
raw MCP replies from observed client execution/discovery and usage. Optional
trial capture retains tool/usage items while excluding account and ambient state;
existing ephemeral trials keep their default behavior.
Follow-up: [Android package delivery and retained manifest](android-package-summary.md)
records real NewPipe SDK pairs, unchanged old requests/Evidence, exact retained
text, and actual Codex outcomes including client errors and a failed discovery.
Reply bytes fall; model-token/time gains are not established.
Follow-up: [resource counters at payload completion](resource-counters.md) adds
optional owned counter observations while preserving unknown whole-scope final
counters, default receipt shape and the unchanged CPU/memory safeguards.
The 12 detailed checkpoint receipts were archived byte-for-byte before removal
from the final PR tree. The archive `review-receipts-00d51e0fc-20261012` is in the
private experiment lab outside the checkout; its `archive-index.json` records
source revision, filenames, sizes and SHA-256.
Raw producer replies, model transcripts and exported Evidence remain in the same
private lab. These local files are not required to build or use REA. Historical
checkpoint commits retain their original receipts; no history was rewritten.
## Optimization priorities and gradual migration
Agent token consumption and end-to-end task time are the primary objectives.
Memory and CPU consumption are also measured and controlled. Correctness,
Evidence provenance, caller choices and existing-user compatibility are
acceptance conditions for every optimization.
- Tokens: minimize unnecessary model-visible data while returning the requested
facts and useful provenance inline. Count discovery, repeated calls, errors,
retries and follow-up turns; report total/cached/uncached input and output
separately. Compact JSON bytes are a delivery measurement, not a token count.
- Time: measure completion of the same analyst question, including startup,
provider work, transport, client processing and model corrections. Separate
measured stages and cold/warm state; use repeated comparable trials before
generalizing an observed latency improvement.
- Memory: record aggregate process-tree peaks and limit/cleanup events, account
for retained Evidence and representation expansion, and keep host safeguards.
- CPU: record aggregate CPU time for the completed task. A one-CPU quota is an
experiment control; it does not itself establish reduced CPU consumption.
Migrate domain by domain with focused real-artifact checks and relevant shared
contract checks. The native follow-up verifies selected PE and DOS MZ entry facts;
DOS COM and complete native application behavior remain unverified. The domain
matrix is a growing roadmap. A passed lane does not imply all
advertised platforms/providers have passed. Newly discovered REA bugs remain
in the separate local handoff document for later team repair.
Old clients using existing CLI/MCP requests against the candidate retain the
complete default path. New summary/view options require explicit selection.
Actual old Evidence import/view/export checks preserve original authenticated
records and identities. These checks establish the recorded baseline/workflow
scope, not every historical release or third-party client. A new client targeting
an older server must discover the actual schema and use a supported equivalent
where available; this study does not implement a universal automatic fallback.
The catalog intentionally gains more precise/additive schemas, so its bytes and
digest are not frozen: measured runtime `259e99dd9` has about 2.6% larger complete
catalog JSON than the frozen baseline. The separate post-integration receipt
records the newer runtime, including upstream changes. Optional views can reduce
model-visible result data; old complete requests do not silently switch delivery
or acquire that reduction automatically.
## Reproduce a measurement
Use the repository's pinned Node/npm and locked dependencies. Build each selected
revision, then copy its `dist/`, `bridge/`, `scripts/`, `skills/`, `package.json`
and `package-lock.json` to a separate runtime directory before editing production
sources. That copy needs the matching locked dependencies. The initial frozen
baseline is `42b0ed126df7d5b908ac369715378d5e519051b7`; this study does not
silently substitute a newer `main` or the previous Code Mode experiment.
The public artifacts and acquisition digests are in `corpus.json`. Supply their
actual local paths and an optional JSON object of explicit provider environment
settings. Do not add credentials to that file. Provider settings are inherited
by the child, but the report persists only the selected settings' digest. Runs
reject undeclared inherited REA/Hopper and Ghidra/Java configuration keys before
starting a measured server or creating a model profile; include those settings
explicitly in `--providers`. Both drivers use `provider-environment.json` and
record its digest. The system/runtime environment still needs comparable
controlled conditions; its contents are not serialized. Both drivers also
fingerprint the effective provider `PATH` without recording its value, and
the SDK comparator rejects different or unrecorded search paths. This detects different
search configuration, not replacement of executable bytes at the same path.
Historical receipts
predate this guard, so their selected-settings digest alone does not certify
that no undeclared provider setting was inherited.
```sh
export NODE_OPTIONS=--max-old-space-size=512
export UV_THREADPOOL_SIZE=1
export GOMAXPROCS=1
export GOMEMLIMIT=2GiB
python3 experiments/analysis-efficiency/resource-run.py -- \
node experiments/analysis-efficiency/measure.mjs \
--runtime-root /absolute/frozen-runtime \
--revision 42b0ed126df7d5b908ac369715378d5e519051b7 \
--artifact obsidian.asar --path /absolute/obsidian-1.14.4.asar \
--providers /absolute/selected-providers.json \
--output /absolute/new-measurement-directory
```
The wrapper requires Linux cgroup v2 and a working user systemd manager. It owns
a unique transient scope, restricts the whole process tree to one CPU, caps
memory at 4 GiB with no swap and 192 tasks, and samples memory/tasks/CPU every
100 ms. It stops its own scope above 3 GiB or below 4 GiB host available memory;
startup requires 8 GiB available. Cleanup failures retain the owned scope's
identity. Run heavy builds, providers and model trials serially. Sampled peaks
can miss short spikes; cgroup limit events are separately reported.
An actual Codex + Chromium trial exceeded the initial 192-task allowance and
was stopped automatically below 1 GiB sampled memory, with no OOM. The isolated
browser model retry uses `resource-run.py --task-ceiling 256 -- COMMAND...` to
account for both process trees; memory, swap and CPU controls are unchanged.
Keep the original aborted run and cleanup receipt. This is experiment capacity,
not a REA defect or a successful browser analysis.
## What the numbers mean
`summary.json` records the selected artifact's before/after SHA-256, runtime
file-table digest, dispatcher and lockfile digests, runner source digest,
Node/SDK versions, catalog sizes, caller arguments and producer Evidence IDs.
`runtime-files.json` identifies the exact compiled files measured. Actual
provider settings and runtime files must stay fixed during a comparison.
Every tool call measures three intervals at the public SDK Transport boundary:
- Client work before `send`, including first-use schema preparation.
- Transport/server roundtrip, including framing, I/O, server work and client
JSON parsing. This interval is **not** a Ghidra-only or provider-only timer.
- Client work after the parsed response reaches `onmessage`.
The SDK call's total excludes the runner's subsequent encoding and disk writes.
Result byte counts measure compact JSON of the parsed client result, not raw
wire bytes or tokens. Progress notifications retain their actual arrival times;
they do not imply more precise internal engine timings than the producer emits.
Scope CPU time and aggregate process-tree memory come from the wrapper's final
JSON line. Fresh processes have cold application caches; host page caches are
not globally flushed.
`--delivery summary` is an explicit candidate workflow, initially for artifact
inventory. It must be supported by the selected server's advertised schema.
The default `complete` runs the existing calls unchanged. Compare the same
analyst facts and complete source Evidence before crediting a smaller response.
Projection can reduce delivery bytes without reducing upstream analysis time.
For WASM, the runner validates a summary request against the actual advertised
2020-12 input schema, including SDK-generated references. Supporting servers
return the first-call summary; older servers retain their complete path and use
summary/export views after an observed transport constraint. Original errors
remain in the receipts, and the complete source Evidence ID is a compared fact.
`--javascript-question selected` analyzes only the exact Obsidian sources
`package.json` and `main.js`, keeps inventory identity, and reads each observed
`main.js` module by its exact node ID. Package metadata is not a module selector.
Compare paired runs with the same runner source and provider settings:
```sh
node experiments/analysis-efficiency/compare.mjs \
--left /absolute/complete-run --right /absolute/summary-run \
--output /absolute/new-comparison.json
```
This checks all selected analyst facts, including inventory source IDs, exact
path records, manifest, counts, completeness, contradictions, coverage,
unexplored branches and limitations. It excludes only delivery observation IDs
and the named recovery-path description. Different settings, changed facts or
failed workflows make the comparator fail. Binwalk's per-invocation region UUIDs
are separately preserved with both original values and JSON paths; only those
opaque lookup values are excluded from physical-region fact equality. Original
producer replies are never rewritten. Selected JavaScript comparisons likewise
preserve both values of the two named parent-heap-dependent byte budgets before
excluding their values from fact equality; fixed limits and coverage rows remain
checked. Counts include extra view calls and
observed tool errors. Use repeated runs with alternating order before claiming
a distribution or a speedup; one pair is only one observation.
For a completed WASM result exceeding the MCP response budget, the runner keeps
the original error, exports retained Evidence through the public tool, and
authenticates the exact reported record using the selected runtime's parser.
The report names this recovery; it does not relabel the oversized inline reply
as successful delivery.
## Initial observations and exclusions
The frozen baseline has 2,326,609 bytes of complete catalog JSON, of which
494,207 bytes describe names, descriptions and input schemas. One Obsidian
trial spent about 21.9 s before the first request was sent, then about 0.77 s
in that request's transport/server roundtrip. Other cold runs differed
substantially. These single observations identify a measurement boundary;
they do not establish a speedup or a distribution.
The initial matrix exercised shipped Obsidian, NewPipe, ShareX, OpenWrt, SQLite
WASM and jq artifacts. SQLite produced a complete result larger than the
transport frame and requires an explicit recovery run. A first jq attempt hit
the SDK's default 60 s timeout because the experimental runner used a superseded
three-argument call signature. SDK 2.3.1 accepts request options as argument two;
the corrected jq run completed real Ghidra analysis in about 265 s. That earlier
driver timeout is excluded from REA regression claims. Provisional runs with
different runner source digests are not one paired statistical cohort.
No cross-session engine database cache, default analyzer changes, external
plugin loading, or broad plugin SDK is enabled by this experiment.
## Obsidian delivery checkpoint
The two recorded pairs compare frozen baseline
`42b0ed12` and candidate `f1106181` in complete → summary and summary → complete
order using the same runner source, bytes and provider settings. Both preserve
every selected fact and the atomic inventory Evidence ID.
| Measurement | Complete | Summary + exact path view |
| --------------------------------------------------- | --------------: | ------------------------: |
| Tool-result compact JSON, including lifecycle calls | 937,404 bytes | 16,322 bytes |
| Tool calls per question | 3 | 4 |
| Complete catalog compact JSON | 2,326,609 bytes | 2,370,505 bytes |
| Workflow elapsed, first pair | 11.04 s | 10.23 s |
| Workflow elapsed, second pair | 10.57 s | 10.18 s |
Reply JSON falls by about 98.3%; catalog JSON grows by about 1.9%. The two elapsed
observations do not establish a statistical speedup. Inventory coverage and
upstream byte acquisition are unchanged. The candidate remains opt-in; existing
requests continue to deliver the complete inspection. Each run verifies the
selected artifact's before/after digest and reports no observed OOM or task
limit events. Source typing and projection improve selected delivery without
introducing an engine database cache or an external plugin protocol.
## Task-scoped analyzer experiment
The recorded jq pair explicitly disables
`Decompiler Switch Analysis` through the existing `REA_GHIDRA_DISABLED_ANALYZERS`
setting and compares it with the unchanged Ghidra default. Both use the same
frozen runtime and real jq bytes, one CPU, a fresh ephemeral database and the
same entry/main question. Completed main dossiers exceed the MCP frame in both
runs; existing retained native views recover the selected facts, preserving the
observed transport errors in the reports.
One disabled/default pair takes 174.77/276.23 seconds. Entry and main pseudocode,
main strings and its block count agree. However, callee `0x40daa0` has 604
recovered body bytes in eight ranges by default, and 164 bytes in four ranges
with the same 646-byte span after disabling switch analysis. Equal top-level
counts do not establish call-graph equivalence. **Keep the production default.**
Use the existing control only for a caller-selected task whose required facts
have been checked; no general fast preset is introduced. A separate real
coreutils/Ghidra probe rejects a nonexistent analyzer before bridge readiness,
preserves the named failure and closes the session. Source bytes remain unchanged.
`--schemas selected` is a separate SDK 2.3.1 client experiment. It passes the exact
live named `tools/list` definition to the SDK's public `callTool` option, retaining
output validation. It does not change REA or the default runner mode. Selected
definitions compile per call rather than preparing the entire cached catalog;
report this client effect separately from engine analysis or model behavior.
## Real Codex CLI trials
`agent-trial.py` accepts an explicit frozen runtime and revision, the same
question templates in `questions/`, and optional explicit provider settings.
It fingerprints the actual runtime, runs pinned local Codex CLI with a private
temporary profile, copies only the authentication file with mode 0600, disables
shell/web/multi-agent tools, and removes copied profile state afterward. Raw
events and answers remain outside Git. A zero exit code is not a factual grade.
Review the original tool calls, failed requests, result limitations and answer.
The optional `--enabled-tools FILE` supplies a list of exact names to the
temporary Codex MCP configuration's `enabled_tools`, as described in the
[official MCP configuration](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
It leaves the REA catalog and other clients intact. Initial Obsidian trials
showed parameter-correction attempts and different delivery choices even with
the same question; filtering alone has not established a cost or quality win.
Requested model aliases are recorded without inventing a resolved model identity.
The browser question uses `--authority browser` to permit only its explicitly
selected public scenario in a fresh, owned headless profile. Browser observations
and cleanup are graded separately from static artifact analysis.
## Real artifact compatibility checkpoint
Six frozen baseline/pilot pairs exercise
Obsidian, NewPipe, ShareX, OpenWrt, SQLite WASM and published historical WETH code
through public MCP tools. All selected facts agree under the stated comparison
rules. Obsidian complete delivery and atomic inventory Evidence identity remain
unchanged. ShareX native-boundary claims remain scoped to the selected DLL;
NewPipe retains a null DEX descriptor rather than inventing one.
SQLite's complete 15,382,128-code-unit WAT exceeds the MCP response budget in both
revisions. The control recovers complete Evidence through file export; the pilot
reads summary and four exact export forms inline, without running WABT again.
Inline byte totals exclude file exports, so they do not establish a size win.
OpenWrt comparison preserves both sets of upstream-generated region UUIDs before
comparing offsets, extents, signatures, coverage and limitations. WETH is a
published historical example; a live RPC request returned HTTP 403, so this is
not live-chain verification. Every pair records unchanged target bytes and zero
observed OOM/task-limit events. The Linux x64 results do not establish behavior
for IDA, Hopper, macOS, Windows or Harmony.
## Same-question model and selected-source follow-up
Two actual SQLite model trials preserve all
12 requested facts. The question, developer instruction, provider settings and
tool allowlist hashes match. A description-only follow-up supplies the exact
summary kind and its fields. Calls change from 42 to 3, workflow time from
292.64 to 63.79 seconds, and reported input tokens from 304,698 to 74,387. The
follow-up reads no unnecessary WAT pages. Both keep the original completed
analysis's transport error and authenticate the retained source/view identities.
This is one stochastic model pair, not a statistical or general causal claim.
The selected JavaScript pair preserves
all 24 observed `main.js` module identities and the exact two-source selection.
The strict comparison initially differs on parent budget values derived from
observed heap availability; both values and paths remain recorded separately.
Other coverage facts, per-family rows, fixed worker limits, omitted/unknown
counts, statistics and Electron observations agree. Coverage remains partial,
with 36 unselected relevant files and 384 semantic unknowns. These static facts
do not establish runtime behavior. The comparator does not rewrite Evidence.
Ten real CLI trial reviews cover native,
managed, Android, firmware, Electron/JavaScript, WASM, EVM and browser tasks.
The selected JavaScript model preserves core facts and partial coverage but
omits full budget/family provenance. The browser producer captures complete
DOM/accessibility/URL evidence and terminates its owned process; direct model
answers lose two accessibility metadata fields to client context clipping and
report them unknown. A requested under-development Codex code-mode configuration
still produces a direct MCP call in the actual trace, so no executor/composition
win is credited. Profile cleanup, original errors, actual calls, usage, facts and
scope limits remain independently reviewed. Enabling a configuration flag does
not prove that a capability was used.
Discovered REA defects are recorded separately for team repair at the user's
request. This follow-up performs no additional REA bug fixes.
## Nonempty managed boundaries and final verification
A second shipped managed library checks
11 ModuleRefs, 147 PInvoke declarations and 225 native implementations from
ShareX HelpersLib 19.0.2. All complete normalized artifact and native-boundary
fields match between baseline and pilot, including source Evidence identities.
This covers nonempty declarations beyond the main ShareX DLL's empty import
tables. It does not verify native exports, execute the assembly or resolve CLR
dependencies. The curated receipt keeps identities, coverage, all ModuleRefs,
the first three PInvoke records and digests of the complete boundary payloads.
Full producer tables and comparison inputs stay in the private lab outputs.
The earlier verification includes 42 real
WABT CLI/MCP cases and the complete real SQLite CLI JSON: the unchanged default
returns the same original source Evidence ID, normalized result and raw result
as the baseline exported MCP record. Source bytes are unchanged. The seven-file
contract/composition run passes 51/52 assertions and hits the existing 20-second
presentation-test deadline while sharing one CPU. That same unmodified assertion
passes alone in 10.835 seconds. The original combined failure and isolated pass
remain recorded; no test deadline or REA bug was patched. Build, type/lint/module
checks and generated-document checks pass. No full `check:pr` or unverified
provider/platform coverage is implied.
## Actual old Evidence migration
The migration experiment imports the original
baseline SQLite Evidence bundle into the pilot runtime, reads a typed summary
and four export forms, and exports the retained bundle again. The complete old
WASM record is deeply equal after import/export, with its original authenticated
Evidence ID. The original baseline Obsidian complete inspection also works as
inline input to the new inventory summary, retaining the old parent and atomic
inventory identities and manifest. Original input files remain byte-identical.
The runtime explicitly selects an absent WABT directory and requests no producer
operation. These views consume existing Evidence without another provider run;
this is portable-result reuse through existing import/export, not an engine
database cache. The five-call workflow completes in 5.458 seconds with a sampled
aggregate peak of 700,542,976 bytes and no observed limit or OOM events.
To repeat it with genuine old public outputs:
```sh
python3 experiments/analysis-efficiency/resource-run.py -- \
node experiments/analysis-efficiency/verify-migration.mjs \
--runtime-root /absolute/frozen-pilot-runtime \
--revision 259e99dd906290189217cf0fb1a19769bcf87101 \
--bundle /absolute/baseline-exported-evidence.json \
--inspection-reply /absolute/baseline-complete-inspection-reply.json \
--output /absolute/new-migration-directory
```
## PR integration verification
The separate post-integration verification pins runtime
`0eb42a1eb8ab17aed04240174cb77612e733a1d8`, integrated with main
`c22111eca2c4bc84a084f12711f405b3e7422a40`. Conflict resolution preserves main's
HAR API-surface views, portable capture admission, exact layout/JavaScript
summary carriers and existing CLI tests alongside inventory/WASM views.
Earlier real-model observations keep their original runtime fingerprints.
Build, the complete `check` static gate and generated documentation checks pass.
Twelve focused files pass 123 assertions, including the presentation test run
separately with its original deadline. Actual package creation, private-prefix
installation and 42 real WABT CLI/MCP cases pass. No package is published.
The complete generic package verifier and full local `check:pr` were not run.
Genuine old SQLite/Obsidian Evidence migration passes again with WABT unavailable.
A fresh public SDK cohort preserves the original Obsidian default result size
(937,404 compact JSON bytes), atomic inventory identity and every selected fact;
explicit summary plus exact paths still returns 16,322 bytes. Complete catalog
JSON is 2,359,082 bytes versus the original baseline's 2,326,609 (about 1.4%
larger). That difference includes intervening main changes and does not isolate
this PR's catalog contribution. One cohort is not a latency distribution.
Recorded integration scopes have no OOM/OOM-kill or hard-limit abort. The full
source-check scope reports three `memory.high` events near its 3 GiB soft
threshold. The subsequent cold pre-push type/lint scope reports 37 such events,
with 3,221,155,840 sampled peak bytes and no hard-limit/OOM event. Heavy lanes stay
serial with the existing CPU, memory and no-swap controls. No further REA bug repairs
are included; separate local findings remain for team follow-up.
## CI attribution
Review of the actual main and PR job logs separates two PR-related
description/test mismatches from pre-existing main failures. The complete-graph
wording check now accepts capitalization changes; the existing effects audit
records why returning WASM execution/network metadata is not foreign execution.
Those two files pass 11 focused assertions without production changes. Main's
own CI already fails the same live prompt-completion assertion and Darwin
packaged-completion checks; the affected implementation and fixture files are
byte-identical here. Those failures remain unchanged for team review at the
maintainer's request. CI failures are not all infrastructure faults, and the
failed CI gate is not presented as passed.
| Failure | Main `c22111eca` | Reviewed PR `8d6f7eb1c` |
| ---------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| Empty prompt completion after open | [main shard](https://github.com/morluto/rea/actions/runs/38224038323/job/114727940506) | [PR shard](https://github.com/morluto/rea/actions/runs/38228724531/job/114742955092) |
| Packaged prompt completion, Darwin arm64 | [main package](https://github.com/morluto/rea/actions/runs/38224038323/job/114728030045) | [PR package](https://github.com/morluto/rea/actions/runs/38228724531/job/114743092314) |
| Packaged prompt completion, Darwin x64 | [main package](https://github.com/morluto/rea/actions/runs/38224038323/job/114728029923) | [PR package](https://github.com/morluto/rea/actions/runs/38228724531/job/114743092079) |
`src/server/promptCompletion.ts`, `src/application/binary/BinarySession.ts`,
`tests/boundary/mcp/promptCompletion.test.ts` and
`scripts/verify-package-prompts.mjs` are byte-identical to that main revision.
Main commit `07b36c148946f46b99a4ce04e55726e97d0ee03a` introduces ready-provider-only
completion; the failing fixtures expect populated completion immediately after
opening. Whether those expectations or the readiness behavior should change is
left for team review. Commit `00d51e0fcd1d1bba60bf56281725e82d525a27ae`
synchronizes only the two PR-related description checks.
## Frozen runtime references
### Review follow-up
Two substantive bot findings were reproduced and addressed before merge. Atomic
inventory projections now reuse the owning subject/digest/format validation.
Actual public SDK calls with original Obsidian data demonstrated the old
acceptance of null subjects and inconsistent formats; the corrected runtime
rejects both with `invalid_request`. Six boundary assertions also cover missing
subject, wrong format and wrong digest across summary and node views.
The related three-file run passes 37 assertions, and full static/docs gates
pass. Genuine baseline SQLite/Obsidian import/view/export still preserves whole
original records and source/view identities with WABT unavailable. A new real
Obsidian summary workflow preserves every selected fact, atomic source identity
and 16,322 delivered JSON bytes; catalog bytes remain 2,359,082.
Both experimental drivers reject undeclared inherited provider controls before
server/profile creation and log no values. Explicit settings still override
the corresponding inherited values. This prevents claiming equal declared
settings while silently inheriting a different analysis option; it does not
certify every aspect of the inherited system/runtime environment. These are
research-driver controls, with no production configuration changes.
The source/static scope records 98 `memory.high` events, no hard limit/OOM event,
and a sampled peak of 3,221,209,088 bytes. The real migration/Obsidian scope peaks
at 677,367,808 bytes with no limit/OOM events. All raw receipts remain outside Git.
A later WASM finding was also reproduced: portable sources with absent subject
or a different subject path could report another artifact path. The producer and
view now share an exact path/digest identity rule. Actual WABT inspection of the
published VS Code Tree-sitter INI grammar (0.3.1, 4,716 bytes, SHA-256
`1e8cdf3027209100fa54a43d0faed69721ae1116428164c8ad6dcc496a9aa6af`)
supplied the unchanged report for public SDK before/after checks. The old runtime
accepts both inconsistencies; the corrected runtime rejects both with
`invalid_request` and WABT unavailable. Its 26 focused assertions and type/lint
checks pass, and genuine old records still round-trip unchanged. The verification
scope peaks at 3,204,509,696 bytes with no observed limit/OOM event. The initial
CSS producer exceeded the MCP reply budget as expected; that failed probe is
preserved separately and is not credited as a completed identity reproduction.
These revisions identify different experiment stages; model measurements were
not rerun or relabeled as post-integration measurements.
| Stage | Source revision |
| ---------------------------------------------- | ------------------------------------------ |
| Original baseline | `42b0ed126df7d5b908ac369715378d5e519051b7` |
| Inventory delivery pairs | `f110618184e99f89fa776bc5e59703a61baa7c57` |
| Initial WASM pilot | `0002caa07ffd7319672a21ce901dbfbc55e21aac` |
| Exact WASM summary guidance | `259e99dd906290189217cf0fb1a19769bcf87101` |
| Main-integrated package/migration verification | `0eb42a1eb8ab17aed04240174cb77612e733a1d8` |
The baseline runtime file-table SHA-256 is
`3a1765a6fec0031db0b288112d4db9bc0dd503c9c3aa0946f07ce57f7673ab4b`;
the integrated runtime file-table SHA-256 is
`e99d3bdc851822b77e7d5bfaa9b60c57e7b99bd66e27a739bdea2e9300560d5f`.
The integrated lockfile SHA-256 is
`0a55042141899a442a39dce3d49755c65a861f86d1930bd4f9c6d89cd53f5eba`.
Actual old migration inputs have SHA-256
`e1ff3d28801436bcc11693f79cc847a4f31234f49d88449f9e0d77215c3765fc`
(SQLite bundle) and
`7cecd07012bb79f3afad2ea9e70357e056e9eab48c1aa13bbbd310cdcb43eb9f`
(Obsidian complete inspection reply). The source WASM identity
`ev_16b9f6e0fcefcab9603f14fd5e63ea00c4749accd94fef4a4e9fbb260d2e0140`
and atomic inventory identity
`ev_22c17e52489f3ec0e7298a62da37bd985dbbec202d7208a0bb1c20d863790aed`
remain unchanged after the recorded import/view/export workflows.
### Complete carrier identity and provider search configuration
The outer `inspect_artifact` carrier now uses the same owning subject/digest/format
validator as its atomic inventory. Invalid imported/inline carriers are rejected
before selected-view construction; the generic historical Evidence parser and
valid complete records are unchanged. Six additional boundary assertions cover
missing subject, wrong format and wrong digest across summary/node projections.
The negative checks use the small keyed-archive workflow so the original large
ZIP retention/capacity workflow keeps its existing deadline and distinct coverage.
An initial large-workflow placement timed out and is retained as a failed attempt.
The three public MCP workflows, build, fast static gate and generated docs pass.
The final static/test scope observed one soft `memory.high` event, with no hard
memory, task-limit, OOM or OOM-kill event; it is not a performance trial.
Both research drivers fingerprint the effective provider `PATH`, including an
explicit caller override, without serializing its value or the ambient environment.
The SDK comparator rejects absent or unequal search-path fingerprints. This
records search configuration, not executable replacement at an unchanged path;
provider/runtime identities and controlled host conditions still matter.
Actual public SDK calls using the original shipped Obsidian inspection reproduce
accepted null/wrong-format outer subjects on frozen `2ef0467bb` and `invalid_request`
on the corrected compiled runtime. Two fresh Obsidian replays with different
inherited search paths preserve selected facts and source identities, but the
comparator rejects matching settings with only `provider_search_path_sha256`
different. The original records and failed/accepted replies stay in private lab
receipts; no environment value is copied into them.
### Resource-counter closeout qualification
The experimental wrapper now attempts a final cgroup event read before waiting
or cleanup. Disappeared/incomplete counters or still-owned descendants make
`resource_counters_verified` false; last observations remain available separately.
The model grader treats missing final counters as unverified, never as zero,
and any recorded soft/hard/task-limit event prevents an unrestricted resource
pass. Lightweight parser probes cover missing/incomplete and nonzero counters;
an actual short command confirms disappearance is reported as unknown. Regrading
one already-correct SQLite model answer preserves its facts but rejects the old
receipt's absent final resource counters. Earlier receipts record last-sampled
observations, not verified final counters. Their bytes, facts and token reports
remain original observations; resource-qualified performance conclusions need
this additional closeout evidence. No analyzer/build/schema/package behavior is
changed, so unrelated verification is not repeated for this research-driver fix.
The next bounded WASM delivery cohort is documented in [first-call summary measurements](wasm-first-call.md).
@@ -1,306 +0,0 @@
"""Evaluate one real Codex CLI task with an isolated REA MCP registration."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import shutil
import signal
import subprocess
import tempfile
import time
from codex_context import capture_tool_context
def file_digest(path):
digest = hashlib.sha256()
with path.open('rb') as data:
for chunk in iter(lambda: data.read(1024 * 1024), b''):
digest.update(chunk)
return digest.hexdigest()
def runtime_fingerprint(root):
files = []
for name in ['dist', 'bridge']:
for path in sorted((root / name).rglob('*')):
if path.is_symlink():
raise ValueError('Runtime fingerprint does not follow symlinks')
if path.is_file():
files.append({'path': path.relative_to(root).as_posix(), 'sha256': file_digest(path)})
files.sort(key=lambda row: row['path'])
text = json.dumps(files, separators=(',', ':'), ensure_ascii=False)
return files, hashlib.sha256(text.encode()).hexdigest()
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--mode', choices=['direct', 'client-code'], default='direct')
parser.add_argument('--runtime-root', type=Path, required=True)
parser.add_argument('--revision', required=True)
parser.add_argument('--prompt', type=Path, required=True)
parser.add_argument('--artifact-path', help='Replace {{artifact_path}} in a question template')
parser.add_argument('--output', type=Path, required=True)
parser.add_argument('--model', default='gpt-5.6-terra')
parser.add_argument('--reasoning', default='high')
parser.add_argument('--timeout', type=int, default=900)
parser.add_argument('--codex', default='/usr/bin/codex')
parser.add_argument('--providers', type=Path)
parser.add_argument('--enabled-tools', type=Path)
parser.add_argument('--authority', choices=['static', 'browser'], default='static')
parser.add_argument('--capture-tool-context', action='store_true',
help='Retain owned tool/usage items; excludes account/ambient state')
parser.add_argument('--guide-enabled-tools', action='store_true',
help='Opt-in exact-name discovery guidance for selected REA tools')
args = parser.parse_args()
if args.guide_enabled_tools and args.enabled_tools is None:
parser.error('--guide-enabled-tools requires --enabled-tools')
enabled_tools = None
if args.enabled_tools:
enabled_tools = json.loads(args.enabled_tools.read_text())
if not isinstance(enabled_tools, list) or not all(isinstance(name, str) and name for name in enabled_tools) or len(enabled_tools) != len(set(enabled_tools)):
raise ValueError('enabled-tools must be a unique list of exact tool names')
if args.guide_enabled_tools and not enabled_tools:
parser.error('--guide-enabled-tools requires a nonempty selected tool list')
def terminate(signum, _frame):
# The outer resource scope terminates descendants together. Ensure the
# runner's copied credentials are also removed on a resource abort.
raise SystemExit(128 + signum)
signal.signal(signal.SIGTERM, terminate)
if not args.runtime_root.is_absolute() or not args.output.is_absolute():
raise ValueError('Runtime and output paths must be absolute')
repository = args.runtime_root
driver_repository = Path(__file__).resolve().parents[2]
experiment = Path(__file__).resolve().parent
node = shutil.which('node')
if subprocess.check_output([node, '--version'], text=True).strip() != 'v24.18.0':
raise SystemExit('Use pinned Node 24.18.0 on PATH')
provider_env = {'REA_LOG_LEVEL': 'silent', 'NODE_OPTIONS': '--max-old-space-size=512'}
if args.providers:
declared = json.loads(args.providers.read_text())
if not isinstance(declared, dict) or not all(
isinstance(value, str) for value in declared.values()
):
raise ValueError('--providers must contain an object of explicit string settings')
provider_env.update(declared)
provider_policy_text = (experiment / 'provider-environment.json').read_text()
provider_policy = json.loads(provider_policy_text)
undeclared = sorted(key for key in os.environ if (
any(key.startswith(prefix) for prefix in provider_policy['namespace_prefixes'])
or key in provider_policy['additional_keys']
) and key not in provider_env)
if undeclared:
raise ValueError('Declare inherited provider settings explicitly in --providers: '
+ ', '.join(undeclared) + '. Values are not logged.')
args.output.mkdir(parents=True, exist_ok=False, mode=0o700)
runtime_files, runtime_digest = runtime_fingerprint(repository)
(args.output / 'runtime-files.json').write_text(json.dumps(runtime_files))
profile = Path(tempfile.mkdtemp(prefix='profile-', dir=args.output))
trial_codex_home = profile / 'codex'
account = profile / 'account'
workspace = profile / 'workspace'
for directory in [trial_codex_home, account, workspace]:
directory.mkdir(mode=0o700)
source_auth = Path(os.environ.get('CODEX_HOME', str(Path.home() / '.codex'))) / 'auth.json'
auth = trial_codex_home / 'auth.json'
started = time.monotonic()
timeout = False
exit_code = None
environment = dict(os.environ)
environment.update({
'CODEX_HOME': str(trial_codex_home), 'HOME': str(account),
'XDG_CONFIG_HOME': str(account / '.config'),
'XDG_CACHE_HOME': str(account / '.cache'),
'XDG_DATA_HOME': str(account / '.local/share'),
'NODE_OPTIONS': '--max-old-space-size=512',
})
target_digest = file_digest(Path(args.artifact_path)) if args.artifact_path else None
command_args = [str(repository / 'scripts/rea.mjs'), 'mcp']
instruction = (
'Use the registered REA MCP server for this investigation. Static analysis '
'only: do not execute target code, fetch URLs, launch a GUI, or modify targets. '
'Preserve observations, derivations, inferences, limitations, and real Evidence IDs. '
'An Evidence value has evidence_id, normalized_result and limitations; '
'non-Evidence session values have result. '
'The analyzed target digest is Evidence.subject.digest.sha256. '
'normalized_result.engine.artifact_sha256 identifies the analysis engine '
'artifact and must never be substituted for the target digest. '
'Prefer summary/focused views where appropriate. Do not invent successful facts '
'after a tool error. No other agents. Stop once the requested facts are supported.'
)
if args.authority == 'browser':
instruction = (
'Use the registered REA tools for the explicitly selected public browser scenario. '
'Launching the selected headless browser with a fresh empty profile and observing '
'the supplied public URL is authorized. Keep all actions within that scenario. '
'No injected code, credentials, unrelated targets, shell/file tools or other agents. '
'Preserve real Evidence IDs, observation completeness, failed captures and limitations. '
'Do not infer original source or global behavior from one observed session.'
)
if args.mode == 'client-code':
instruction += (
' Use the client JavaScript executor to compose registered MCP calls when '
'possible and select the requested normalized_result fields before returning '
'intermediate output to model context. Keep real Evidence IDs and limitations.'
)
if args.guide_enabled_tools:
instruction += (
' Configured REA tool function names for this trial: '
+ json.dumps(['mcp__rea__' + name for name in enabled_tools])
+ '. For discovery select only these exact names from ALL_TOOLS and '
'return only their metadata. Preserve the original analyst question, '
'dependency order and source Evidence.'
)
quote = json.dumps
config = '\n'.join([
'approval_policy = "never"', 'sandbox_mode = "read-only"',
'web_search = "disabled"', 'model = ' + quote(args.model),
'model_reasoning_effort = ' + quote(args.reasoning),
'developer_instructions = ' + quote(instruction),
'[features]', 'multi_agent = false', 'shell_snapshot = false',
'shell_tool = false', 'unified_exec = false',
'code_mode = ' + ('true' if args.mode == 'client-code' else 'false'),
'code_mode_only = ' + ('true' if args.mode == 'client-code' else 'false'),
'[history]', 'persistence = "none"',
'[mcp_servers.rea]', 'command = ' + quote(node),
'args = ' + quote(command_args), 'startup_timeout_sec = 60',
'tool_timeout_sec = 600',
*([] if enabled_tools is None else ['enabled_tools = ' + quote(enabled_tools)]),
'[mcp_servers.rea.env]',
*[key + ' = ' + quote(value) for key, value in provider_env.items()],
]) + '\n'
# MCP read-only hints cover normal static tools. Explicitly authorize only
# the session-opening primitive needed by the requested native tasks.
config += '[mcp_servers.rea.tools.open_binary]\napproval_mode = "approve"\n'
for tool in ['analyze_javascript_application', 'inspect_analysis_view',
'inspect_android_package', 'search_android_classes',
'inspect_android_class', 'inspect_android_method',
'inspect_firmware_regions', 'inspect_managed_artifact',
'inspect_sqlite_database',
'inspect_managed_members', 'inspect_managed_native_boundaries',
'inspect_artifact', 'inspect_wasm_artifact',
'inspect_evm_interface', 'get_evidence_bundle', 'export_evidence_bundle',
'capture_browser_scenario',
'resolve_containing_procedure', 'analyze_function', 'close_binary']:
config += '[mcp_servers.rea.tools.' + tool + ']\napproval_mode = "approve"\n'
try:
if source_auth.exists():
shutil.copyfile(source_auth, auth)
auth.chmod(0o600)
(trial_codex_home / 'config.toml').write_text(config)
(trial_codex_home / 'config.toml').chmod(0o600)
prompt = args.prompt.read_text()
template_digest = hashlib.sha256(prompt.encode()).hexdigest()
if '{{artifact_path}}' in prompt:
if not args.artifact_path or not os.path.isabs(args.artifact_path):
raise ValueError('A question template requires an absolute --artifact-path')
prompt = prompt.replace('{{artifact_path}}', args.artifact_path)
elif args.artifact_path:
raise ValueError('--artifact-path requires the literal template marker')
(args.output / 'prompt.txt').write_text(prompt)
(args.output / 'trial-settings.json').write_text(json.dumps({
'mode': args.mode, 'model': args.model, 'reasoning': args.reasoning,
'capture_tool_context': args.capture_tool_context,
'guide_enabled_tools': args.guide_enabled_tools,
'driver_commit': subprocess.check_output(
['git', 'rev-parse', 'HEAD'], cwd=driver_repository, text=True).strip(),
'runtime_revision': args.revision,
'runtime_root': str(repository),
'selected_artifact_path': args.artifact_path,
'selected_artifact_sha256_before': target_digest,
'enabled_tools': enabled_tools,
'authority': args.authority,
'runtime_files_sha256': runtime_digest,
'runtime_dispatcher_sha256': file_digest(repository / 'scripts/rea.mjs'),
'package_lock_sha256': file_digest(repository / 'package-lock.json'),
'experiment_sources_sha256': {
name: hashlib.sha256((experiment / name).read_bytes()).hexdigest()
for name in ['agent-trial.py', 'codex_context.py', 'provider-environment.json']
},
'developer_instructions': instruction,
'developer_instructions_sha256': hashlib.sha256(instruction.encode()).hexdigest(),
'prompt_sha256': hashlib.sha256(prompt.encode()).hexdigest(),
'question_template_sha256': template_digest,
'provider_settings_sha256': hashlib.sha256(
json.dumps(provider_env, sort_keys=True).encode()).hexdigest(),
'provider_search_path_sha256': hashlib.sha256(
provider_env.get('PATH', os.environ.get('PATH', '')).encode()).hexdigest(),
'provider_environment_policy_sha256': hashlib.sha256(
provider_policy_text.encode()).hexdigest(),
'features': {'shell_tool': False, 'unified_exec': False,
'multi_agent': False, 'code_mode': args.mode == 'client-code',
'code_mode_only': args.mode == 'client-code'},
}, indent=2) + '\n')
invocation = [args.codex, '--no-daemon', 'exec', '--strict-config',
*([] if args.capture_tool_context else ['--ephemeral']),
'--skip-git-repo-check', '--ignore-rules', '--json',
'--color', 'never', '-C', str(workspace),
'--output-last-message', str(args.output.resolve() / 'answer.txt'), '-']
with (args.output / 'events.jsonl').open('w') as events, (args.output / 'stderr.log').open('w') as errors:
child = subprocess.Popen(invocation, env=environment, cwd=workspace,
stdin=subprocess.PIPE, stdout=events, stderr=errors, text=True)
child.stdin.write(prompt)
child.stdin.close()
try:
exit_code = child.wait(timeout=args.timeout)
except subprocess.TimeoutExpired:
timeout = True
child.terminate()
try:
exit_code = child.wait(timeout=10)
except subprocess.TimeoutExpired:
child.kill()
exit_code = child.wait()
usage = []
tools = []
event_types = {}
with (args.output / 'events.jsonl').open() as event_file:
for line in event_file:
if not line.strip():
continue
event = json.loads(line)
kind = event.get('type', 'unknown')
event_types[kind] = event_types.get(kind, 0) + 1
if 'usage' in event:
usage.append(event['usage'])
item = event.get('item', {})
if item.get('type') == 'mcp_tool_call' and kind == 'item.completed':
tools.append({
**{k: item.get(k) for k in ['server', 'tool', 'arguments', 'status', 'error']},
'codex_event_result_json_utf8_bytes': len(json.dumps(
item.get('result'), separators=(',', ':'), ensure_ascii=False
).encode()),
})
final_target_digest = file_digest(Path(args.artifact_path)) if args.artifact_path else None
summary = {
'mode': args.mode, 'requested_model': args.model, 'reasoning': args.reasoning,
'runtime_revision': args.revision,
'capture_tool_context_requested': args.capture_tool_context,
'selected_artifact_sha256_before': target_digest,
'selected_artifact_sha256_after': final_target_digest,
'selected_artifact_bytes_unchanged': target_digest == final_target_digest if target_digest else None,
'model_identity_scope': 'requested alias; resolved server-side model identity is not inferred',
'codex_version': subprocess.check_output([args.codex, '--version'], text=True).strip(),
'exit_code': exit_code, 'timeout': timeout,
'wall_seconds': round(time.monotonic() - started, 3),
'usage': usage, 'completed_mcp_calls': tools, 'event_types': event_types,
'factual_correctness': 'not_assessed',
'scope': 'real_cli_trial_requires_transcript_and_fact_review',
}
(args.output / 'summary.json').write_text(json.dumps(summary, indent=2) + '\n')
print(json.dumps(summary))
finally:
try:
if args.capture_tool_context:
capture_tool_context(trial_codex_home, args.output)
finally:
# Capture failure must never prevent copied-credential cleanup.
shutil.rmtree(profile)
(args.output / 'cleanup.json').write_text(json.dumps({'profile_removed': not profile.exists()}) + '\n')
raise SystemExit(124 if timeout else exit_code)
if __name__ == '__main__':
main()
@@ -1,166 +0,0 @@
# Android package summary and exact retained manifest
Continues [#2016](https://github.com/morluto/rea/issues/2016) and
[#2438](https://github.com/morluto/rea/pull/2438). The recurring NewPipe question
asks for APK/package/version identity, all case-sensitive MainActivity matches
and all reported onCreate entries, including explicit null DEX descriptors.
Complete package replies delivered decoded manifest text and duplicate upstream
calls unrelated to those selected facts.
## Compatibility and ownership
MCP `inspect_android_package` accepts explicit `detail: "summary"`; omitted and
`"complete"` requests preserve the complete output and provider request. The
one-shot CLI stays complete. Summary selection happens in the application
workflow, independently of the engine protocol, using the existing retained
analysis-view machinery. No third-party plugin API or persistent analysis cache
is introduced. Servers lacking retention reject summary before provider work.
The complete original Evidence stays under its original ID and session lifetime.
A distinct linked derived view returns all package/SDK/permission declarations,
engine identity, class/resource counts and signature-verification status.
Manifest metadata retains the producer's partial/complete status, nullable
reported byte total, and observed UTF-16 length. Text and duplicate raw calls
remain in the original record, rather than being rewritten under its ID.
Use `inspect_analysis_view` with the parent's ID and
`view: {kind: "android", facet: "manifest", offset: 0, limit: 4096}` to read exact
retained decoded text. Follow `coverage.next_offset`; surrogate boundaries use
the existing text-page implementation. Exhaustion describes the retained text,
not global completeness when the producer says partial. APK signatures and
runtime behavior remain unverified. Engine artifact SHA-256 identifies the JAR;
views require the authenticated APK subject and never substitute the engine
hash for a missing target identity. Older servers require schema discovery and
the original complete request; automatic fallback is not introduced.
## Frozen runtime and real SDK pairs
Source runtime: `28c84e78cf2fbfde4aceed345b773c59eb889f68`; later test-only schema
typing corrections do not relabel these receipts. Compiled dist/bridge file-table
SHA-256: `5332dda13981f043e146b3601ebec1f380d9f698280ca53d75786b638a912e11`.
The frozen old runtime is `8bc1601ca51e417ca472d90ea0367e9418a1a0f2`, digest
`9e7380f537301bf0cfe2926f5619011af848af7c220750e75189498e65d825e1`.
Real NewPipe 0.29.1 bytes, acquisition and digest are pinned in `corpus.json`.
Actual configured JADX headless MCP 0.7.1/Java runs use the same selected
provider settings and search-path digests, one worker and 768 MiB Java heap.
Node is 24.18.0; actual SDK client/server are 2.3.1. Processes and engines are
fresh per trial; host page caches are not flushed. SDK schema mode is selected
in both treatments. Heavy runs are serial, with one CPU, unchanged 3 GiB early
stop/4 GiB hard memory, no swap, and 192 tasks.
All four candidate workflows use three successful public MCP calls. Only the
first package delivery changes. Both pairs pass settings and selected-fact
comparison, including all declarations, manifest status/length, engine identity,
original limitations, matching class rows and onCreate entries. Original replies
and IDs remain separate. A fresh old-runtime complete workflow also passes
comparison against the candidate complete request; both complete package replies
are exactly 119,527 compact client-result JSON bytes. This is scoped compatibility
evidence, not a guarantee for every historical release/client/host.
| Trial | Package reply bytes | SDK workflow seconds | Payload CPU seconds | Kernel peak bytes |
| -------------- | ------------------: | -------------------: | ------------------: | ----------------: |
| sdk-complete-1 | 119,527 | 24.059 | 25.259 | 1,225,076,736 |
| sdk-summary-1 | 8,659 | 23.694 | 24.894 | 1,226,870,784 |
| sdk-summary-2 | 8,659 | 24.407 | 25.611 | 1,228,296,192 |
| sdk-complete-2 | 119,527 | 24.509 | 25.740 | 1,229,844,480 |
Summary replies are 8,659 bytes, about 92.8% smaller; all three replies together
fall from 149,577 to 38,709 bytes. This is a delivery result, not a model-token
or engine-work saving. The SDK timing differences are small. CPU and memory do
not establish a reduction. No provider setting or analysis scope changes.
Transport roundtrip includes server/client work and is not an engine-only timer.
The complete catalog is 2,506,213 compact JSON bytes versus 2,497,635 on the old
runtime: about 0.34% growth, including intervening main changes. Discovery cost
remains visible alongside selected-delivery savings.
## Authentic old Evidence continuation
A real package record from old runtime 8bc160 imports into the candidate and
supports retained summary, exact manifest pages, inline portable summary and
export through actual public SDK tools. The new session explicitly selects an
absent JADX JAR; this workflow performs no package analysis. Eleven successful
calls preserve the original record, original ID, all declarations and all 25,222
manifest UTF-16 units. Manifest UTF-8 SHA-256:
`fee192fe2a6d7892c22cba115184c74c7e2c42ce464e8bb37be6289f2c16881d`.
The exported original record is deeply equal to the imported record.
## Actual Codex task outcomes
Four serial trials run in complete/summary/summary/complete order on the same
frozen candidate. Requested configuration: Codex CLI 0.161.0, `gpt-5.6-terra` high,
three exact selected tool names and the same optional context/discovery capture
settings. The requested alias does not certify the server-resolved model. The
original analyst question is unchanged; equal treatment instructions explicitly
choose package detail and explain the summary carrier. Temporary configuration
points to the frozen modified REA MCP; no global configuration is edited.
| Trial | Input | Cached | Uncached | Output | Seconds | MCP calls | Usage records | Facts |
| ---------------- | ------: | -----: | -------: | -----: | ------: | --------: | ------------: | ----- |
| model-complete-1 | 39,267 | 23,040 | 16,227 | 1,690 | 94.053 | 3 | 3 | Pass |
| model-summary-1 | 128,417 | 93,440 | 34,977 | 3,633 | 150.401 | 8 | 9 | Pass |
| model-summary-2 | 54,437 | 37,120 | 17,317 | 2,185 | 123.677 | 3 | 4 | Pass |
| model-complete-2 | 21,332 | 9,984 | 11,348 | 667 | 20.774 | 0 | 2 | Fail |
Three answers pass the original selected-fact gate against the actual SDK
producer. Each trial preserves APK bytes and removes its isolated profile.
The first summary trial makes five successful calls and three rejected requests:
an invented `case_sensitive` argument, empty class-search input and empty
class-inspection input. It then repeats successful package/search work. These
errors and correction turns remain part of measured task cost; strict existing
schemas correctly reject them. The second summary trial uses the intended three
successful calls, but still does not establish improved total/uncached input or
latency against the factually acceptable first complete control.
The final complete control's first client executor filters `ALL_TOOLS` for the
same three exact names and receives an empty array. It makes zero MCP calls,
reports all requested facts unknown and fails the factual gate. Identical name
filters worked in the other trials. Stderr contains no explanatory error; the
client visibility failure remains unexplained and is not attributed to REA or
summary delivery. Its short duration is not comparable completed work. The
original failed receipt is retained rather than replaced by a successful trial.
These measurements demonstrate no real-model token or speed gain. Smaller raw
MCP envelopes do not establish smaller model context; observed usage also
includes discovery, execution context, corrections and extra responses. Usage
records count captured usage items rather than asserting exact remote request
contents or equating MCP calls with model rounds. The complete default and
opt-in choice remain unchanged; this is useful delivery/retention capability,
not a general performance recommendation.
All model runs have verified payload-completion witnesses with only the observer
remaining and zero memory/task limit events at that phase. Kernel peaks are
602,472,448–1,444,945,920 bytes; the failed no-analysis control is included in that
range and is not evidence of lower analysis memory. Whole-scope final counters
remain unknown and the existing full resource grader stays false. No broader
CPU, memory, OS/provider or model claim is made.
## Resource interpretation
Every SDK run and portable continuation has a verified owned
payload-exited-observer-alive witness, with only the observer remaining and no
memory/task limit events at that phase. Kernel peak and CPU include that opt-in
observer. Whole-scope terminal counters remain unknown; the existing complete
physical resource grader is not changed or called successful. No OOM stress or
resource-limit increase is used.
## Verification and scope
Twenty-seven relevant converted-schema, SDK, domain and existing Android
failure/cancellation/cleanup checks pass. A three-case focused rerun passes after
a test-only schema typing correction. The 1 MiB manifest protocol fixture verifies
original default/full output, reconstruction after source removal, unchanged
exported Evidence and one engine launch. Other cases preserve nulls and partial
status, Unicode boundaries and tagged malformed/missing-identity failures, and
reject unavailable retention or cancelled requests before provider work. These
fixtures verify production boundaries; actual JADX claims use the real NewPipe
runs above. Full supported single-thread compiler and unchanged lint pass under
the same memory safeguards. No other Android OS/device/provider lane is inferred.
Raw SDK/model replies, private profiles and resource receipts stay outside Git.
Reproduce SDK pairs using the existing `measure.mjs` with `--artifact newpipe.apk`,
`--schemas selected`, identical explicit provider configuration and frozen runtime,
and alternating `--delivery complete` / `--delivery summary`. Preserve failed
attempts and run `compare.mjs` on both pair orders. Model findings require their
own identical analyst facts and explicit delivery controls.
@@ -1,117 +0,0 @@
"""Retain owned Codex tool/usage observations without account or ambient state."""
import hashlib
import json
import os
def token_counts(value):
if not isinstance(value, dict):
raise ValueError('Expected a token-count object')
result = {}
for key in ['input_tokens', 'cached_input_tokens', 'cache_write_input_tokens',
'output_tokens', 'reasoning_output_tokens', 'total_tokens']:
if key in value:
count = value[key]
if not isinstance(count, int) or isinstance(count, bool) or count < 0:
raise ValueError('Expected nonnegative integer token counts')
result[key] = count
return result
def selected_event(event):
"""Select observed items; these are not the exact submitted model request."""
if not isinstance(event, dict) or not isinstance(event.get('payload'), dict):
raise ValueError('Expected an event object with an object payload')
if not isinstance(event.get('type'), str):
raise ValueError('Expected an event type string')
if event.get('timestamp') is not None and not isinstance(event['timestamp'], str):
raise ValueError('Expected a timestamp string or omission')
payload = event['payload']
kind = event.get('type')
if kind == 'response_item' and payload.get('type') in [
'custom_tool_call', 'custom_tool_call_output',
'function_call', 'function_call_output',
]:
keys = ['type', 'call_id', 'name', 'input', 'arguments', 'output']
elif kind == 'token_usage_record':
keys = ['response_id', 'usage', 'turn_token_usage', 'thread_token_usage']
payload = {key: token_counts(payload[key]) if key != 'response_id'
else payload[key] for key in keys if key in payload}
elif kind == 'event_msg' and payload.get('type') == 'token_count':
keys = ['type', 'info']
info = payload.get('info')
if info is not None:
if not isinstance(info, dict):
raise ValueError('Expected token-count info')
selected_info = {key: token_counts(info[key]) for key in
['total_token_usage', 'last_token_usage'] if key in info}
window = info.get('model_context_window')
if 'model_context_window' in info:
if window is not None and (not isinstance(window, int) or isinstance(window, bool) or window <= 0):
raise ValueError('Expected a positive model context window')
selected_info['model_context_window'] = window
payload = {'type': 'token_count', 'info': selected_info}
else:
payload = {'type': 'token_count', 'info': None}
else:
return None
return {
'timestamp': event.get('timestamp'),
'type': kind,
'payload': {key: payload[key] for key in keys if key in payload},
}
def capture_tool_context(codex_home, output):
"""Capture only an explicitly selected trial's rollouts; never its auth/config."""
sessions = codex_home / 'sessions'
blocked = sessions.is_symlink()
sources = [] if blocked else sorted(sessions.rglob('*.jsonl'))
target = output / 'codex-tool-context.jsonl'
source_receipts = []
errors = [{'source': 'sessions', 'reason': 'not_an_owned_directory'}] if blocked else []
retained = 0
with os.fdopen(os.open(target, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600),
'w', encoding='utf-8') as result:
for source in sources:
name = source.relative_to(codex_home).as_posix()
if source.is_symlink() or not source.is_file():
errors.append({'source': name, 'reason': 'not_an_owned_regular_file'})
continue
digest = hashlib.sha256()
counts = {}
with source.open('rb') as lines:
for ordinal, line in enumerate(lines, 1):
digest.update(line)
try:
event = json.loads(line)
selected = selected_event(event)
except ValueError as error:
errors.append({'source': name, 'line': ordinal,
'reason': type(error).__name__})
continue
kind = event.get('type')
counts[str(kind)] = counts.get(str(kind), 0) + 1
if selected is not None:
result.write(json.dumps(selected, ensure_ascii=False) + '\n')
retained += 1
source_receipts.append({'source': name, 'sha256': digest.hexdigest(),
'event_counts': counts})
retained_digest = hashlib.sha256()
with target.open('rb') as captured:
for chunk in iter(lambda: captured.read(1024 * 1024), b''):
retained_digest.update(chunk)
receipt = {
'status': 'partial' if errors else 'captured' if source_receipts else 'unavailable',
'retained_file': target.name,
'retained_sha256': retained_digest.hexdigest(),
'retained_events': retained, 'sources': source_receipts, 'errors': errors,
'scope': 'Owned client tool-call/reply and per-response usage items, not '
'the exact submitted model request. Session/account metadata, '
'world state, user/developer messages, encrypted reasoning and '
'internal passthrough are omitted. Authentication, configuration '
'and ambient environment are never copied by this capture.',
}
(output / 'context-receipt.json').write_text(json.dumps(receipt, indent=2) + '\n')
return receipt
-173
View File
@@ -1,173 +0,0 @@
import { isDeepStrictEqual } from "node:util";
import { readFile, writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { parseArgs } from "node:util";
const { values } = parseArgs({
options: {
left: { type: "string" },
right: { type: "string" },
output: { type: "string" },
},
});
if (!values.left || !values.right)
throw new Error(
"Use --left MEASUREMENT_DIR --right MEASUREMENT_DIR [--output JSON]",
);
const read = async (directory, name) =>
JSON.parse(await readFile(resolve(directory, name), "utf8"));
const left = await read(values.left, "summary.json");
const right = await read(values.right, "summary.json");
const leftAnswer = await read(values.left, "answer.json");
const rightAnswer = await read(values.right, "answer.json");
const sameSettings = [
"artifact",
"artifact_sha256",
"artifact_sha256_after",
"retained_verification",
"native_question",
"javascript_question",
"managed_question",
"provider_settings_sha256",
"provider_search_path_sha256",
"provider_environment_policy_sha256",
"measure_source_sha256",
"native_workflow_source_sha256",
"package_lock_sha256",
"node_version",
"sdk_client_version",
"sdk_server_version",
"platform",
"architecture",
];
const settingDifferences = sameSettings.filter(
(key) =>
!isDeepStrictEqual(left[key], right[key]) ||
((key === "provider_search_path_sha256" ||
(key === "native_workflow_source_sha256" &&
typeof left.native_question === "string")) &&
!/^[a-f0-9]{64}$/.test(left[key] ?? "")),
);
// Producer/view IDs identify different delivery observations; a named recovery
// describes the delivery path. All selected analyst facts still must agree.
const facts = (answer) =>
Object.fromEntries(
Object.entries(answer).filter(
([key]) => key !== "evidence_ids" && key !== "recovery",
),
);
const a = facts(leftAnswer);
const b = facts(rightAnswer);
const runSpecific = [];
for (const [side, answer] of [
["left", leftAnswer],
["right", rightAnswer],
]) {
if (Object.hasOwn(answer, "evidence_ids"))
runSpecific.push({
side,
path: ["evidence_ids"],
value: answer.evidence_ids,
});
}
// Binwalk assigns a new opaque region UUID in each invocation. Preserve both
// original lookup values in this report; compare the observed region facts
// separately. The product and original replies retain those IDs unchanged.
if (left.artifact === "openwrt.bin") {
for (const [side, answer] of [
["left", a],
["right", b],
]) {
for (const [index, region] of answer.result.regions.entries()) {
runSpecific.push({
side,
path: ["result", "regions", index, "provider_id"],
value: region.provider_id,
});
delete region.provider_id;
}
}
}
// JavaScript result budgets depend on observed parent heap availability.
// Preserve their exact values on both sides, then compare the coverage facts
// and fixed worker limits. Never exclude status, omitted counts or families.
if (
left.artifact === "obsidian.asar" &&
left.javascript_question === "selected"
) {
const dynamicBudgets = new Set([
"javascript_analysis_parent_available_result_budget_bytes",
"javascript_analysis_parent_result_budget_bytes",
]);
for (const [side, answer] of [
["left", a],
["right", b],
]) {
for (const layer of ["application", "semantic"]) {
for (const [index, limit] of answer.coverage[layer].limits.entries()) {
if (!dynamicBudgets.has(limit.name) || limit.unit !== "bytes") continue;
runSpecific.push({
side,
path: ["coverage", layer, "limits", index, "value"],
name: limit.name,
unit: limit.unit,
value: limit.value,
});
delete limit.value;
}
}
}
}
const factDifferences = [
...new Set([...Object.keys(a), ...Object.keys(b)]),
].filter((key) => !isDeepStrictEqual(a[key], b[key]));
const cost = (report) => ({
revision: report.revision,
runtime_files_sha256: report.runtime_files_sha256,
delivery: report.delivery,
sdk_schema_mode: report.sdk_schema_mode,
elapsed_ms: report.elapsed_ms,
catalog_json_utf8_bytes: report.catalog_json_utf8_bytes,
calls: report.calls.length,
observed_tool_errors: report.calls.filter((call) => call.is_error).length,
client_result_json_utf8_bytes: report.calls.reduce(
(sum, call) => sum + (call.client_result_json_utf8_bytes ?? 0),
0,
),
client_before_send_ms: report.calls.reduce(
(sum, call) => sum + (call.client_before_send_ms ?? 0),
0,
),
transport_roundtrip_ms: report.calls.reduce(
(sum, call) => sum + (call.transport_roundtrip_ms ?? 0),
0,
),
client_after_receive_ms: report.calls.reduce(
(sum, call) => sum + (call.client_after_receive_ms ?? 0),
0,
),
});
const comparison = {
artifact: left.artifact,
artifact_sha256: left.artifact_sha256,
settings_match: settingDifferences.length === 0,
setting_differences: settingDifferences,
facts_match: factDifferences.length === 0,
fact_differences: factDifferences,
preserved_run_specific_values: runSpecific,
workflow_failures: [left.failure, right.failure],
left: cost(left),
right: cost(right),
scope:
"Same selected analyst facts; includes extra view calls and preserves observed tool errors. Result JSON bytes exclude file exports, catalog responses and raw wire framing. This is one paired observation, not a statistical speedup or independent ground-truth proof.",
};
const text = JSON.stringify(comparison, null, 2) + "\n";
if (values.output) await writeFile(values.output, text, { flag: "wx" });
process.stdout.write(text);
if (
settingDifferences.length ||
factDifferences.length ||
left.failure ||
right.failure
)
process.exitCode = 1;
-268
View File
@@ -1,268 +0,0 @@
{
"schema_version": 1,
"artifacts": [
{
"id": "sharex.dll",
"file": "ShareX.dll",
"bytes": 2162688,
"sha256": "191a191be964e434daf0f9d76d1e0d8ddce90d7e248cba2a6b5ac9577f288d53",
"provenance": {
"project": "ShareX",
"version": "19.0.2",
"upstreamFile": "ShareX-19.0.2-portable.zip",
"url": "https://github.com/ShareX/ShareX/releases/download/v19.0.2/ShareX-19.0.2-portable.zip",
"transport_sha256": "967b5d838df5ce25fb5fd7cbd16f1bd797427e2df16907b022b74a4bc0fb9d54",
"transport_bytes": 168796487,
"derivation": "selected regular ZIP member ShareX.dll"
}
},
{
"id": "sqlite.wasm",
"file": "sqlite3.wasm",
"bytes": 868907,
"sha256": "2ee8f3dab694532afc8840e07703127287662d08b74e6ff50491ce63f00d5752",
"provenance": {
"project": "SQLite Wasm",
"version": "3.53.4-build1",
"upstreamFile": "sqlite-wasm-3.53.4-build1.tgz",
"url": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.53.4-build1.tgz",
"transport_sha256": "24f46db4ce5248fa8f8f24b67e81909ab1a9c152f42a4796a32c6d385a6fb62b",
"transport_bytes": 977616,
"transport_integrity": "sha512-U8pvL0patYHMgieD8JxxYJTlh9m1LUX8+BDYb7MiKQzBI89f2qbdmdcG/PvnPaLm9wsBbv4VlVG453ixnxBOnA==",
"derivation": "selected regular tar member package/dist/sqlite3.wasm"
}
},
{
"id": "obsidian.asar",
"file": "obsidian-1.14.4.asar",
"bytes": 27477966,
"sha256": "146ef8470d8cbb4a6db209bdc19bf2bad13350444186c0fd93c31087b142b92f",
"provenance": {
"project": "Obsidian",
"version": "1.14.4",
"upstreamFile": "obsidian-1.14.4.asar",
"transport": {
"file": "obsidian-1.14.4.asar.gz",
"url": "https://github.com/obsidianmd/obsidian-releases/releases/download/v1.14.4/obsidian-1.14.4.asar.gz",
"sha256": "d1ed428c363968774f0f3906e67d8a53a058ece0b6cdd924b07865977b2ada21",
"bytes": 9200670
},
"derivation": "gzip decompression"
}
},
{
"id": "newpipe.apk",
"file": "NewPipe_v0.29.1.apk",
"bytes": 11507122,
"sha256": "18447bfb1e06d113edc88df93f471827280de06f6f3d4dc42f56f28b9c1bab79",
"provenance": {
"project": "NewPipe",
"version": "0.29.1",
"upstreamFile": "NewPipe_v0.29.1.apk",
"url": "https://github.com/TeamNewPipe/NewPipe/releases/download/v0.29.1/NewPipe_v0.29.1.apk"
}
},
{
"id": "jq",
"file": "jq-linux-amd64",
"bytes": 2267912,
"sha256": "b1c22172dd303f3be49e935aa56aa48a8b7a46e0bc838b4997d3bb451495870f",
"provenance": {
"project": "jq",
"version": "1.8.2",
"upstreamFile": "jq-linux-amd64",
"url": "https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-linux-amd64"
}
},
{
"id": "openwrt.bin",
"file": "openwrt-25.12.5-ath79-generic-tplink_archer-c7-v5-squashfs-sysupgrade.bin",
"bytes": 7405862,
"sha256": "f15b16b36df7fce8a5cf1302320fdb428c3bb6fbc2949a4858afa257f4f364a2",
"provenance": {
"project": "OpenWrt Archer C7 v5",
"version": "25.12.5",
"upstreamFile": "openwrt-25.12.5-ath79-generic-tplink_archer-c7-v5-squashfs-sysupgrade.bin",
"url": "https://downloads.openwrt.org/releases/25.12.5/targets/ath79/generic/openwrt-25.12.5-ath79-generic-tplink_archer-c7-v5-squashfs-sysupgrade.bin"
}
},
{
"id": "weth.hex",
"file": "weth-published.hex",
"bytes": 6251,
"sha256": "eb67ea4da28b88358df0385358bad3a58b131317835b45b3ede85c61851335e4",
"provenance": {
"project": "Published historical WETH runtime code example",
"url": "https://ethereum.org/developers/docs/apis/json-rpc/",
"contract_address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"published_block": "0x5daf3b",
"transport_sha256": "98c131a1bd99a0c2051dd6d6716fd306c36cdd45995d5ffd559bd9c690569c0f",
"derivation": "Parse the named eth_getCode JSON result from the official published example and preserve the hex carrier with one trailing LF",
"authority": "published historical RPC example; live retrieval returned HTTP 403; deployment authenticity remains unverified"
}
},
{
"id": "sharex.helpers.dll",
"file": "ShareX.HelpersLib.dll",
"bytes": 1076224,
"sha256": "e91bd1ec904e2bb8a1add4bb6187443b878bf33d24fe9e27f0b799bfee9de33d",
"provenance": {
"project": "ShareX HelpersLib",
"version": "19.0.2",
"upstreamFile": "ShareX-19.0.2-portable.zip",
"url": "https://github.com/ShareX/ShareX/releases/download/v19.0.2/ShareX-19.0.2-portable.zip",
"transport_sha256": "967b5d838df5ce25fb5fd7cbd16f1bd797427e2df16907b022b74a4bc0fb9d54",
"transport_bytes": 168796487,
"derivation": "selected regular ZIP member ShareX.HelpersLib.dll; no target execution"
}
},
{
"id": "sharex.exe",
"file": "ShareX.exe",
"bytes": 198656,
"sha256": "46af1ccc514b395cb703633abb5a505a771942b7db9b1915f31aeea541b3685f",
"provenance": {
"project": "ShareX native executable component",
"version": "19.0.2",
"upstreamFile": "ShareX-19.0.2-portable.zip",
"url": "https://github.com/ShareX/ShareX/releases/download/v19.0.2/ShareX-19.0.2-portable.zip",
"transport_sha256": "967b5d838df5ce25fb5fd7cbd16f1bd797427e2df16907b022b74a4bc0fb9d54",
"transport_bytes": 168796487,
"derivation": "selected regular ZIP member ShareX.exe; PE32+ x86-64 with no CLR directory; no target execution"
}
},
{
"id": "freedos.edlin.exe",
"file": "EDLIN.EXE",
"bytes": 31492,
"sha256": "96b2b6d543e2d8bdc83e313756444e103339eb5ee2c1229abe3607539b31ad6e",
"provenance": {
"project": "FreeDOS EDLIN",
"version": "2.24",
"upstreamFile": "edlin.zip",
"url": "https://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/repositories/1.4/base/edlin.zip",
"transport_sha256": "9db8a0b50bc4be5c2358cd0fa1fb6fc77342c6d5175a6b1084547c370e428f8a",
"transport_bytes": 377009,
"derivation": "selected regular ZIP member BIN/EDLIN.EXE; original UPX-compressed DOS MZ; APPINFO/EDLIN.LSM reports version; no execution or unpacking"
}
},
{
"id": "vscode.tree-sitter.wasm",
"file": "tree-sitter.wasm",
"bytes": 206218,
"sha256": "3a31af706ffdf4a7116b064cdd4988df6791823298615009fc5b6bccbd42909b",
"provenance": {
"project": "VS Code Tree-sitter published WASM package",
"version": "0.3.1",
"project_url": "https://github.com/microsoft/vscode-tree-sitter-wasm",
"upstreamFile": "tree-sitter-wasm-0.3.1.tgz",
"url": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.3.1.tgz",
"transport_sha256": "985684b2cfbe5e8f90499a9f36e37519887c7d4e2697d0457d0f1e923ce5184c",
"transport_bytes": 2053205,
"transport_integrity": "sha512-RJFoomET6FajjG511fmQxeBQfU6M24a0aFZPqpid+ttIxanWf1VGytBG0UmsGjt07qmIPJS8U31D+aecuCucsQ==",
"derivation": "selected regular tar member package/wasm/tree-sitter.wasm; no target execution"
}
},
{
"id": "vscode.tree-sitter-css.wasm",
"file": "tree-sitter-css.wasm",
"bytes": 128668,
"sha256": "8a23977fe271357cce6f254ef88c9bebf3854602d8046605aef6a45c02135c59",
"provenance": {
"project": "VS Code Tree-sitter published WASM package",
"version": "0.3.1",
"project_url": "https://github.com/microsoft/vscode-tree-sitter-wasm",
"upstreamFile": "tree-sitter-wasm-0.3.1.tgz",
"url": "https://registry.npmjs.org/@vscode/tree-sitter-wasm/-/tree-sitter-wasm-0.3.1.tgz",
"transport_sha256": "985684b2cfbe5e8f90499a9f36e37519887c7d4e2697d0457d0f1e923ce5184c",
"transport_bytes": 2053205,
"transport_integrity": "sha512-RJFoomET6FajjG511fmQxeBQfU6M24a0aFZPqpid+ttIxanWf1VGytBG0UmsGjt07qmIPJS8U31D+aecuCucsQ==",
"derivation": "selected regular tar member package/wasm/tree-sitter-css.wasm; no target execution"
}
},
{
"id": "uniswap-v3.factory.hex",
"file": "UniswapV3Factory.runtime.hex",
"bytes": 49073,
"sha256": "fb152cc9b597ef4e54e9d72e81dd72c202050aae5e98c63df139864274504276",
"decoded_bytes": 24535,
"decoded_sha256": "95c34fe1e6b26c79ae42800041a3e2bdb6a978d19297cd74001ac6b316a48d8d",
"provenance": {
"project": "Uniswap v3-core UniswapV3Factory",
"version": "1.0.1",
"url": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.1.tgz",
"transport_bytes": 86371,
"transport_sha256": "141b001e2a376fff867cb24e0713b2834095cb1250c13aae263d9a646446d329",
"transport_integrity": "sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==",
"archive_member": "package/artifacts/contracts/UniswapV3Factory.sol/UniswapV3Factory.json",
"compiler_artifact_bytes": 104076,
"compiler_artifact_sha256": "599479f60ebb056804aff7b2d05bdd0830ddbb1fdfaa0b6c62c02294ca7188b0",
"derivation": "Parse the exact published Hardhat deployedBytecode field and preserve its original hex carrier with one trailing LF; preserve template placeholders",
"authority": "Published compiler runtime template, not a live deployed instance; original placeholders/immutables preserved; no execution or chain lookup",
"published_abi_function_count": 7,
"deployed_link_references": {},
"immutable_references": {
"recorded": false,
"value": null
},
"immutable_scope": "Published Hardhat artifact does not record an immutable-reference map; absence is unknown, not proof of no immutables. Runtime template bytes remain exact."
}
},
{
"id": "uniswap-v3.pool.hex",
"file": "UniswapV3Pool.runtime.hex",
"bytes": 44287,
"sha256": "84d90218eb125074383287877cdc564eca3765241e3bf6f6afdd64a922fbed2b",
"decoded_bytes": 22142,
"decoded_sha256": "3ef71385c2a22b945bead7904f24b25db877de9db51d1401f2f9daea07ea5c0c",
"provenance": {
"project": "Uniswap v3-core UniswapV3Pool",
"version": "1.0.1",
"url": "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.1.tgz",
"transport_bytes": 86371,
"transport_sha256": "141b001e2a376fff867cb24e0713b2834095cb1250c13aae263d9a646446d329",
"transport_integrity": "sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==",
"archive_member": "package/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json",
"compiler_artifact_bytes": 111557,
"compiler_artifact_sha256": "204fb2fa7ad1a639b1df5601f035f9924b064b721b97adf60c7d5d4712643e34",
"derivation": "Parse the exact published Hardhat deployedBytecode field and preserve its original hex carrier with one trailing LF; preserve template placeholders",
"authority": "Published compiler runtime template, not a live deployed instance; original placeholders/immutables preserved; no execution or chain lookup",
"published_abi_function_count": 26,
"deployed_link_references": {},
"immutable_references": {
"recorded": false,
"value": null
},
"immutable_scope": "Published Hardhat artifact does not record an immutable-reference map; absence is unknown, not proof of no immutables. Runtime template bytes remain exact."
}
},
{
"id": "localsend-arm64.apk",
"file": "LocalSend-1.18.2-android-arm64v8.apk",
"bytes": 46558706,
"sha256": "82ec3568fba2aa5295b9aae8b76f701d7a4703d86b9f8bad749472038fbaeab3",
"provenance": {
"project": "LocalSend",
"version": "1.18.2",
"upstreamFile": "LocalSend-1.18.2-android-arm64v8.apk",
"url": "https://github.com/localsend/localsend/releases/download/v1.18.2/LocalSend-1.18.2-android-arm64v8.apk",
"transport_sha256": "82ec3568fba2aa5295b9aae8b76f701d7a4703d86b9f8bad749472038fbaeab3",
"transport_bytes": 46558706,
"derivation": "Official arm64 release APK, compared with GitHub release asset digest; byte-only analysis without execution"
}
},
{
"id": "qgis-world-map.gpkg",
"file": "qgis-world-map.gpkg",
"bytes": 12914688,
"sha256": "01d293159d1b77bd9212b5252587853f61aa9e25b2387135f34afaba8d057190",
"provenance": {
"project": "QGIS bundled world map",
"source_commit": "e1223b8e9e71fc50ee995ed556f711c54ccc101b",
"git_blob_sha1": "c9ff80228dff0de93c9acdef16a97545ba360244",
"url": "https://raw.githubusercontent.com/qgis/QGIS/e1223b8e9e71fc50ee995ed556f711c54ccc101b/resources/data/world_map.gpkg",
"derivation": "unmodified official resource file; streaming Git blob and SHA-256 verification"
}
}
]
}
@@ -1,218 +0,0 @@
# EVM descriptor and real-template checkpoint
Continues [#2016](https://github.com/morluto/rea/issues/2016) after the native
checkpoint merged. The internal descriptor binds the existing exact EVM
contract, CLI name and typed service lifetime. Existing complete inputs, output,
provider selection and cleanup remain the baseline. Wiring alone does not establish
token or latency savings.
The descriptor contains only the named contract, existing CLI name and existing
factory. The legacy `createEvmInterfaceService` export remains usable. The MCP
host selects one complete service instance, preserves injection identity, passes
that same instance to registration and retains it for cleanup/retry. No bound
service wrapper, generic registry, automatic dependency acquisition or new pack
selection is introduced.
Five actual in-memory SDK boundary scenarios verify converted schemas, duplicate
registration rejection before use, malformed inputs, explicit unavailable or
incompatible-output failures with a healthy WASM peer, cleanup retry, and request
cancellation followed by recovery. Their injected ports are recording seams, not
real EVMole/WABT claims. Nine service and 26 provider-boundary cases also pass;
two unsupported-host scenarios are skipped on this Linux host. The existing seven
WASM MCP scenarios pass. Full `npm run check` passes; its approximately 3 GiB
sampled peak and `memory.high` events are excluded from performance claims.
Candidate real-artifact/catalog and model observations are recorded below.
## Public inputs and independent checks
[corpus.json](corpus.json) retains the original WETH historical example and adds
Uniswap v3-core 1.0.1 Factory/Pool compiler runtime templates from the official npm
package. Archive integrity, exact regular member, compiler JSON, original carrier
and decoded-byte digests are pinned. The carrier is the original `deployedBytecode`
field plus one trailing LF. No placeholder is rewritten and no contract is executed.
These are compiler templates, not live deployed instances. Their published Hardhat
artifacts omit immutable-reference maps; that metadata remains explicitly unknown.
The recorded empty link-reference maps do not establish absence of immutables.
WETH remains a published historical RPC example, with unknown live authenticity.
Actual control CLI observations infer 7 Factory and 26 Pool functions. The
[independent verifier](verify-evm-template.mjs) hashes each canonical published ABI
signature with caller-supplied Ethereum Keccak and checks the complete ABI-dispatch
selector multiset against the original REA response. Both sets match. This does not
establish inferred argument/mutability equivalence, deployment authenticity or
runtime semantics; all producer unknowns remain visible.
## Latest-main control
Production control: `1770f38cfc6cbe87491d0de8b8730c305c5cf8ea`, Node 24.18.0,
npm 11.16.0, matching locked dependencies and unchanged EVMole 0.9.3.
The frozen `dist/`/`bridge/` file-table SHA-256 is
`7fd6c2c37b4e166df158ec29d48d31f3712b9b087d9807ee019ee997d06ea144`.
Measurement driver SHA-256 is
`f767c0c0232be1e11918e70e3197a6919680d16688076bef28d4320662f712f7`.
Each public SDK run validates the selected named advertised schema and verifies
original carrier and decoded identities, inference/unknown scope and unchanged
input bytes. All three runs return the same complete 2,420,709-byte catalog.
| Question | Inferred functions | SDK tool-result JSON bytes | First workflow seconds |
| ------------------------ | -----------------: | -------------------------: | ---------------------: |
| WETH historical carrier | 11 | 26,760 | 11.432 |
| Uniswap Factory template | 7 | 110,424 | 3.628 |
| Uniswap Pool template | 26 | 110,998 | 11.211 |
These are initial observations, not paired performance conclusions or model-token
counts. Each workflow includes connection, complete catalog discovery and one
interface query. Full bytecode remains inline. Candidate/control repetitions must
use the same source driver, inputs, provider settings and Node/worker limits.
Preparation against earlier frozen main `b1bf4a70d44191348ca20a91a52fb663da4daed0`
also passed all 59 cases of the existing real CLI/MCP EVM verifier with privately
supplied solc 0.8.30 and strace 6.1. Those cases cover compiler configurations,
raw/hex identity, malformed/unsupported carriers, missing limiter and resource
constraints. Its measured scope took 233.1 seconds, sampled peak 1,192,730,624
bytes and last-observed CPU 181.018 seconds. This is a control, not candidate proof.
All heavy runs are serial under one CPU, 4 GiB hard memory/3 GiB early-stop, no swap
and bounded tasks. Final cgroup counters disappear at scope teardown and remain
unverified; last-observed zero limit events are not substituted for final counters.
Raw replies, tools, compiler artifacts and detailed receipts remain outside Git.
## Reproduction
Build and freeze each pinned runtime using the repository toolchain, then run
`measure.mjs --artifact uniswap-v3.factory.hex` or `uniswap-v3.pool.hex` with the
exact derived carrier, `--schemas selected`, explicit runtime/revision and a fresh
private output directory. Existing `weth.hex` answer fields and invocation remain
unchanged. The same common workflow verifies all three offline carriers.
Run `verify-evm-template.mjs` with `--artifact` selecting the corpus ID,
`--artifact-json` selecting its original published compiler JSON, `--evidence`
selecting the recorded CLI Evidence or SDK structured reply, `--keccak-module`
selecting the absolute `js-sha3/src/sha3.js` module from the private solc toolchain,
and `--output` selecting a new private receipt. It acquires no dependencies and
does not overwrite an existing receipt.
The [template model question](questions/evm-uniswap.txt) requires the same complete
inferred interface facts and explicit unknowns. An ABI-count match is not used as
a model grade.
## Candidate compatibility and real-provider verification
Candidate: `152984da771450048ee9d60db8a410994a125878`, frozen runtime file-table
SHA-256 `725563640c27eb50ddb6f977d2dfbe1bdaddf7e05c02897318bceaa36fa602d7`.
Two repetitions for each EVM input produce six passing paired fact/settings
comparisons with the same driver and explicit limits. Each report preserves both
original Evidence reference maps. The complete actual SDK catalog is byte-identical
on every pair, including order, names, descriptions, schemas and annotations;
catalog SHA-256 is
`8664e42fd5225645cfd910f440f731c67ac198d3d53aa85b5c485374c74cf603`.
Result byte counts remain unchanged. Candidate Factory/Pool selectors also match
the independent published ABI oracle.
| Question | Control seconds, repetitions 1 / 2 | Candidate seconds, repetitions 1 / 2 |
| -------- | ---------------------------------: | -----------------------------------: |
| Factory | 3.628 / 3.650 | 3.708 / 3.605 |
| Pool | 11.211 / 3.591 | 3.749 / 3.581 |
| WETH | 11.432 / 3.694 | 3.572 / 3.677 |
First controls preceded wiring; each second pair ran candidate then control.
Every measurement starts a new MCP process; host cache/page state is not fully
controlled. Slower initial controls do not establish a descriptor speedup.
Second-pair latency and last-observed CPU are similar. Sampled EVM SDK family peaks
range from 510,255,104 to 527,622,144 bytes. No scope abort occurred; final counters
remain unknown, so these measurements are descriptive.
The candidate passes all 59 existing real CLI/MCP verifier cases with solc 0.8.30
and unchanged EVMole 0.9.3. Actual syscall traces report target execution and network
sockets absent for those scenarios, and the verifier reports no remaining
descendants. The scope took 177.456 seconds, sampled peak 1,237,020,672 bytes and
last-observed CPU 144.913 seconds. Different totals from the earlier control are
not attributed to unchanged provider algorithms.
Post-descriptor public MCP regression uses the original pinned shipped corpus:
| Domain / selected question | Actual provider / scope | Calls | Seconds |
| ------------------------------------------- | -------------------------------------------------- | ----: | ------: |
| SQLite WASM counts / exports | WABT 1.0.42; selected summary and retained read | 2 | 5.516 |
| ShareX managed metadata / native boundaries | Static PE/CLI, no assembly execution | 2 | 3.710 |
| Obsidian manifest / inventory | Complete inventory retained, no AST claim | 4 | 5.376 |
| NewPipe package / MainActivity methods | Real headless JADX 0.7.1 | 3 | 21.669 |
| OpenWrt regions | Real firmware signature scan, no device execution | 1 | 3.581 |
| jq native entry | Ghidra 12.1.4, default analysis, ephemeral Program | 4 | 270.986 |
All six workflows pass named SDK output validation and original digest checks;
input bytes remain unchanged. Maximum sampled family peak is 1,284,648,960 bytes.
They establish those available Linux workflows, not paired performance or
Windows/macOS, IDA/Hopper, Android-device, DOS COM, browser or JavaScript AST
behavior. Browser/AST were not repeated for this narrow migration.
## Real model complete-output calibration
Six serial Codex CLI 0.161.0 trials request `gpt-5.6-terra`, high reasoning, with
isolated temporary profiles pointing to the frozen candidate. Resolved server-side
model identity is not inferred. Only the EVM inspection tool is enabled, matching
the earlier WETH calibration; this is not full-catalog tool selection verification.
Every trial makes one successful call and no failed call.
| Trial | Total input | Uncached input | Output | Seconds |
| --------- | ----------: | -------------: | -----: | ------: |
| Factory 1 | 66,158 | 36,974 | 1,329 | 43.483 |
| Pool 1 | 65,600 | 36,416 | 2,307 | 69.546 |
| WETH 1 | 54,700 | 25,516 | 1,144 | 56.372 |
| Factory 2 | 65,964 | 36,780 | 1,453 | 26.412 |
| Pool 2 | 65,753 | 36,569 | 1,939 | 74.706 |
| WETH 2 | 54,502 | 25,318 | 1,208 | 35.137 |
Every trial reports 29,184 cached input tokens. Selected fact/reference/lifecycle
grades all pass: original/decoded identities, every inferred selector, offset,
dispatch, argument/mutability string including null, explicit unknowns, no runtime
execution, observed Evidence references, unchanged bytes and removed profiles.
Raw transcripts and grades remain private. Sampled peaks are
594,853,888–776,335,360 bytes; last-observed CPU is 6.181–7.034 seconds. Strict
overall grades remain unverified because final resource counters are unknown;
they are not relabeled as wholly passing resource-qualified runs.
This calibrates the current complete path after compatible wiring, not a paired
model performance experiment. The next token experiment should answer the same
interface question through an explicitly selected precise view, retain full
bytecode/original Evidence under the existing lifetime, and preserve complete
defaults. Discover support before sending new options to an older server. Include
discovery, follow-up, failures and retries in the complete task cost.
## Static contract admission verification
The follow-up from main `c462a4ebd3a10e59253bcf38353a0914b176738b` tests the
pilot's actual static boundary, without adding a dynamic module registry or
changing production code. Complete-project TypeScript checking now verifies
that the inferred descriptor type rejects a WASM operation contract, a WASM
CLI command, a WASM service factory, an unrelated input schema and an unrelated
output schema. These are negative assignability assertions: their guarantee
comes from the compiler, not from executing an incompatible descriptor.
The existing named contract and CLI identity are also checked at runtime;
separate factory calls produce distinct service/provider owners. Invalid target
input remains an application error without launching a worker.
The actual public in-memory MCP SDK test additionally spies on the provider:
duplicate EVM registration throws the named `already registered` error before
any provider call. Converted input/output JSON Schemas validate before the
first valid operation. Invalid client arguments are rejected before execution;
incompatible provider reply data is validated **after** execution and is not
presented as a pre-use contract guarantee. Existing healthy-peer, cancellation,
retained summary/default and cleanup-retry scenarios remain covered.
Full project typecheck passes with the installed compiler's supported single
thread scheduling; it includes all source/test files. The two exact focused
files pass 12 runtime cases. The resource scopes sample 2,057,961,472 bytes for
typecheck and 2,426,290,176 bytes for required build plus focused tests, below the
unchanged 3 GiB early-stop/4 GiB hard ceiling. Final transient-cgroup counters
remain unknown. No new real-provider or performance improvement is claimed by
these compile/SDK checks; the earlier pinned real EVMole/WABT/lifecycle evidence
retains its original scope and source identity.
This proves the one statically composed descriptor's named/schema/factory
compatibility and duplicate-registration guard. It does not implement runtime
admission of arbitrary JavaScript descriptors, third-party plugin ABI/version
negotiation or a general plugin SDK. Those remain deferred by the original plan.
Existing callers, full defaults, provider inputs, owned lifetimes and output
identities are unchanged.
@@ -1,208 +0,0 @@
# EVM interface delivery and migration checkpoint
Continues [#2016](https://github.com/morluto/rea/issues/2016) after the static
descriptor merged in [#2261](https://github.com/morluto/rea/pull/2261). Opt-in
`inspect_evm_interface` MCP `detail: "summary"` returns every inferred interface
candidate without bytecode hex or duplicate stdout. Complete Evidence remains
retained under its original identity. Delivery bytes fall; the measured model
cohort does **not** establish a stable token or task-time improvement.
## Frozen scope
Control production is `ad08510a113d7a9b8d92fb1e385757880e469869`; candidate
production is `32c7548b9ae5c8cda348653d177b1747127c74ba`. Their compiled file-table
SHA-256 values are respectively
`f68e85030cb05082520ea9f0d7650298ae316ce7bba59a8942e0cc1318ae9850` and
`978b3a014e3b2a1e1c6620364dcd793fa7cb40f19892d44cfb0312739a8c14a3`.
The SDK driver SHA-256 is
`a95d8d8e9f72c0b2b885c61907ed13054ebf7d1642f6f13b0126163840b1221a`.
Driver commit `03bff83e70e09a917341c1fe3ebffbfdc67785c5` fixes only reading the
public `get_evidence_bundle.result.records` envelope; production is unchanged.
Both runtimes use Node 24.18.0, matching locked dependencies, SDK client/server
2.3.1 and unchanged bundled EVMole 0.9.3.
Inputs are the digest-pinned WETH historical hex carrier and Uniswap v3-core
1.0.1 Factory/Pool compiler runtime templates in [corpus.json](corpus.json).
Original carrier and decoded-byte identities remain distinct. Templates are
not authenticated deployed instances; constructor-dependent values and absent
immutable-reference metadata stay unknown. No chain, target execution or
signature lookup is introduced.
## Public SDK pairs
Two pairs per artifact run serially: complete control then selected candidate,
followed by candidate then control. Each starts a fresh MCP process, discovers
the catalog and validates the actual named advertised schema. Host caches are
not independently controlled. All six fact/settings comparisons pass. Both
answer projections omit unrequested hex; original complete replies remain intact.
| Input | Complete / summary result bytes | Reduction | Control seconds, 1 / 2 | Candidate seconds, 1 / 2 |
| ------- | ------------------------------: | --------: | ---------------------: | -----------------------: |
| Factory | 110,424 / 14,442 | 86.92% | 3.670 / 3.766 | 3.664 / 3.867 |
| Pool | 110,998 / 19,922 | 82.05% | 4.110 / 3.740 | 3.977 / 3.870 |
| WETH | 26,760 / 15,378 | 42.53% | 3.671 / 3.710 | 3.930 / 3.673 |
These measurements support smaller delivery, not faster interpretation. Analysis
still runs and the full parent still incurs producer/retention costs. Catalog
count and order stay at 184 tools. The complete catalog grows from 2,422,229 to
2,429,938 compact JSON bytes (+7,709); all name/description/input definitions
grow from 512,655 to 514,074 bytes. The EVM input definition grows from 1,443 to
2,029 bytes. Only `inspect_analysis_view` and `inspect_evm_interface` definitions
change. These discovery costs are visible and are not converted into token counts.
Nine separate measurements verify new-server complete defaults, old-server
summary fallback and retained reads for all three inputs. The four-call retained
proofs retrieve the complete canonical parent plus pages and cost 160,110,
177,106 and 79,160 bytes for Factory, Pool and WETH respectively. They are
verification workflows, not examples of one-call delivery savings.
## Real Codex pairs and answer qualification
Twelve serial Codex CLI 0.161.0 trials use the existing identical questions for
each pair, the same artifact path, one enabled EVM tool, temporary MCP profiles
and requested `gpt-5.6-terra` high. The requested alias is not proof of the
resolved model identity. Trials include schema discovery, reasoning, one actual
successful EVM call and final answer. No call fails or retries. Profiles are
removed and input bytes remain unchanged. This fixed one-tool profile does not
test selection from the full catalog.
| Input / repetition | Uncached input, control → candidate | Seconds, control → candidate | Candidate delivery |
| ------------------ | ----------------------------------: | ---------------------------: | ------------------ |
| Factory / 1 | 22,901 → 25,668 | 52.485 → 48.768 | summary |
| Factory / 2 | 37,181 → 15,270 | 53.404 → 45.345 | summary |
| Pool / 1 | 36,652 → 26,657 | 57.764 → 66.642 | summary |
| Pool / 2 | 28,305 → 36,259 | 62.068 → 71.756 | complete |
| WETH / 1 | 21,128 → 25,187 | 44.869 → 46.809 | summary |
| WETH / 2 | 17,417 → 17,529 | 30.364 → 39.943 | summary |
Keep all trials, including the candidate that explicitly chose complete delivery.
Five of six candidates select summary, but uncached input improves in only two
pairs and time improves in only two. Aggregate control → candidate observations
are 362,496 → 357,770 total input; 198,912 → 211,200 cached input;
163,584 → 146,570 uncached input; 8,953 → 10,397 output; and
300.954 → 319.263 seconds. Cache state and model/service variation are not
separated; the aggregate does not establish a repeatable saving for an individual
question or a qualified performance recommendation.
Every answer passes exact core-field checks: both identities/byte counts, every
function selector/offset/dispatch/argument/mutability including null, inference,
unknown completeness/kind/hardfork/authenticity, and absent runtime execution.
All reported IDs occur in actual responses. However, the existing grader requires
the final limitation list to equal the producer list verbatim and in order.
Only three trials pass that additional check; nine fail. The questions request
preserving limitations but do not explicitly request a verbatim ordered list.
Four failures contain all original strings with extra correct scope statements
or different ordering. The other five paraphrase or omit source caveats, including
worker or upstream-metadata limitations. Do not silently waive those omissions
or turn these into twelve fully acceptable answers. The strict reports and
original transcripts remain intact; core-field success is a narrower result.
Model scope sampled peaks range from 562.5 to 710.5 MiB, with last-observed CPU
5.945–6.878 seconds. CPU includes the local process family, not remote model
computation. All heavy jobs use one CPU, a 4 GiB hard limit, 3 GiB early-stop,
no swap and 192 tasks. No scope abort occurs in this cohort. Final cgroup
counters are unavailable after teardown: final OOM/task/limit-event assertions
remain **unverified**. Last-observed counters are not substituted for final ones.
Consequently neither strict answer acceptance nor resource-qualified performance
success is claimed for the whole cohort.
## Existing-user compatibility
Omitted and explicit-complete MCP requests, the existing CLI and provider inputs
preserve their full behavior. `detail` is removed before the unchanged provider
input; original full Evidence parameters, raw result and identity are retained.
Summary receives its own identity linked to that parent. All candidate facts,
original report limitations, stderr/truncation and explicit unknowns stay inline.
Complete-within-view candidate coverage is not global discovery completeness.
Function pages retain original order; text pages use UTF-16 code units, with
hex characters distinguished from decoded-byte function offsets.
Actual new default replies for all three artifacts validate against the frozen
old advertised input/output schemas, and structured/text payloads agree. Older
servers reject neither request nor unsupported fields because the experimental
client discovers support before selecting summary and otherwise calls complete.
This is an explicit client fallback, not universal server forward compatibility.
Three authentic old-runtime records and old-created canonical bundles pass new
MCP import, retained summary, CLI inline summary and export. Original records,
IDs and bundle source bytes stay deeply equal. The reproducible verifier below
also checks function/hex pages with the analysis limiter explicitly unavailable,
so retained reads cannot silently start successful producer analysis. This
proves the pinned old/new Linux workflows, not every historical client release.
The initial retained experiment failed because its driver read the bundle's
wrong envelope. Correcting that consumer produced passing retained proofs; the
failed receipt stays archived and is not recorded as a REA defect. Separately,
one static-check attempt hit the unchanged 3 GiB early-stop. The bounded retry
passes with Node heap 512 MiB/native checker memory controls; its roughly 3 GiB
peak and soft-limit events are excluded from efficiency comparisons.
## Reproduction and checks
Use [the shared instructions](README.md), explicit frozen revisions/runtimes and
fresh private output directories. Run `measure.mjs` for `weth.hex`,
`uniswap-v3.factory.hex` and `uniswap-v3.pool.hex`, with `--schemas selected` and
paired `--delivery complete` / `summary`; run `compare.mjs` on equivalent pairs.
Add `--verify-retained` only for the separate four-call proof. Use the unchanged
[WETH](questions/evm.txt) or [template](questions/evm-uniswap.txt) question and the
same one-tool profile for `agent-trial.py`, preserving all usage and grader results.
Export complete Evidence with the old runtime's public ledger workflow, then run:
```sh
node experiments/analysis-efficiency/verify-evm-retention.mjs \
--runtime-root ABS_FROZEN_NEW_RUNTIME --revision NEW_SHA \
--bundle ABS_OLD_BUNDLE_JSON --output NEW_PRIVATE_ABS_DIR
```
The script acquires no dependencies and preserves the old bundle. Revision is
caller-supplied; retain the frozen file-table receipt alongside it. Raw JSON,
transcripts, profiles, bytecode, compiler inputs and generated artifacts stay
outside Git. This checkpoint adds source verification and curated observations.
The production change passes 64 focused EVM/WASM/generic-view/domain/service
checks and full static/docs gates. Recording provider seams establish exact
schemas, old defaults, inference/null preservation, historical identity failures,
peer availability, cancellation and cleanup retry; they are not real-provider
claims. Real-provider and shared-domain checks are recorded separately.
The same frozen candidate also passes six actual public MCP artifact workflows:
SQLite WASM with WABT summary, ShareX managed metadata, Obsidian inventory,
NewPipe with JADX, an OpenWrt region inspection, and jq entry analysis with
Ghidra. These are shared-contract regressions; they do not establish AST analysis
of all Obsidian code, full firmware reconstruction, browser coverage, or new token
savings in those domains. Native Windows PE and DOS coverage remains at the
[earlier native checkpoint](native-entry-views.md), not a new Ghidra/Windows claim.
The source retention verifier passes for all three authentic old EVM bundles,
including exact summaries, function/hex pages, CLI inline views and unchanged
exported originals with the limiter explicitly unavailable.
The frozen candidate passes all 59 existing real EVM CLI/MCP verifier cases with
caller-supplied solc 0.8.30 and strace 6.1, including malformed/unsupported
carriers, unavailable limiter and capacity failures. Its scope takes 96.076
seconds with 1,345,052,672 sampled peak bytes and 95.130 last-observed CPU seconds.
This is regression evidence, not an interpreter speedup comparison; final
resource counters remain unverified. Fresh fast static and generated-document
checks also pass after adding the migration verifier and this report.
## Latest-main integration
The branch rebases without conflict onto main
`0043d9b134c0a353e8bf85c0bde4492275f1f720`. Production integration commit
`3766749316c345ccb594b1b748747b1af9582b34` preserves the same EVM projection,
provider and delivery semantics; intervening main adds unrelated capabilities.
The above performance cohort stays pinned to its original frozen runtimes and
is not relabeled as a measurement of the larger integrated catalog.
At `cda794fb9d4a5ca2bd661853a899d579fb8a47b2`, all 30 affected EVM/WASM/generic-view
MCP tests pass again, as do full `npm run check` and `npm run docs:check`. A fresh
real Factory SDK selected-summary/retained-parent/page workflow and the original
Pool bundle's SDK/CLI migration verifier also pass against the rebuilt integrated
runtime. The latter still has an explicitly unavailable analysis limiter.
The initial integrated static-check scope stops at 3,221,446,656 sampled bytes,
just above the unchanged 3 GiB early-stop. Running the same typecheck through
its single Turbo task with less launcher overhead passes at 3,219,353,600 sampled
bytes; the subsequent full gate uses that valid cached typecheck and passes.
No memory threshold or check requirement is relaxed. Preserve both receipts;
these near-limit validation jobs are excluded from efficiency conclusions.
@@ -1,159 +0,0 @@
# EVM descriptor lifecycle acceptance
Continues [#2016](https://github.com/morluto/rea/issues/2016) after
[#2349](https://github.com/morluto/rea/pull/2349) merged. The
[public verifier](verify-evm-lifecycle.mjs) exercises actual compiled CLI and
stdio MCP workflows with unchanged EVMole 0.9.3/WASM. This increment adds
verification only; production contracts, factories, algorithms and defaults
remain unchanged. It does not introduce a plugin SDK or database cache.
## Runtime and public artifacts
The verified runtime is explicitly frozen from
`67f817e3653efad35f7044e68fbd6f163b86864b`, built with Node 24.18.0 and the
matching locked dependencies. Its `dist/` and `bridge/` file-table SHA-256 is
`cf03167870ac9def929cfaab536d6bd791089031660d1b35bff20672ac07cbbf`.
The table is checked again after each workflow; source and target bytes must
remain unchanged before a success receipt is published.
Inputs are the digest-pinned [corpus](corpus.json): published historical WETH
and official Uniswap v3-core 1.0.1 Factory/Pool compiler runtime templates.
They are not independently authenticated live deployments. Their deployment,
hardfork, immutable-reference and inferred-interface limitations remain as
recorded in [the descriptor checkpoint](evm-descriptor.md). The healthy peer
is the shipped SQLite WASM 3.53.4-build1 module, inspected by real WABT 1.0.42.
No contract, native target, chain/RPC query or transaction is executed.
## Actual cancellation and retained cleanup
The verifier supplies a private test launcher through the existing explicit
`REA_EVM_PRLIMIT_COMMAND` setting. It passes the original arguments to real
`/usr/bin/prlimit`, runs the unchanged Node/EVMole worker, then briefly gates
launcher completion after that worker exits and writes its complete reply.
This controls a real lifecycle boundary without replacing the analysis engine.
It adds process overhead and is not a performance comparison.
Before cancellation or permission changes, production inspection primitives
verify the live launcher's run token, parent/group relationship and native
start identity. The complete worker reply must match the original selected
bytecode and producer facts. Filesystem changes apply only to the verified,
non-root user's temporary runtime directory.
Three scenarios are verified:
- **Late cancellation:** the real worker has completed, while the public SDK
request remains pending. SDK cancellation reports `REQUEST_TIMEOUT` locally;
token sweeps and directory removal independently confirm provider cleanup.
A subsequent complete request returns identical analysis facts.
- **Successful analysis followed by cleanup failure:** removing write permission
produces actual `EACCES`. MCP reports `cleanup_incomplete` and retains the
original resource path. A retry before permission repair fails on that same
resource. Real SQLite WASM analysis still succeeds. Restoring permission lets
the provider retire the old resource and perform a fresh complete EVM query.
- **Format failure followed by cleanup failure:** a deliberately malformed
odd-nibble carrier reaches the unchanged worker. The cleanup error preserves
its original `invalid_input` category and exact producer diagnostic rather
than overwriting the failure. The same repair/retry and healthy-peer checks
succeed.
The existing CLI `inspect-evm-interface PATH hex --json` produces the same
complete normalized facts, parameters and subject as MCP. Fresh Evidence IDs
are not equated. Final verifier lineage is checked after client/transport close;
an empty descendant list is a point-in-time observation, not proof that the
workflow never launched children. Cleanup callbacks always run and preserve
verification and cleanup failures together.
This proves cancellation after actual analysis, not interruption inside
EVMole's synchronous WASM computation. Server-shutdown cleanup retry still has
the separately labeled injected-owner SDK tests from the descriptor checkpoint.
These Linux x64 observations do not establish Windows/macOS provider behavior.
Earlier real CLI/MCP malformed/unavailable/capacity checks remain linked in the
descriptor checkpoint; they are not silently rerun or attributed to this script.
## Measurements and compatibility scope
Initial three-carrier verifier source SHA-256 is
`2fec069b53324ef82070d323b26dd613b6da0caa7f18100adbeb39b045cf98dc`.
All three carriers pass all three scenarios and CLI parity with this same source.
| Carrier | Seconds | Sampled peak family bytes | Last-observed CPU seconds |
| ------- | ------: | ------------------------: | ------------------------: |
| WETH | 25.595 | 1,116,884,992 | 23.926 |
| Factory | 23.979 | 1,132,994,560 | 23.419 |
| Pool | 24.589 | 1,141,415,936 | 24.043 |
Runs are serial under the existing one-CPU quota, 4 GiB hard memory, unchanged
3 GiB early-stop, no swap and 192-task ceiling. Resource receipts, complete
producer replies, derived malformed input, launcher and runtime copies stay in
the private lab outside Git. Final cgroup counters disappear at scope teardown
and remain unknown; sampled zero events do not prove final no-OOM/no-limit
results. This is compatibility and recovery evidence, not a model-token,
whole-task latency or CPU saving claim.
Latest main `81cca2e0e3ebd98c21f41d7ad63d6a00e4cbc3f9` could not build during
setup: its shared partial-error handler passes three arguments to an interface
requiring four. Independently completed main CI at
`fdd8f826023c568937d237c2f97d855de283a9b8` reports the same TypeScript failure
([run 38309578208](https://github.com/morluto/rea/actions/runs/38309578208)).
The unrelated regression is recorded in the maintainer-requested private bug
handoff; this change does not repair it. The maintainer independently corrected
the producing caller in main `8fc2043eb8bcedbf34dce064f977e455438635d6`.
The frozen-runtime observations above remain pinned to their original revision;
synchronizing the branch does not relabel them as latest-main verification.
After rebasing, a fresh build and all 10 focused EVM MCP boundary tests pass.
The same unchanged source verifier also passes all three real Factory scenarios,
CLI parity, healthy SQLite WASM checks and final cleanup on the newly built
runtime `b3eadf147221a2fa997ac26667a183ca5bccb1f4` (parent is corrected main
`8fc2043eb8bcedbf34dce064f977e455438635d6`). Its `dist/`/`bridge/` file-table
SHA-256 is `7a4cec0fa4f7e929356b50a6b13472f80bd6f526221e427125370cca3ef98d00`.
This related rerun takes 24.285 seconds, samples 1,146,167,296 peak family bytes
and records 23.662 last-observed CPU seconds. The older failed build and earlier
cohort receipts are preserved; wider domain/model matrices are not repeated.
Static composition continues to bind one named canonical contract and one
typed factory. Existing SDK checks reject duplicate registration before use
and reject malformed inputs before invoking the provider. Producer contract
violations are detected when the producer returns a result; they cannot be
validated in advance without that result. A dynamic third-party module ABI
preflight is not implemented or claimed. The corresponding broader acceptance
item remains open rather than creating the deferred generic plugin registry.
## Final launcher review
A missing gate marker while gating is disabled cannot establish absence of a
new launch. The fixture now appends a launch record before starting the actual
worker; both permission-failure retries must leave that log byte-identical.
This independently verifies that retained cleanup failure stops a new EVM
launch, while preserving the original resource and healthy WASM peer.
Final verifier source SHA-256 is
`fc9a50e2e54e4c8eede4b8a19283e11ddaa1faadea52eebc390b55b5a1902668`.
All three related real Factory scenarios, CLI parity and final cleanup pass
again on the corrected-main runtime: 23.579 seconds, 1,163,685,888 peak sampled
family bytes and 23.110 last-observed CPU seconds. The earlier three-carrier
receipts remain pinned to their earlier source; wider artifacts/models are
not repeated for this review fix.
## Reproduction
Build and freeze the explicit source revision as documented in the measurement
README. Supply an object of explicit string-valued provider settings, including
the caller-installed WABT paths. As a non-root Linux x64 user, run under the
existing resource wrapper:
```bash
python3 experiments/analysis-efficiency/resource-run.py -- \
node experiments/analysis-efficiency/verify-evm-lifecycle.mjs \
--runtime-root /absolute/frozen-runtime \
--revision 67f817e3653efad35f7044e68fbd6f163b86864b \
--path /absolute/UniswapV3Factory.runtime.hex \
--peer-path /absolute/sqlite3.wasm \
--providers /absolute/explicit-providers.json \
--output /absolute/new-private-receipt-directory
```
The verifier checks the carrier and SQLite module against the committed corpus,
creates an owner-only receipt directory without overwriting existing receipts,
and acquires no dependencies. Preserve failed attempts separately. A shorter
reply or a successful cleanup verifier does not establish an agent-cost gain.
@@ -1,160 +0,0 @@
# Dart AOT summary and retained string pools
Continues [#2016](https://github.com/morluto/rea/issues/2016) and
[#2455](https://github.com/morluto/rea/pull/2455). The selected analyst question
asks for shipped LocalSend target/ABI/library identity, every nullable snapshot
observation, string-pool lower bounds and returned counts, and original coverage
and limitations. It does not require individual observed strings.
## Compatibility and ownership
MCP `inspect_dart_aot` accepts explicit `detail: "summary"`. Omitted and complete
requests preserve the complete result and original provider inputs. The CLI
remains complete. ABI omission and explicit ABI selection retain their original
meaning; the provider never receives the delivery field. Missing retention,
invalid detail and pre-cancellation fail before provider work.
The existing application workflow retains the complete original Evidence, then
returns a distinct derived summary linked to its parent ID. It preserves target
and libapp digests, every snapshot section and nullable fact, original pool and
overall coverage, lower-bound counts and limitations. `returned_counts` reports
the lengths of the producer-returned arrays; it does not upgrade lower bounds
to a complete snapshot inventory. The analysis and original source retention
are unchanged. No new engine, persistent cache or plugin SDK is introduced.
Read exact retained strings using `inspect_analysis_view`, the parent ID, and
`view: {kind: "dart-aot", collection: "package_uris", offset: 0, limit: 64}`.
Other collections are `dart_uris` and `class_like_tokens`. Follow the returned
next offset. Pages preserve source order, ABI/library identity and partial pool
coverage without opening the APK again. Page exhaustion describes retained
strings, not the entire snapshot. Strings remain byte-pattern observations,
rather than recovered typed class/function semantics. Missing historical
subjects remain explicitly unknown; conflicting recorded target digests fail.
## Frozen runtime and real SDK pairs
The official LocalSend 1.18.2 arm64 APK acquisition, size and SHA-256 are pinned
in `corpus.json`. No APK installation, target execution or version-dataset
lookup occurred. Source runtime: `811034a7283c9751a3ecbff33e8b2f28bec55793`;
compiled dist/bridge file-table SHA-256:
`dabbb63536c5862be839ecdc0f3eaad05b29c2a3816f57041528d30f754311be`.
The previous runtime is `28c84e78cf2fbfde4aceed345b773c59eb889f68`, digest
`5332dda13981f043e146b3601ebec1f380d9f698280ca53d75786b638a912e11`.
Its production sources were verified byte-equal to main f254 at acquisition.
Subsequent test-only changes and main's SAZ addition do not relabel these pins.
Node is 24.18.0 and the SDK client/server are 2.3.1. Each workflow starts a fresh
server and validates the selected live advertised schema. Artifact bytes,
provider environment/search-path fingerprints, driver and locked dependencies
stay equal. Host page caches are not flushed. Heavy tasks run serially under
the unchanged CPU, memory, task and host guards.
| Trial | AOT reply bytes | SDK workflow seconds | Payload CPU seconds | Kernel peak bytes |
| -------------- | --------------: | -------------------: | ------------------: | ----------------: |
| sdk-complete-1 | 151,341 | 5.139 | 6.819 | 691,441,664 |
| sdk-summary-1 | 12,037 | 5.219 | 6.608 | 639,430,656 |
| sdk-summary-2 | 12,037 | 5.064 | 6.405 | 640,868,352 |
| sdk-complete-2 | 151,341 | 5.128 | 6.468 | 633,614,336 |
Both pairs use one successful public tool call and pass settings/fact comparison,
including all snapshot fields, coverage, original limitations and all counts.
Reply bytes fall 92.05%. Whole SDK time stays approximately 5.1 seconds; these
trials do not establish engine speed, CPU or memory savings. Payload CPU includes
driver/catalog work beyond the SDK workflow timer. Catalog JSON grows from
2,506,213 bytes on the previous runtime to 2,514,896 (about 0.35%).
A fresh old-runtime complete request passes comparison against candidate
complete, including identical 151,341-byte replies. This is scoped compatibility
evidence, not a guarantee for every historical release or third-party client.
## Real old Evidence continuation
Fifteen successful public MCP calls import genuine old-runtime AOT Evidence,
project retained summary, reconstruct all 500 package URIs, 216 Dart URIs and
2,000 class-like tokens, compare inline portable summary, and export the original
record. The APK is absent during all these operations. Original string order,
lower bounds, partial coverage, nullable snapshot facts, subject and parent ID
remain intact; the original exported record is deeply equal to its source.
The first private verification attempt used a nonexistent receipt filename and
failed before import or artifact relocation. That driver error is retained;
the corrected attempt selects the fresh old-runtime record. It is not a REA
defect or a successful migration trial.
## Actual Codex task outcomes
Four serial trials use the same frozen candidate in complete/summary/summary/
complete order. Requested configuration is Codex CLI 0.161.0, `gpt-5.6-terra`
high, one exact enabled tool (`inspect_dart_aot`), and identical optional owned
context capture/discovery guidance. This requested alias does not certify the
server-resolved model. Temporary configuration points to the modified frozen
REA MCP; all copied credential profiles are removed and target bytes remain
unchanged. The source question is fixed; equal treatment instructions choose
detail and explain the summary carrier and parent reference.
| Trial | Input | Cached | Uncached | Output | Seconds | MCP attempts | Failed attempts | Facts |
| ---------------- | -----: | -----: | -------: | -----: | ------: | -----------: | --------------: | ----- |
| model-complete-1 | 74,641 | 50,176 | 24,465 | 2,765 | 116.898 | 3 | 1 | pass |
| model-summary-1 | 38,253 | 22,016 | 16,237 | 1,449 | 88.904 | 1 | 0 | pass |
| model-summary-2 | 38,363 | 22,016 | 16,347 | 1,515 | 55.190 | 1 | 0 | pass |
| model-complete-2 | 66,585 | 38,144 | 28,441 | 2,217 | 79.180 | 2 | 0 | pass |
Both pairs pass checks for every selected producer fact, exact nullable
observations, target digest, observed response Evidence IDs, original limitations,
artifact preservation and profile cleanup. The grader compares the reported
facts with producer observations; it is not an independent Dart deserializer.
Total input falls 48.75% / 42.38%, uncached input 33.63% / 42.52%, reported output
47.59% / 31.66%, and whole-task time 23.95% / 30.30%. Usage is the final aggregate
reported by the actual CLI, one usage record per trial; cached tokens are not
subtracted from total input. Reported output includes reasoning output (1,262,
321, 383 and 709 tokens respectively).
The first complete trial initially supplied `artifact_path` instead of the
advertised `path`, corrected it, then repeated a successful complete call.
The second complete trial made two successful calls. Both summary trials made
one successful call. All attempts, discovery and correction costs remain
included. The paired whole-task improvement therefore includes actual model
decisions and the convenience of explicit returned counts; it does not isolate
serialization as the sole cause or establish engine acceleration. Two pairs on
one app/question/model configuration support this scope, not a universal gain.
Payload CPU seconds / kernel peak bytes are respectively 12.556 / 876,937,216;
9.213 / 785,272,832; 9.108 / 793,939,968; and 13.164 / 803,209,216. Model payload
observations verify owned cleanup and zero phase limit events, with no guard
aborts. Whole-scope final counters remain unknown, so every strict all-selected
resource grade remains false even though the separate factual grade passes.
## Resource and verification scope
SDK and migration payload-exit observations verify owned cleanup and zero
observed memory/pids limit events, with peaks below 692 MB. Missing whole-scope
terminal counters remain unknown; the strict whole-resource grader stays false.
One-CPU quotas are experiment controls rather than CPU-efficiency claims.
Production-provider fixture tests cover explicit ABI, old complete defaults,
actual SDK-converted schemas, exact pages after APK removal, portable records,
nullable/partial facts, malformed inputs, target digest conflicts and early
refusals. CLI/MCP acceptance covers original report equality, duplicate-member
refusals and unsupported snapshot kinds. Fixture successes are distinguished
from the real LocalSend SDK/migration workflows. Other Flutter apps, architectures,
SDK layouts, typed class recovery and runtime behavior remain unverified here.
Raw replies, binaries, model traces and temporary credentials stay outside Git.
## Integration with the newer main
The rebased verification runtime is `63984ce0898bd7997e6d9b138e6d96d0a24f2b09`
on main `a2d8b94dd50dab8d966239dd63ab84718aa8b4b4`, with compiled file-table
SHA-256 `19c8ccdd3e99bb46a5c54f4edd8c6b2d2eb4f3a4870b3c129061d38145382b68`.
Targeted Flutter/SAZ/shared-view integration passes 35 tests; one opposite
runtime-capacity branch is skipped because this host enforces decoder memory.
Documentation checks and two README conformance tests pass.
Fresh real complete/summary SDK checks on this runtime match the earlier selected
facts and settings, with unchanged 151,341 / 12,037-byte AOT replies. Fifteen
old-Evidence migration calls again preserve every original string and record
with the source APK absent. The real one-shot CLI complete result also matches
the previous-runtime normalized report, subject, parameters and original ID.
An initial CLI-only controller check lacked an owned resource receipt; it is
retained and excluded from resource/performance claims, then repeated in the
bounded owned scope. These checks establish integration, rather than relabeling
the earlier paired model/SDK measurements as the rebased runtime.
@@ -1,120 +0,0 @@
# Native IDA MCP verification on Windows
Verification date: 2026-10-13. These runs used **IDA Pro 9.3** (executable
product version `9.3.26.0213`), not Windows IDA Free. Personal paths, raw
observations, and license registration information are excluded.
The native plugin was built from upstream
[`c9d15d98e8a143fc74f6e14037c48f63889b6d6c`](https://github.com/0xshlomil/ida-free-mcp/commit/c9d15d98e8a143fc74f6e14037c48f63889b6d6c)
with MinGW GCC 13 and its pinned public SDK. The only local source change
bound the listener to `127.0.0.1`; the upstream function-navigation fix was
already present. This does not verify the stock 1.1.2 release listener or
its older navigation order.
## Correctness and authority
The public [IDA fixture](../../tests/conformance/ida/inventory.c) contains
two exported functions with distinct bodies. Production CLI/MCP verification
checks matching function Evidence, assembly, a unique second-function marker,
return to the first function, original-input identity, invalid requests, and
connection cleanup. Native verification requires the second procedure and its
unique marker; missing, incomplete and empty arguments are rejected before
connecting. Dossier relationship coverage remains unknown when direct callers
are unavailable, while standalone callee coverage retains its own observed state.
It preserves the attached GUI database.
The later verification follow-up rejects native callee successes without an
explicit truncation marker, checks positive procedure inventory/search and
compares normalized function results. String and xref correctness require
independent positive oracles; runs without those oracles label them unverified.
Earlier reports established contract validity for these operations and did not
by themselves establish string/xref semantic correctness.
The follow-up passed eight production checks with a known CRT literal confirmed
in the unchanged fixture bytes and a reference source address independently
identified from `main` assembly matching the C source. A loopback response-only
proxy in front of the real IDA Pro provider reproduced the earlier verifier
passing empty function inventories and xrefs. The corrected verifier rejected
those replies with positive oracles, empty string results and missing native
callee truncation markers. The comparison used verifier source `d1aaeee40`
with the same current adapter runtime; it is a verifier comparison, not an
engine performance comparison. Only response payloads were modified; the original
input digest stayed unchanged, the target was never executed, and the attached
GUI database was preserved.
The real application was a digest-verified, unchanged copy of Windows
`whoami.exe`: 94,208 bytes, 243 recognized functions, and 314 upstream
C-string observations. The selected 1,741-byte function had 20 resolved
callees. Before and after, the task returned identical pseudocode, callee
addresses, and its one `whoami` string match. The executable was never run.
Other string representations remain unknown in the native profile.
A Windows C++ producer golden checked 24 literal/case combinations and
408 candidate comparisons, including metacharacters, Kelvin sign, dotted I,
sigma, supplementary characters, and null bytes. Adapter tests additionally
cover malformed UTF-16 fallback, candidate pagination, explicit search errors,
and reordered, missing, duplicate, unrelated, or failed lookup replies.
These checks do not establish IDA recognition of every Unicode string format.
## Equivalent completed tasks
Both builds used main `59be86671`. The baseline was `fb34ccbec`, before
the native performance edits; the comparison build added those edits.
Schemas were identical. Each run opened the same analyzed binary, read the
specified function's pseudocode and callees, searched literal `whoami`, and
closed the REA session. The task then repeated on the same MCP connection.
There were two runs per build on a shared host. Node 24.18.0 and IDA were
restricted to one logical CPU with below-normal priority; each Node process
had a 768 MiB heap ceiling. The attached database was already analyzed.
Node compile caching was disabled for the primary comparison.
| Measurement | Before | After |
| --------------------------------------------------- | -----------: | -----------: |
| Task response text | 49,139 bytes | 32,546 bytes |
| Task response token estimate | 16,618 | 11,509 |
| Callee lookup calls, including selector | 17 | 2 |
| String-search pages | 4 | 1 |
| String-search Evidence | 19,022 bytes | 3,344 bytes |
| Mean task time, warm MCP connection | 675 ms | 317 ms |
| Mean task time, fresh MCP process and catalog | 19.72 s | 20.86 s |
| Mean Node family CPU, fresh and warm tasks together | 17.72 s | 18.62 s |
| Largest Node family peak-RSS upper bound | 776.8 MiB | 780.0 MiB |
| Mean attached IDA CPU during both tasks | 226.6 ms | 171.9 ms |
The warm task was about 53% faster and its response estimate about 31%
smaller. Fresh-start, overall CPU, and memory improvements were not
established. Startup and full catalog conversion dominate the fresh task.
Two samples do not establish a general performance guarantee.
Token counts use local `cl100k_base` tokenization of complete serialized
MCP response text and request arguments; they are estimates, not model usage.
Requests added 99 estimated tokens per task. The unchanged full schema
catalog contained 2,422,229 bytes and 613,965 estimated tokens. Including it
once gives first-task estimates of 630,682 before and 625,573 after. A host
may select schemas lazily; actual host injection, prompts, reasoning tokens,
and model-side costs were not measured. No retries were needed.
Node CPU counters were captured at shutdown. The memory figure sums the
two processes' individual OS peak RSS values: an upper bound, not a
simultaneous family peak. Attached IDA is outside that process family; its
unchanged lifetime peak working set was 376.9 MiB, including initial analysis.
Measurement overhead and whole-machine resource use were not measured.
## Reuse and cleanup
Callee queries are deduplicated and batched within an operation. Literal
search fetches a conservative candidate set, including non-ASCII text when
needed, and preserves REA's final Unicode predicate. It examines all candidate
pages and retains full source observations. Regex searches keep the full scan.
Cross-request analysis results remain live because an input digest does not
establish database revision or freshness. An exploratory caller-selected
[Node compile cache](https://nodejs.org/download/release/v24.16.0/docs/api/module.html#module-compile-cache)
did not demonstrate startup improvement: empty-cache and cache-hit MCP starts
were 7.35 s and 7.56 s. It occupied 6.7 MiB and was limited to this experiment;
no new default cache or installation behavior was introduced.
Temporary source, SDK, build, portable runtime, cache, and raw measurement
outputs are test-owned cleanup targets. Attached GUI databases are retained;
REA never saves or closes them.
@@ -1,75 +0,0 @@
# Latest-main efficiency continuation
Continues [#2016](https://github.com/morluto/rea/issues/2016). The 2026-10-13
fetch resolved main to `f254f5ac2b804b353a711264bb178f43fdf07867`, the same
revision as the preceding Android conclusion. Newer capabilities below were
added during that earlier cycle; they are additional measurement scopes, not
new commits after that conclusion.
| Capability | Existing controls | Next evidence needed |
| ----------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| Flutter / Dart AOT (#1582) | Explicit ABI, bounded string observations, partial coverage | Real shipped snapshot/count question; opt-in delivery only if unrelated strings dominate |
| SQLite (#2271) | Compact inventory, selected table/columns, row limit | Real application database and model workflow before adding another selector |
| TShark (#2318) | Fields, filter, decode-as, pass, default 50 matching rows, paging, explicit null for all | Real public capture and repeated task cost; paging repeats dissection |
| sigrok (#2339) | Decoder/channels/annotation selection, default 50 display lines, paging | Real public capture; display-line count is not annotation count and paging repeats decoding |
| Retained unknown head results | Existing retained paging | Reuse the existing view rather than duplicate its implementation |
Attached IDA, Frida and other live runtime workflows involve separate authority
and lifecycle questions and are outside this static parsing continuation.
Plugin SDKs and cross-session engine caches remain deferred until an observed
need and benefit justify them.
## First selected scope: Dart AOT
The official LocalSend 1.18.2 arm64 APK is pinned in `corpus.json`. The initial
real public SDK baseline inspected actual bytes without executing/installing
the APK. Its complete default AOT reply was 151,341 compact client-result JSON
bytes (70,487 normalized bytes), with 500 package URIs, 216 Dart URIs and 2,000
class-like tokens. String-pool and overall coverage were partial. A second
explicit arm64 request returned the same normalized facts.
These are exploratory first/warm calls, not an optimization pair. The frozen
runtime source is `28c84e78cf2fbfde4aceed345b773c59eb889f68`, with production
source bytes verified equal to main f254 at baseline acquisition. Its compiled
file-table digest is
`5332dda13981f043e146b3601ebec1f380d9f698280ca53d75786b638a912e11`;
the receipt is not relabeled as a newer build.
The candidate adds explicit MCP `detail: "summary"` and retained pool pages.
Omitted/complete requests and the CLI preserve the old complete path. Analysis,
ABI selection and original Evidence stay intact. Summary retains target/libapp
identity, exact nullable snapshot observations, lower bounds, returned counts,
coverage and limitations. Pages preserve original string order and source
coverage without rescanning. No engine cache, provider protocol or third-party
plugin API is introduced.
Follow-up measurements must compare identical selected facts, portable old
Evidence and actual model tasks. Reply bytes do not establish token or latency
improvements. Whole-scope final counters remain unknown if their cgroup has
disappeared, even when the narrower payload-exit observation is verified.
Raw records, binaries and model traces stay in the private lab outside Git.
Heavy work remains serial under the unchanged one-CPU, 3 GiB early-stop / 4 GiB
hard memory, no-swap and host-availability guards.
## Main advanced during the experiment
Main subsequently advanced to `a2d8b94dd50dab8d966239dd63ab84718aa8b4b4`,
adding native Fiddler SAZ parsing. Its web-network capture contract already
offers opt-in summary and retained capture pages, archive-member coordinates
and exact exposed encoded bytes. It decodes all records before ordinal
selection and rejects malformed/oversized inputs without partial success.
Measure real public SAZ artifacts using these controls before adding another
API or changing decoding or credential-redaction semantics. SAZ performance
remains unverified in this Flutter continuation.
The Flutter cohorts keep their original frozen runtime; subsequent integration
onto this newer main does not relabel earlier measurement receipts.
Main advanced again to `bb154d106` during CI, adding retained aioquic 1.5.0
qlog 0.3 JSON parsing and qlog views. The existing capture summary/page path
already applies. Qlog's trace-scoped STREAM interval unions and endpoint loss
declarations have separate semantics: they do not recover bodies, prove network
loss or establish PCAP correlation. Measure genuine supported recordings and
existing retained views before adding delivery or caching. Other qlog layouts
and qlog performance remain unverified in the Flutter experiment. Shared-view
integration is checked after rebasing; earlier runtime receipts remain pinned.
@@ -1,234 +0,0 @@
# Managed artifact delivery and retained views
Continues [#2016](https://github.com/morluto/rea/issues/2016) after
[#2404](https://github.com/morluto/rea/pull/2404) merged. This checkpoint pins
the complete managed workflow before implementing another optional view.
The baseline below precedes implementation; the follow-up adds explicit summary
delivery and portable collection pages while preserving complete defaults.
## Frozen control and analyst question
Control source is merged main `ae8051302b5834322fa00cfa31c968ae74ab6ed9`,
Node 24.18.0, matching locked dependencies and actual compiled stdio MCP.
The frozen `dist/`/`bridge/` file-table SHA-256 is
`7a4cec0fa4f7e929356b50a6b13472f80bd6f526221e427125370cca3ef98d00`.
Measurement source SHA-256 is
`a95d8d8e9f72c0b2b885c61907ed13054ebf7d1642f6f13b0126163840b1221a`.
Use the digest-pinned shipped ShareX DLL from [the corpus](corpus.json),
2,162,688 bytes, SHA-256
`191a191be964e434daf0f9d76d1e0d8ddce90d7e248cba2a6b5ac9577f288d53`.
The [existing model question](questions/managed.txt) requests exact identity,
complete managed classification and its evidence, frameworks and every declared
native ModuleRef/PInvoke boundary with coverage and limitations. It explicitly
excludes unrelated resource/custom-attribute inventories. Analysis reads PE/CLI
metadata without loading or executing the assembly.
The current complete result has exactly the same normalized facts as the earlier
real managed checkpoint linked from [the EVM descriptor study](evm-descriptor.md).
This comparison does not equate fresh Evidence IDs, provider versions or whole
catalogs. Original target bytes remain unchanged; SDK-converted named schemas
and actual replies validate in the public measurement workflow.
## Observed data costs
| Public operation | SDK result JSON UTF-8 bytes | Tool milliseconds |
| ----------------------------------- | --------------------------: | ----------------: |
| `inspect_managed_artifact` | 1,270,839 | 450.306 |
| `inspect_managed_native_boundaries` | 27,913 | 142.663 |
The complete workflow, including connection/discovery and both calls, takes
3.721 seconds. The full discovered catalog is 2,482,204 compact JSON bytes;
its input definitions are 527,569 bytes. These costs include the current main
changes and are not silently substituted for an older catalog baseline.
The artifact inspection's normalized payload alone is 607,605 compact JSON UTF-8
bytes, measured with actual Node `JSON.stringify`:
| Returned collection | Rows | Compact JSON UTF-8 bytes |
| ------------------- | ----: | -----------------------: |
| References | 38 | 12,153 |
| Resources | 36 | 10,357 |
| Custom attributes | 1,945 | 582,586 |
Custom attributes dominate the payload. The remaining identity, PE/CLI,
classification, metadata, framework and coverage facts are comparatively small.
`raw_result` is null. SDK result size includes both structured and text
representations; it is not the exact context a model receives or a token count.
The serial owned scope takes 4.852 seconds including the driver, samples
520,110,080 peak family bytes and records 4.699 last-observed CPU seconds.
One CPU, 4 GiB hard memory, unchanged 3 GiB early-stop, no swap and 192 tasks
remain in effect. No guard abort occurs. Final cgroup counters disappear and
remain unknown; sampled zero events are not final no-OOM proof.
## Bounded candidate and acceptance
Evaluate an explicit overview on the first artifact inspection, retaining the
unchanged complete source and returning a distinct linked view. Keep complete
identity/classification, metadata status, nullable module/MVID, assembly,
frameworks, original coverage/issues/limitations and returned-collection counts
inline. Typed pages can expose original references/resources/attributes with
their nulls, token coordinates, offsets, order and values. Returned-array
coverage must remain distinct from whole-metadata completeness.
Reuse the existing managed schemas, retained Evidence application workflow and
named registration hooks. Keep omitted/complete requests, other managed tools,
selected target/provider behavior and original export/import identities usable.
Do not strengthen historical admission to require a non-null subject or
reinterpret foreign recorded paths through this host's filesystem. Delivery
selection must not be passed to the PE/CLI parser as an analysis option.
At the baseline checkpoint the candidate was not implemented or measured. Compare the
same completed analyst question, actual discovery/results, full default
compatibility and retained paging without producer reruns. Follow with other
shipped managed inputs, partial/unavailable metadata and real Codex trials with
strict factual/reference checks. Preserve failed or truncated transcripts.
Count total/cached/uncached input, output, calls/retries, whole-task time, CPU
and family memory before recommending a token or latency improvement. A smaller
reply alone is insufficient.
## Reproduce the control
Build and freeze the explicit source revision before editing production code.
Supply the original shipped DLL and an explicit string-valued provider dictionary
in a fresh private receipt directory:
```bash
python3 experiments/analysis-efficiency/resource-run.py -- \
node experiments/analysis-efficiency/measure.mjs \
--runtime-root /absolute/control-ae805 \
--revision ae8051302b5834322fa00cfa31c968ae74ab6ed9 \
--artifact sharex.dll --path /absolute/ShareX.dll \
--providers /absolute/explicit-providers.json --schemas selected \
--output /absolute/new-control-receipts
```
Raw replies, runtime copies, fingerprints and detailed resource receipts stay
outside Git. No new provider, plugin SDK, database cache or target execution is
introduced by this baseline.
## Implemented candidate and real SDK observations
Candidate `8bc1601ca51e417ca472d90ea0367e9418a1a0f2` adds
`inspect_managed_artifact({path, detail: "summary"})` and managed collection pages
through the existing `inspect_analysis_view` contract. The complete parser result
remains retained. Omitted detail and explicit `complete` keep complete output;
other managed tools do not acquire this selector. CLI inspection stays complete.
The frozen candidate runtime file-table SHA-256 is
`9e7380f537301bf0cfe2926f5619011af848af7c220750e75189498e65d825e1`.
The revised measurement driver SHA-256 is
`8c22f59e931fdc347dea1204ea0faf91330578db684357261ec6f03bd0efa85e`.
Use `--managed-question identity` on **both** sides, with `--delivery complete`
for the control and `--delivery summary` for the candidate. The original default
`inventory` recipe remains unchanged. Both identity recipes make the same two
public calls, validate their advertised SDK schemas, and compare complete
identity/classification, frameworks, coverage and native-boundary facts.
| Artifact | Complete metadata bytes | Summary metadata bytes | Complete two-call bytes | Summary two-call bytes |
| --------------------- | ----------------------: | ---------------------: | ----------------------: | ---------------------: |
| ShareX.dll | 1,270,839 | 10,549 | 1,298,752 | 38,462 |
| ShareX.HelpersLib.dll | 1,296,839 | 10,937 | 1,586,970 | 301,068 |
The helper assembly is a second shipped member of the same pinned ShareX release,
1,076,224 bytes, SHA-256
`e91bd1ec904e2bb8a1add4bb6187443b878bf33d24fe9e27f0b799bfee9de33d`.
It is not an independent application or a new runtime/provider lane. Its native
boundary report remains comparatively large and unchanged. Metadata reply bytes
fall by about 99.17% and 99.16%; two-call totals fall by about 97.04% and 81.03%.
The first committed-candidate observations take 3.699 and 3.838 seconds, versus
3.809 and 3.925 seconds for controls. These timings include discovery and do not
establish a general latency improvement. The full candidate catalog grows from
2,482,204 to 2,497,635 bytes; input definitions grow from 527,569 to 528,862.
An earlier dirty prototype produced the same runtime file-table hash and a
separate provenance receipt. Its observations remain separate; a clean baseline
commit is never presented as the source of uncommitted production changes.
## Actual Codex findings: token benefit is not established
Four sequential trials use actual Codex CLI 0.161.0, requested model
`gpt-5.6-terra`, high reasoning, the unchanged question above and the same two
enabled tools. The requested alias does not prove a resolved server model ID.
Order is control, candidate, candidate, control. Both candidate trials independently
select summary; all trials preserve dependency order, make two successful calls,
leave the artifact unchanged and remove temporary profiles.
| Trial | Input tokens | Cached input | Uncached input | Output tokens | Wall seconds |
| ----------- | -----------: | -----------: | -------------: | ------------: | -----------: |
| Control 1 | 54,821 | 29,184 | 25,637 | 1,782 | 63.207 |
| Candidate 1 | 77,594 | 50,432 | 27,162 | 1,583 | 46.685 |
| Candidate 2 | 82,426 | 49,408 | 33,018 | 2,120 | 67.379 |
| Control 2 | 55,296 | 29,184 | 26,112 | 2,361 | 62.159 |
Uncached input is reported input minus cached input. **Candidate input and
uncached input are higher in both comparisons.** Latency is mixed. This feature
demonstrates smaller selected delivery, not measured model-token savings or a
stable whole-task speedup. Event result bytes are also not a measurement of the
exact context presented to the model. No hidden truncation/cache mechanism is
inferred from these aggregates. Keep further model-context investigation separate
from this additive view implementation.
The question prescribes a `coverage` field without prescribing its nested labels.
The grader now accepts only explicit equivalent artifact/native scope names;
conflicting duplicate scopes still fail. Original failure receipts remain intact.
Control 1 and both candidates pass the selected factual checks after that
correction. Control 2 omits `classification.container` and does not report
separate artifact/native coverage in the expected representation; it fails these
strict selected checks. The prompt did not specify every nested key, so this is
also an answer-representation limitation. It is not counted as a fully acceptable
control answer or repaired by assuming ambiguous flat coverage. Original
limitations were additionally reviewed against producer replies.
All four reports still fail the **complete** selected gate because final physical
resource counters are unavailable. The factual subset is reported separately;
it does not turn unknown final resource counters into a pass. Trial guards remain
unchanged, no guard abort is observed, and sampled peaks stay below the 3 GiB
early-stop threshold. A sampled zero OOM count is not final no-OOM proof.
## Previous-runtime Evidence compatibility
Complete actual producer Evidence from control `ae8051302b5834322fa00cfa31c968ae74ab6ed9`
for both shipped assemblies is passed, unchanged, through the candidate's public
SDK inline view. Each artifact makes 14 view calls: a summary, all original
reference/resource/attribute pages at a caller-selected 256 rows, and exhausted
pages for each collection. Summary facts, every row and order, source coverage,
parent ID, links and target digest match; the original Evidence stays unchanged.
ShareX has 38/36/1,945 reported rows and HelpersLib has 49/17/1,988. No producer
operation or target mutation is requested by this portable workflow.
The private verification driver SHA-256 is
`7bb1f24b488beda012b1e78132de29b868fe1ea91a5e1499d7f271801fa40380`;
the receipt scope takes 5.860 seconds, samples 642,244,608 peak family bytes and
5.619 last-observed CPU seconds, with no guard abort. Final counters remain unknown.
These are actual previous-runtime records, unlike the separate synthetic
null-subject compatibility test. They do not prove every historical release.
Focused SDK/domain checks cover first-call summary, complete defaults, selected
target reuse, paging after the source disappears, malformed metadata, historical
null subjects, digest mismatch, portable projection and unavailable retention
before file access. The exact candidate CI passes all checks after only the
browser cleanup and Apple `hdiutil` jobs are retried on the same source revision;
their original failures remain recorded in the private team handoff.
## Committed-runtime repetition and complete defaults
A second SDK pair reverses the order (candidate before control) for both
assemblies. Result byte totals repeat exactly. ShareX workflow times are
3.644 versus 3.687 seconds; HelpersLib times are 3.714 versus 3.859 seconds.
Both pairs preserve selected settings/facts and have no tool errors. Two pairs
per assembly, sharing one application and host, remain a narrow descriptive
sample rather than a general performance claim.
Actual omitted-detail calls on the candidate additionally reproduce **all**
normalized metadata inventories and native-boundary facts from both controls,
not just the identity recipe's selected subset. Their canonical complete
Evidence IDs also match. This verifies the recorded old request and complete
result path alongside the explicit new delivery option.
The changed shared projector also handles an actual shipped SQLite WASM run
through the candidate's SDK summary workflow, with real configured WABT:
two calls, 18,687 result JSON bytes, 5.614 seconds and no tool failure. This
checks that neighboring dispatch path; it does not establish a new WASM
performance improvement or additional operating-system/provider coverage.
-996
View File
@@ -1,996 +0,0 @@
import { createHash } from "node:crypto";
import { createReadStream } from "node:fs";
import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
import { dirname, isAbsolute, resolve } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { isDeepStrictEqual, parseArgs } from "node:util";
import {
NATIVE_ARTIFACTS,
measureNativeEntry,
nativeEntrySeed,
} from "./native-entry.mjs";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import { Ajv2020 } from "ajv/dist/2020.js";
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
const { values } = parseArgs({
options: {
"runtime-root": { type: "string", default: root },
revision: { type: "string" },
artifact: { type: "string" },
path: { type: "string" },
providers: { type: "string" },
output: { type: "string" },
delivery: { type: "string", default: "complete" },
"verify-retained": { type: "boolean", default: false },
"native-question": { type: "string", default: "entry" },
"javascript-question": { type: "string", default: "inventory" },
"managed-question": { type: "string", default: "inventory" },
schemas: { type: "string", default: "default" },
"sqlite-selection": { type: "string", default: "all" },
},
});
if (
!values.revision ||
!values.artifact ||
!values.path ||
!values.output ||
!isAbsolute(values.path) ||
!isAbsolute(values.output) ||
!["complete", "summary"].includes(values.delivery) ||
!["entry", "entry-and-main", "entry-views"].includes(
values["native-question"],
) ||
!["inventory", "selected"].includes(values["javascript-question"]) ||
!["default", "selected"].includes(values.schemas) ||
!["all", "columns"].includes(values["sqlite-selection"]) ||
(values.artifact !== "qgis-world-map.gpkg" &&
values["sqlite-selection"] !== "all") ||
(values.artifact === "qgis-world-map.gpkg" &&
values.delivery !== "complete") ||
!["inventory", "identity"].includes(values["managed-question"]) ||
(!["sharex.dll", "sharex.helpers.dll"].includes(values.artifact) &&
values["managed-question"] !== "inventory") ||
(["sharex.dll", "sharex.helpers.dll"].includes(values.artifact) &&
values.delivery === "summary" &&
values["managed-question"] !== "identity") ||
(values["verify-retained"] &&
!["weth.hex", "uniswap-v3.factory.hex", "uniswap-v3.pool.hex"].includes(
values.artifact,
)) ||
(!NATIVE_ARTIFACTS.includes(values.artifact) &&
values["native-question"] !== "entry") ||
(values.artifact !== "jq" &&
values["native-question"] === "entry-and-main") ||
(values.artifact !== "obsidian.asar" &&
values["javascript-question"] !== "inventory")
)
throw new Error(
"Use --revision SHA --artifact ID --path ABS --output NEW_ABS_DIR [--runtime-root ABS] [--providers JSON] [--delivery complete|summary]",
);
const sha = (text) => createHash("sha256").update(text).digest("hex");
const fileSha = async (path) => {
const hash = createHash("sha256");
for await (const chunk of createReadStream(path)) hash.update(chunk);
return hash.digest("hex");
};
const corpus = JSON.parse(
await readFile(new URL("./corpus.json", import.meta.url), "utf8"),
);
const artifact = corpus.artifacts.find(({ id }) => id === values.artifact);
if (!artifact) throw new Error("Select an artifact from the pinned corpus");
const inputSha = await fileSha(values.path);
if (
artifact.sha256 !== inputSha ||
artifact.bytes !== (await stat(values.path)).size
)
throw new Error("Selected bytes differ from the pinned public corpus");
const selectedProviders = values.providers
? JSON.parse(await readFile(values.providers, "utf8"))
: {};
if (
selectedProviders === null ||
Array.isArray(selectedProviders) ||
typeof selectedProviders !== "object" ||
Object.values(selectedProviders).some((value) => typeof value !== "string")
)
throw new Error(
"--providers must contain an object of explicit string settings",
);
const providerPolicyText = await readFile(
new URL("./provider-environment.json", import.meta.url),
"utf8",
);
const providerPolicy = JSON.parse(providerPolicyText);
const undeclaredProviderKeys = Object.keys(process.env).filter(
(key) =>
(providerPolicy.namespace_prefixes.some((prefix) =>
key.startsWith(prefix),
) ||
providerPolicy.additional_keys.includes(key)) &&
!Object.hasOwn(selectedProviders, key),
);
if (undeclaredProviderKeys.length > 0)
throw new Error(
`Declare inherited provider settings explicitly in --providers: ${undeclaredProviderKeys.sort().join(", ")}. Values are not logged.`,
);
await mkdir(values.output, { recursive: false, mode: 0o700 });
const runtimeFiles = [];
const fingerprintTree = async (directory) => {
for (const entry of await readdir(directory, { withFileTypes: true })) {
const path = resolve(directory, entry.name);
if (entry.isDirectory()) await fingerprintTree(path);
else if (entry.isFile())
runtimeFiles.push({
path: path.slice(resolve(values["runtime-root"]).length + 1),
sha256: await fileSha(path),
});
else throw new Error("Runtime fingerprint does not follow symlinks");
}
};
await fingerprintTree(resolve(values["runtime-root"], "dist"));
await fingerprintTree(resolve(values["runtime-root"], "bridge"));
runtimeFiles.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
await writeFile(
resolve(values.output, "runtime-files.json"),
JSON.stringify(runtimeFiles),
);
const fingerprints = {
measure_source_sha256: await fileSha(fileURLToPath(import.meta.url)),
native_workflow_source_sha256: await fileSha(
fileURLToPath(new URL("./native-entry.mjs", import.meta.url)),
),
runtime_files_sha256: sha(JSON.stringify(runtimeFiles)),
runtime_dispatcher_sha256: await fileSha(
resolve(values["runtime-root"], "scripts/rea.mjs"),
),
package_lock_sha256: await fileSha(
resolve(values["runtime-root"], "package-lock.json"),
),
};
const clientVersion = JSON.parse(
await readFile(
resolve(root, "node_modules/@modelcontextprotocol/client/package.json"),
"utf8",
),
).version;
const serverVersion = JSON.parse(
await readFile(
resolve(
values["runtime-root"],
"node_modules/@modelcontextprotocol/server/package.json",
),
"utf8",
),
).version;
class ToolFailure extends Error {
constructor(value) {
super("REA returned a tool error");
this.value = value;
}
}
const client = new Client({ name: "rea-analysis-efficiency", version: "1" });
const transport = new StdioClientTransport({
command: process.execPath,
args: [resolve(values["runtime-root"], "scripts/rea.mjs"), "mcp"],
env: { ...process.env, ...selectedProviders },
stderr: "pipe",
});
const diagnostics = [];
const calls = [];
const catalogDefinitions = new Map();
const pendingRpc = new Map();
let activeCall;
const started = performance.now();
let connectedMs, catalogMs, catalogBytes, catalogInputBytes, result, failure;
const decode = (reply) =>
reply.structuredContent ??
JSON.parse(
reply.content.find((item) => item.type === "text")?.text ?? "null",
);
const call = async (name, arguments_) => {
const toolDefinition =
values.schemas === "selected" ? catalogDefinitions.get(name) : undefined;
if (values.schemas === "selected" && toolDefinition === undefined)
throw new Error(`No live advertised definition for ${name}`);
const began = performance.now();
const progress = [];
const rpc = {};
activeCall = { began, rpc };
try {
const reply = await client.callTool(
{ name, arguments: arguments_ },
{
...(toolDefinition === undefined ? {} : { toolDefinition }),
timeout: 600_000,
onprogress: (update) =>
progress.push({ elapsed_ms: performance.now() - began, ...update }),
},
);
const elapsedMs = performance.now() - began;
const encodingBegan = performance.now();
const text = JSON.stringify(reply);
const value = decode(reply);
calls.push({
name,
arguments: arguments_,
elapsed_ms: elapsedMs,
client_before_send_ms: rpc.sent === undefined ? null : rpc.sent - began,
transport_roundtrip_ms:
rpc.received === undefined || rpc.sent === undefined
? null
: rpc.received - rpc.sent,
client_after_receive_ms:
rpc.received === undefined ? null : began + elapsedMs - rpc.received,
client_result_json_utf8_bytes: Buffer.byteLength(text),
runner_encoding_ms: performance.now() - encodingBegan,
producer_evidence_id: value?.evidence_id ?? null,
is_error: reply.isError === true,
progress,
});
await writeFile(resolve(values.output, `call-${calls.length}.json`), text);
if (reply.isError) throw new ToolFailure(value);
return value;
} catch (error) {
if (calls.at(-1)?.name !== name || calls.at(-1)?.arguments !== arguments_)
calls.push({
name,
arguments: arguments_,
elapsed_ms: performance.now() - began,
failure: String(error),
progress,
});
throw error;
} finally {
activeCall = undefined;
for (const [id, pending] of pendingRpc)
if (pending.rpc === rpc) pendingRpc.delete(id);
}
};
const normalized = (value) => value.normalized_result;
const targetSha = (value) => value.subject?.digest.sha256;
const inventoryPaths = ["package.json", "main.js", "preload.js"];
const unique = (values) => [...new Set(values)].sort();
const inspectManagedTarget = async () => {
const arguments_ = {
path: values.path,
...(values.delivery === "summary" ? { detail: "summary" } : {}),
};
const definition = catalogDefinitions.get("inspect_managed_artifact");
if (definition === undefined)
throw new Error("Managed inspection is not advertised");
const accepted = new Ajv2020({
strict: false,
validateFormats: false,
}).compile(definition.inputSchema)(arguments_);
if (!accepted)
throw new Error(
"Selected managed delivery is not advertised by this runtime",
);
const info = await call("inspect_managed_artifact", arguments_);
const boundaries = await call("inspect_managed_native_boundaries", {
path: values.path,
});
const received = normalized(info);
const report = received.kind === "summary" ? received.summary : received;
let artifact = report;
if (values["managed-question"] === "identity") {
const {
references,
resources,
attributes,
reported_counts,
identity_scope: _scope,
...identity
} = report;
artifact = {
...identity,
reported_counts: reported_counts ?? {
references: references.length,
resources: resources.length,
attributes: attributes.length,
},
};
}
return {
artifact_sha256: targetSha(info),
artifact,
boundaries: normalized(boundaries),
evidence_ids: [
info.evidence_id,
...(received.kind === "summary" ? [received.parent_evidence_id] : []),
boundaries.evidence_id,
],
};
};
/** The same counts/export question for each pinned shipped WASM module. */
const inspectWasmTarget = async () => {
let info;
let recovery = null;
const arguments_ = {
path: values.path,
glue_paths: [],
candidate_paths: [],
};
const definition = catalogDefinitions.get("inspect_wasm_artifact");
if (!definition) throw new Error("Missing advertised WASM definition");
// Validate the real advertised dialect, including SDK-generated local refs.
const supportsSummary = new Ajv2020({
strict: false,
validateFormats: false,
}).compile(definition.inputSchema)({ ...arguments_, detail: "summary" });
try {
info = await call("inspect_wasm_artifact", {
...arguments_,
...(values.delivery === "summary" && supportsSummary
? { detail: "summary" }
: {}),
});
} catch (error) {
const reference =
error instanceof ToolFailure &&
error.value?.error?.code === "resource_constraint"
? error.value.error.details?.reported_limits?.evidence_reference
: undefined;
if (reference?.kind !== "retained-evidence") throw error;
if (values.delivery === "summary") {
info = await call("inspect_analysis_view", {
source: reference,
view: { kind: "summary" },
});
recovery =
"existing completed producer reference read through typed WASM views";
} else {
const path = resolve(values.output, "retained-evidence.json");
await call("export_evidence_bundle", { path });
const bundle = JSON.parse(await readFile(path, "utf8"));
const record = bundle.records.find(
(row) => row.evidence_id === reference.evidence_id,
);
const { parseEvidence } = await import(
pathToFileURL(
resolve(values["runtime-root"], "dist/domain/evidence.js"),
).href
);
info = parseEvidence(record);
recovery =
"complete producer Evidence exported after an observed transport constraint";
}
}
const n = normalized(info);
if (n.kind === "summary") {
const summary = n.summary;
const exportsEvidence = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: n.parent_evidence_id },
view: { kind: "wasm", facet: "exports", offset: 0, limit: 4 },
});
return {
artifact_sha256: targetSha(info),
validation: summary.validation,
section_count: summary.available_counts.sections,
import_count: summary.available_counts.imports,
export_count: summary.available_counts.exports,
exports_first4: normalized(exportsEvidence).item,
wat_sha256: summary.wat.sha256,
wat_code_units: summary.wat.code_units,
tool_profile: summary.tool_profile,
runtime_execution: summary.runtime_execution,
network_fetch: summary.network_fetch,
evidence_ids: [
n.parent_evidence_id,
info.evidence_id,
exportsEvidence.evidence_id,
],
source_evidence_id: n.parent_evidence_id,
recovery,
};
}
return {
artifact_sha256: targetSha(info),
validation: n.validation,
section_count: n.sections.length,
import_count: n.imports.length,
export_count: n.exports.length,
exports_first4: n.exports.slice(0, 4),
wat_sha256: n.wat.sha256,
wat_code_units: n.wat.text.length,
tool_profile: n.tool_profile,
runtime_execution: n.runtime_execution,
network_fetch: n.network_fetch,
evidence_ids: [info.evidence_id],
source_evidence_id: info.evidence_id,
recovery,
};
};
/** Identical interface facts for complete delivery, selected summary or old-server fallback. */
const inspectEvmTarget = async () => {
const definition = catalogDefinitions.get("inspect_evm_interface");
if (!definition) throw new Error("Missing advertised EVM definition");
const input = { path: values.path, encoding: "hex" };
const supportsSummary = new Ajv2020({
strict: false,
validateFormats: false,
}).compile(definition.inputSchema)({ ...input, detail: "summary" });
const info = await call("inspect_evm_interface", {
...input,
...(values.delivery === "summary" && supportsSummary
? { detail: "summary" }
: {}),
});
const result = normalized(info);
const projected = result.kind === "summary";
const n = projected ? result.summary : result;
const references = [info.evidence_id];
if (projected) {
if (
result.parent_operation !== "inspect_evm_interface" ||
result.parent_evidence_id === info.evidence_id ||
!info.evidence_links.includes(result.parent_evidence_id) ||
"hex" in n.bytecode ||
"stdout" in n.diagnostics
)
throw new Error(
"EVM summary changed source provenance or precise delivery",
);
references.push(result.parent_evidence_id);
}
if (
n.evidence_kind !== "inferred" ||
n.artifact.path !== values.path ||
n.artifact.sha256 !== inputSha ||
n.artifact.bytes !== artifact.bytes ||
n.artifact.encoding !== "hex" ||
n.discovery_completeness !== "unknown" ||
n.runtime_execution !== "not-performed" ||
["kind", "hardfork", "deployment_authenticity"].some(
(key) => n.bytecode[key] !== "unknown",
) ||
(artifact.decoded_sha256 !== undefined &&
n.bytecode.sha256 !== artifact.decoded_sha256) ||
(artifact.decoded_bytes !== undefined &&
n.bytecode.bytes !== artifact.decoded_bytes)
)
throw new Error("EVM interface identity or uncertainty changed");
if (values["verify-retained"]) {
if (!projected)
throw new Error(
"Retained verification requires supported selected summary",
);
const bundle = (await call("get_evidence_bundle", {})).result;
const parent = bundle.records.find(
(record) => record.evidence_id === result.parent_evidence_id,
);
if (
!parent ||
parent.operation !== "inspect_evm_interface" ||
parent.subject?.digest.sha256 !== inputSha ||
parent.parameters.path !== values.path ||
parent.parameters.encoding !== "hex" ||
"detail" in parent.parameters
)
throw new Error(
"Complete original EVM source was not retained unchanged",
);
const original = normalized(parent);
const { hex: _hex, ...identity } = original.bytecode;
const { stdout, ...diagnostics } = original.diagnostics;
const expected = {
...original,
bytecode: identity,
diagnostics: { ...diagnostics, stdout_code_units: stdout.length },
};
if (!isDeepStrictEqual(expected, n))
throw new Error("EVM summary changed selected original facts");
for (const [facet, item] of [
["functions", original.functions.slice(0, 64)],
[
"bytecode_hex",
{ text: original.bytecode.hex.slice(0, 64), unit: "utf16-code-units" },
],
]) {
const page = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: parent.evidence_id },
view: { kind: "evm", facet, offset: 0, limit: 64 },
});
const v = normalized(page);
if (
!isDeepStrictEqual(v.item, item) ||
v.parent_evidence_id !== parent.evidence_id ||
v.artifact.sha256 !== inputSha
)
throw new Error("EVM retained read changed source facts or identity");
if (references.includes(page.evidence_id))
throw new Error("EVM retained read reused an Evidence identity");
references.push(page.evidence_id);
}
}
const { hex: _hex, ...bytecode } = n.bytecode;
return {
artifact_sha256: targetSha(info),
artifact: n.artifact,
bytecode,
functions: n.functions,
discovery_completeness: n.discovery_completeness,
runtime_execution: n.runtime_execution,
limitations: n.limitations,
evidence_ids: references,
};
};
const workflows = {
"qgis-world-map.gpkg": async () => {
const columns = ["fid", "NAME", "ISO_A3"];
const input = {
path: values.path,
table: "countries",
row_limit: 1,
...(values["sqlite-selection"] === "columns" ? { columns } : {}),
};
const definition = catalogDefinitions.get("inspect_sqlite_database");
if (
definition === undefined ||
!new Ajv2020({ strict: false, validateFormats: false }).validate(
definition.inputSchema,
input,
)
)
throw new Error(
"Selected SQLite request is not advertised by this runtime",
);
const inspected = await call("inspect_sqlite_database", input);
const report = normalized(inspected);
if (report.rows === null || report.rows.table !== "countries")
throw new Error("Runtime returned no selected country sample");
const indexes = columns.map((column) => {
const index = report.rows.columns.indexOf(column);
if (index < 0)
throw new Error(`Missing requested SQLite column ${column}`);
return index;
});
return {
artifact_sha256: targetSha(inspected),
artifact: report.artifact,
wal: report.wal,
engine: report.engine,
database_encoding: report.database_encoding,
schema: report.schema,
rows: {
...report.rows,
columns,
values: report.rows.values.map((row) =>
indexes.map((index) => row[index]),
),
},
producer_limitations: report.limitations,
limitations: inspected.limitations,
evidence_ids: [inspected.evidence_id],
};
},
"obsidian.asar": async () => {
if (values["javascript-question"] === "selected") {
const inspected = await call("analyze_javascript_application", {
input_path: values.path,
source_paths: ["package.json", "main.js"],
detail: "summary",
});
const receipt = normalized(inspected);
const parent = receipt.parent_evidence_id;
const evidenceIds = [parent, inspected.evidence_id];
const modules = [];
let offset = 0;
do {
const page = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: parent },
view: { kind: "page", collection: "modules", offset, limit: 64 },
});
evidenceIds.push(page.evidence_id);
const view = normalized(page);
for (const module of view.items.filter(
(row) => row.path === "main.js",
)) {
const selected = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: parent },
view: {
kind: "item",
collection: "modules",
selector: { node_id: module.node_id },
},
});
evidenceIds.push(selected.evidence_id);
modules.push(normalized(selected).item);
}
if (view.coverage.exhausted) break;
if (
view.coverage.next_offset === null ||
view.coverage.next_offset <= offset
)
throw new Error("Module page did not advance");
offset = view.coverage.next_offset;
} while (true);
return {
artifact_sha256: targetSha(inspected),
...receipt.summary,
modules,
limitations: receipt.limitations,
evidence_ids: evidenceIds,
};
}
await call("open_binary", { path: values.path });
try {
const inspected = await call(
"inspect_artifact",
values.delivery === "summary" ? { detail: "summary" } : {},
);
if (values.delivery === "summary") {
const view = normalized(inspected);
const summary = view.summary;
if (!summary.source_complete || !summary.inspection)
throw new Error(
"Expected a complete inventory with inspection coverage",
);
const parent = view.parent_evidence_id;
const selected = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: parent },
view: {
kind: "inventory",
collection: "occurrences",
logical_paths: inventoryPaths,
offset: 0,
limit: 64,
},
});
const contradictions = [];
let offset = 0;
while (offset < summary.available_counts.integrity_contradictions) {
const page = normalized(
await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: parent },
view: {
kind: "inventory",
collection: "integrity_contradictions",
offset,
limit: 64,
},
}),
);
contradictions.push(...page.items);
if (page.coverage.exhausted) break;
if (
page.coverage.next_offset === null ||
page.coverage.next_offset <= offset
)
throw new Error("Inventory page did not advance");
offset = page.coverage.next_offset;
}
return {
artifact_sha256: targetSha(inspected),
manifest: summary.manifest,
source_complete: summary.source_complete,
entry_kind_counts: summary.observed_entry_kind_counts,
requested_paths: normalized(selected).items,
inventory_evidence_ids: summary.inventory_evidence_ids,
integrity_contradictions: contradictions,
coverage: summary.inspection.coverage,
unexplored_branches: summary.inspection.unexplored_branches,
limitations: view.limitations,
evidence_ids: [inspected.evidence_id, selected.evidence_id],
};
}
const inspection = normalized(inspected);
const inventory = inspection.substeps[0].evidence;
const graph = normalized(inventory);
const counts = { file: 0, directory: 0, symlink: 0, slice: 0 };
for (const row of graph.occurrences) counts[row.entry_kind]++;
const { parseArtifactInventoryEvidence } = await import(
pathToFileURL(
resolve(
values["runtime-root"],
"dist/domain/artifactInventoryEvidence.js",
),
).href
);
const checked = parseArtifactInventoryEvidence(inventory);
return {
artifact_sha256: targetSha(inspected),
manifest: graph.manifest,
source_complete: checked.inventory.complete,
entry_kind_counts: counts,
requested_paths: graph.occurrences.filter((row) =>
inventoryPaths.includes(row.logical_path),
),
inventory_evidence_ids: [inventory.evidence_id],
integrity_contradictions: graph.integrity_contradictions,
coverage: inspection.coverage,
unexplored_branches: inspection.unexplored_branches,
evidence_ids: [inspected.evidence_id, inventory.evidence_id],
limitations: unique([
...inspected.limitations,
...inspection.limitations,
...inventory.limitations,
]),
};
} finally {
await call("close_binary", {});
}
},
"newpipe.apk": async () => {
const packageInput = {
path: values.path,
...(values.delivery === "summary" ? { detail: "summary" } : {}),
};
const definition = catalogDefinitions.get("inspect_android_package");
if (
definition === undefined ||
!new Ajv2020({ strict: false, validateFormats: false }).validate(
definition.inputSchema,
packageInput,
)
)
throw new Error(
"Selected Android delivery is not advertised by this runtime",
);
const pkg = await call("inspect_android_package", packageInput);
const result = normalized(pkg);
const report = values.delivery === "summary" ? result.summary : result;
if (
values.delivery === "summary" &&
(result.kind !== "summary" ||
result.parent_operation !== "inspect_android_package")
)
throw new Error("Runtime returned no retained Android package summary");
const { manifest, ...declarations } = report;
const manifestObservation =
values.delivery === "summary"
? manifest
: {
status: manifest.status,
reported_total_bytes: manifest.reported_total_bytes,
text_code_units: manifest.text.length,
text_included: false,
};
const found = await call("search_android_classes", {
path: values.path,
query: "MainActivity",
});
const cls = await call("inspect_android_class", {
path: values.path,
class_name: "org.schabi.newpipe.MainActivity",
});
return {
artifact_sha256: targetSha(pkg),
package_name: report.package_name,
version_name: report.version_name,
version_code: report.version_code,
package_declarations: declarations,
manifest_observation: manifestObservation,
package_limitations: pkg.limitations,
matches: normalized(found).matches,
coverage: normalized(found).coverage,
onCreate: normalized(cls).methods.filter(
(row) => row.name === "onCreate",
),
evidence_ids: [pkg.evidence_id, found.evidence_id, cls.evidence_id],
};
},
"sharex.dll": inspectManagedTarget,
"sharex.helpers.dll": inspectManagedTarget,
"localsend-arm64.apk": async () => {
const input = {
path: values.path,
...(values.delivery === "summary" ? { detail: "summary" } : {}),
};
const definition = catalogDefinitions.get("inspect_dart_aot");
if (
definition === undefined ||
!new Ajv2020({ strict: false, validateFormats: false }).validate(
definition.inputSchema,
input,
)
)
throw new Error(
"Selected Dart AOT delivery is not advertised by this runtime",
);
const inspected = await call("inspect_dart_aot", input);
const result = normalized(inspected);
if (
values.delivery === "summary" &&
(result.kind !== "summary" ||
result.parent_operation !== "inspect_dart_aot")
)
throw new Error("Runtime returned no retained Dart AOT summary");
const report = values.delivery === "summary" ? result.summary : result;
const { package_uris, dart_uris, class_like_tokens, ...pool } =
report.string_pool;
return {
artifact_sha256: targetSha(inspected),
target: report.target,
abi: report.abi,
libapp: report.libapp,
string_pool:
values.delivery === "summary"
? pool
: {
...pool,
returned_counts: {
package_uris: package_uris.length,
dart_uris: dart_uris.length,
class_like_tokens: class_like_tokens.length,
},
},
coverage: report.coverage,
limitations: inspected.limitations,
evidence_ids: [inspected.evidence_id],
};
},
"openwrt.bin": async () => {
const info = await call("inspect_firmware_regions", { path: values.path });
return {
artifact_sha256: targetSha(info),
result: normalized(info),
evidence_ids: [info.evidence_id],
};
},
"sqlite.wasm": inspectWasmTarget,
"vscode.tree-sitter.wasm": inspectWasmTarget,
"vscode.tree-sitter-css.wasm": inspectWasmTarget,
"weth.hex": inspectEvmTarget,
"uniswap-v3.factory.hex": inspectEvmTarget,
"uniswap-v3.pool.hex": inspectEvmTarget,
...Object.fromEntries(
NATIVE_ARTIFACTS.map((artifact) => [
artifact,
async () =>
measureNativeEntry({
seed: await nativeEntrySeed(artifact, values.path),
values,
call,
inputSha,
ToolFailure,
}),
]),
),
};
try {
await client.connect(transport);
connectedMs = performance.now() - started;
// Observe the public Transport seam without replacing its codec or lifecycle.
// These intervals separate SDK work from the transport/server roundtrip;
// the roundtrip still includes server work, framing, IO and client parsing.
const send = transport.send.bind(transport);
transport.send = (message, options) => {
if (message.method === "tools/call" && activeCall !== undefined) {
activeCall.rpc.sent = performance.now();
pendingRpc.set(message.id, activeCall);
}
return send(message, options);
};
const receive = transport.onmessage;
transport.onmessage = (message, extra) => {
if ("result" in message || "error" in message) {
const pending = pendingRpc.get(message.id);
if (pending !== undefined) {
pending.rpc.received = performance.now();
pendingRpc.delete(message.id);
}
}
receive?.(message, extra);
};
transport.stderr?.on("data", (chunk) => diagnostics.push(chunk.toString()));
const catalogStarted = performance.now();
const tools = [];
let cursor;
do {
const page = await client.listTools(cursor === undefined ? {} : { cursor });
tools.push(...page.tools);
cursor = page.nextCursor;
} while (cursor !== undefined);
catalogMs = performance.now() - catalogStarted;
for (const tool of tools) {
if (catalogDefinitions.has(tool.name))
throw new Error("Duplicate advertised tool name");
catalogDefinitions.set(tool.name, tool);
}
catalogBytes = Buffer.byteLength(JSON.stringify(tools));
catalogInputBytes = Buffer.byteLength(
JSON.stringify(
tools.map(({ name, description, inputSchema }) => ({
name,
description,
inputSchema,
})),
),
);
await writeFile(
resolve(values.output, "catalog.json"),
JSON.stringify(tools),
);
const workflow = workflows[values.artifact];
if (!workflow) throw new Error("No pinned question for selected artifact");
result = await workflow();
if (result.artifact_sha256 !== inputSha)
throw new Error("Producer target digest differs from selected bytes");
} catch (error) {
failure = String(error);
} finally {
try {
await client.close();
} catch (error) {
failure = `${failure ?? ""} cleanup: ${String(error)}`;
}
}
await writeFile(
resolve(values.output, "diagnostics.log"),
diagnostics.join(""),
);
const finalInputSha = await fileSha(values.path);
if (finalInputSha !== inputSha)
failure = `${failure ?? ""} Selected artifact bytes changed during the workflow`;
if (result)
await writeFile(
resolve(values.output, "answer.json"),
JSON.stringify(result),
);
const report = {
revision: values.revision,
runtime_root: values["runtime-root"],
artifact: values.artifact,
artifact_sha256: inputSha,
artifact_sha256_after: finalInputSha,
delivery: values.delivery,
sdk_schema_mode: values.schemas,
retained_verification: values["verify-retained"],
native_question: NATIVE_ARTIFACTS.includes(values.artifact)
? values["native-question"]
: null,
javascript_question:
values.artifact === "obsidian.asar" ? values["javascript-question"] : null,
managed_question: ["sharex.dll", "sharex.helpers.dll"].includes(
values.artifact,
)
? values["managed-question"]
: null,
sqlite_selection:
values.artifact === "qgis-world-map.gpkg"
? values["sqlite-selection"]
: null,
provider_settings_sha256: sha(JSON.stringify(selectedProviders)),
provider_search_path_sha256: sha(
selectedProviders.PATH ?? process.env.PATH ?? "",
),
provider_environment_policy_sha256: sha(providerPolicyText),
...fingerprints,
node_version: process.version,
sdk_client_version: clientVersion,
sdk_server_version: serverVersion,
platform: process.platform,
architecture: process.arch,
connected_ms: connectedMs,
catalog_ms: catalogMs,
catalog_json_utf8_bytes: catalogBytes,
catalog_input_definition_utf8_bytes: catalogInputBytes,
elapsed_ms: performance.now() - started,
calls,
failure: failure ?? null,
measurement_scope:
"Public SDK Transport timestamps split client work from the transport/server roundtrip; parsed result JSON bytes are not raw wire bytes; runner encoding and writes are outside each call; engine-stage durations and independent producer truth are not inferred",
};
await writeFile(
resolve(values.output, "summary.json"),
JSON.stringify(report, null, 2),
);
process.stdout.write(
JSON.stringify({
artifact: values.artifact,
delivery: values.delivery,
elapsed_ms: report.elapsed_ms,
failure: failure?.slice(0, 800) ?? null,
}) + "\n",
);
if (failure) process.exitCode = 1;
@@ -1,209 +0,0 @@
# Observe the client boundary before claiming token savings
Continues [#2016](https://github.com/morluto/rea/issues/2016) after the managed
summary [PR #2413](https://github.com/morluto/rea/pull/2413) merged as
`82cfcee19f18b0eeae9a330ba04e0411cdf85225`. That opt-in view has verified smaller
delivery and complete-default migration, while its original real-model cohort
does not establish token savings. This follow-up measures why raw reply bytes
and aggregate model usage cannot be treated as interchangeable observations.
## Concrete diagnostic observation
An individual real Codex CLI 0.161.0 control uses frozen runtime
`ae8051302b5834322fa00cfa31c968ae74ab6ed9`, the unchanged ShareX identity question,
requested `gpt-5.6-terra` high and the same two enabled REA tools. A private
diagnostic copy removes the original runner's explicit `--ephemeral` flag.
Authentication/profile cleanup still runs; only selected tool/usage items are
retained after filtering the owned rollout. Its source rollout SHA-256 is
`d4df41d6187880d177f00b7533d85ad032c9c4ec502a39e7d5a566180e10461b` and the retained
filtered-item SHA-256 is
`0d5b4fb67c5674d1ba14ac32ae37e9a72b0368f4d9f5f9f81eb4d13193cda260`.
The original whole-copy is removed; account metadata, world state, messages and
internal passthrough are not retained in the filtered receipt.
Despite the requested `direct` configuration label, the observed client uses
three JavaScript `exec` calls. First it filters `ALL_TOOLS` with a broad
`/REA|reverse|artifact|managed|assembly|metadata/i` expression and prints matching
metadata. The client reports truncation of a 164,005-token original output.
This is the client's output measurement, not billed input or a complete inventory.
Next it invokes complete managed inspection but selects requested normalized
identity/classification fields before printing. Finally it invokes native-boundary
inspection and prints selected fields. The actual original complete MCP replies
remain available in the separate public-event transcript.
The persisted custom-tool output values are 41,704 / 2,154 / 13,489 UTF-8 bytes.
These are the serialized recorded output **values**, not raw wire bytes or exact
submitted model requests. The trace reports four per-response usage observations:
| Response | Input | Cached input | Output |
| -------- | -----: | -----------: | -----: |
| 1 | 10,400 | 0 | 132 |
| 2 | 19,992 | 9,984 | 456 |
| 3 | 21,242 | 19,200 | 251 |
| 4 | 24,799 | 20,224 | 1,535 |
Their totals match public turn usage: 76,433 input, 49,408 cached, 27,025 uncached
and 2,374 output, with 61.436 seconds observed wall time. Two MCP calls alone do
not describe the client's discovery/execution rounds. This proves the observed
control can project a complete result before printing it; it does not establish
that every earlier control/candidate did the same, or attribute every token
difference to discovery. The earlier `direct` label specifies requested client
configuration, not a verified absence of an executor.
Initial transcript-capture attempts retained empty source lists because the
original runner intentionally passed `--ephemeral`. A first private flag-removal
edit missed its newline and failed; that candidate remains an unsuccessful
capture attempt. The later corrected control is an individual diagnostic,
not a comparable pair with that candidate. Other exploratory aggregates remain
private and are not silently folded into the original four-trial cohort.
## Reproducible optional capture
`agent-trial.py --capture-tool-context` omits `--ephemeral` only for that explicitly
selected temporary trial. Its default is unchanged. The profile still disappears
in `finally`, including when capture fails. The capture reads only its owned
`sessions/*.jsonl` records, rejects symlink sources, and retains:
- Custom/function tool calls and replies, preserving call IDs and exact values.
- Per-response token counts and cumulative counts, with original response IDs.
- Client token-count events, retaining explicit unknown `info: null`.
It excludes session/account metadata, world state, user/developer messages,
encrypted reasoning, internal passthrough and unknown nested usage fields. It
does not copy authentication, configuration or the ambient environment. Receipts
record source/retained digests, event counts, malformed-line failures and missing
rollouts as unavailable. Capture is an observation of persisted client items,
not proof of the exact request accepted by a remote model service.
Run the same frozen runtime, question, tool selection and capture mode on both
sides. Preserve source/settings hashes and separate requested versus observed
behavior. Use the existing resource wrapper with unchanged one CPU, 4 GiB hard
memory, 3 GiB early-stop, no swap and task/host safeguards. Final physical counters
remain unknown when transient cgroups disappear; this instrumentation does not
repair that measurement limitation.
The focused Python tests run through the existing CI `test:python` gate.
They cover account/ambient exclusion while preserving caller data, malformed and
missing records, foreign symlinks, and capture failure without copied-credential
leakage. The cleanup test simulates a CLI and establishes only cleanup semantics;
it is not real-model/provider evidence.
## An explicit discovery-guidance experiment
`--guide-enabled-tools` is another opt-in experiment flag. It requires a nonempty
`--enabled-tools` list and adds the exact corresponding `mcp__rea__...` function
names to the temporary developer instructions, requesting only exact-name
metadata discovery. It preserves the analyst question, operation order, tool
selection and provider inputs. The default instruction is unchanged. Missing or
invalid selected tools fail before creating an output/profile. The test gate
also verifies the new prerequisite without acquiring a profile.
Compare guided and unguided runs on the **same** frozen REA runtime with matching
capture mode and requested facts. A smaller discovery response or additional
hint is not itself a task/token success: grade answers, count all response usage,
preserve failed/truncated runs and repeat both orders before recommending this
guidance. This is a caller-side experiment, not a new REA tool or provider preset.
## First committed capture pair
Checkpoint `9ebdcc458c399b9bdecaaca2ef47422888231181` runs the unchanged question
against frozen control `ae8051302b5834322fa00cfa31c968ae74ab6ed9` and candidate
`8bc1601ca51e417ca472d90ea0367e9418a1a0f2`, both with capture enabled and no tool
guidance. Both captures succeed with 10 retained events, unchanged source bytes,
removed profiles, two successful MCP calls and passing selected factual checks.
Full grader gates remain false because final physical resource counters are
unavailable; factual subsets do not override that limitation.
| Side | Input | Cached | Uncached | Output | Wall seconds |
| ----------------- | -----: | -----: | -------: | -----: | -----------: |
| Complete control | 52,656 | 27,136 | 25,520 | 2,015 | 57.736 |
| Summary candidate | 56,655 | 29,184 | 27,471 | 1,534 | 55.055 |
Both clients make two executor calls and three response-usage observations.
First they print broad discovered metadata, with truncation. Then each executor
sequentially performs both MCP operations, preserving selected-target dependency
order. The control prints a 2,086-byte output value; the candidate prints 22,770
bytes. Their discovery output values are 41,723 and 41,675 bytes. These are
recorded serialized values and remain distinct from raw MCP envelopes, billed
tokens and exact submitted requests. Both requested modes are `direct`; the
actual executor use is separately observed.
The candidate's smaller raw metadata reply does not result in a smaller printed
client value in this pair. Candidate input/uncached tokens remain higher. The
observed projection and round counts are useful constraints for the next
experiment; this one pair does not attribute all usage differences to either
formatting or discovery, or establish a reliable speedup.
## Same-runtime guided discovery, repeated in both orders
Checkpoint `e20bd0e2a905f06bc8c56fe04b0e61f3da88636a` runs four actual Codex trials
in unguided/guided/guided/unguided order. All use the **same** frozen candidate
runtime, artifact, original question, requested model/reasoning, two selected
tools, provider settings and capture mode. Only the explicit discovery-guidance
treatment changes. Every trial selects artifact summary and makes the same two
successful MCP calls in dependency order; source bytes stay unchanged, captures
succeed and profiles are removed.
| Trial | Input | Cached | Uncached | Output | Seconds | Observed responses |
| ---------- | ------: | -----: | -------: | -----: | ------: | -----------------: |
| Unguided 1 | 77,251 | 50,432 | 26,819 | 1,931 | 62.066 | 4 |
| Guided 1 | 39,175 | 23,040 | 16,135 | 1,763 | 55.658 | 3 |
| Guided 2 | 58,336 | 38,144 | 20,192 | 1,626 | 50.685 | 4 |
| Unguided 2 | 103,301 | 72,704 | 30,597 | 1,983 | 60.336 | 5 |
Both guided discovery output values repeat at 12,336 bytes without truncation,
versus 41,709 bytes with truncation on both unguided trials. The recorded
executor/output usage explains observable discovery and round differences; it
does not certify exact remote request contents or attribute every token to the
hint. CPU samples are 6.303–6.554 seconds and peak family memory 684,519,424–
712,028,160 bytes, with no guard abort. Final resource counters remain unknown.
These samples do not establish a memory or CPU improvement.
Unguided 1 omits `classification.container` and fails the selected factual gate;
it is not a fully acceptable comparison answer. Guided 1 and Unguided 2 pass
that gate. Guided 2 initially fails exact coverage-object equality because it
adds `module_ref_count: 0` and `pinvoke_import_count: 0` to the explicitly named
native scope. Both numbers exactly match the producer's returned arrays. The
grader now explicitly verifies only these two known additional counts, including
integer type, while still requiring all original coverage facts. Unknown extra
claims, conflicting aliases, wrong counts, boolean/string counts and omitted
issues continue to fail. Source coverage remains unchanged; returned-row counts
do not establish global absence. Original failure receipts remain preserved;
the regrade separately records its new source hash. Guided 2 then passes selected
facts, but every **full** gate still fails unknown final physical resource checks.
The second comparison has two factually acceptable answers: observed guided input
falls about 43.5%, uncached input about 34.0%, and wall time about 16.0%. The first
comparison has an incomplete unguided answer and is reported without counting it
as equivalent completed work. Two trials per treatment on one question/application
remain a preliminary signal, not a general default recommendation. The hint stays
opt-in; wider questions/domains, count/coverage representation and client round
behavior need further verification before promoting it into general guidance.
## Real Android follow-up: the primary outcomes are mixed
Checkpoint `22834c7d73056e2480b426848f58c31af0c307bc` checks the pinned real
NewPipe 0.29.1 APK using actual configured JADX 0.7.1/Java, the original Android
question and the same frozen candidate runtime. First a fresh SDK workflow
validates three live advertised operations and produces the comparison facts:
package/version identity, every case-sensitive MainActivity match and all
reported onCreate entries, preserving signatures, overload indices and null DEX
descriptors. It takes 26.961 seconds; the owned scope samples 1,234,735,104 bytes.
Both subsequent actual Codex trials use the same three selected tool names,
capture mode, model/reasoning, question and provider settings. Only discovery
guidance changes. Each makes three successful MCP calls and five observed model
responses, passes selected facts against the fresh actual producer, preserves
source bytes and removes its temporary profile. No APK execution is requested.
| Trial | Input | Cached | Uncached | Output | Wall seconds | Sampled peak bytes |
| -------- | -----: | -----: | -------: | -----: | -----------: | -----------------: |
| Unguided | 99,913 | 80,640 | 19,273 | 1,527 | 66.797 | 1,405,829,120 |
| Guided | 89,220 | 62,464 | 26,756 | 2,142 | 76.936 | 1,345,576,960 |
Total input falls about 10.7%, but uncached input increases and wall time is
longer. One pair does not demonstrate improved Android performance or memory.
No guard abort occurs; final counters remain unknown and full resource gates
remain false. This second domain is a concrete counterexample to generalizing
the favorable managed comparison. Keep both flags optional and continue
task-specific experiments before changing installed/default agent guidance.
@@ -1,178 +0,0 @@
# Native PE and DOS entry-view checkpoint
Continuation of [#2016](https://github.com/morluto/rea/issues/2016) after
#2122 and #2193 merged. Real Ghidra observations and real Codex CLI answers
support the selected native facets on these shipped inputs. They do not justify
an automatic native summary policy: the four selected replies are larger than
the complete dossier for the small PE entry, and smaller for the DOS entry.
The initial complete analysis still runs and is delivered in both cases.
This checkpoint changes experiment scripts, corpus inputs and grading only.
Existing production CLI/MCP contracts, defaults and session behavior are unchanged.
## Inputs and runtime
Production runtime: main `10400fdb57e4226c5ce15af17968a664f35498ce`,
including the merged WASM summary work and subsequent main changes. Node
24.18.0/npm 11.16.0, locked dependencies, actual Ghidra 12.1.4 on Linux.
Default auto-analysis remains enabled, with a 768 MiB JVM ceiling and one
active processor. The whole process family uses the existing one-CPU,
4 GiB hard/3 GiB early-stop, no-swap, bounded-task resource scope.
| Shipped artifact | Selected bytes | SHA-256 | Static scope |
| ---------------------------------- | -------------: | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| ShareX 19.0.2 `ShareX.exe` | 198,656 | `46af1ccc514b395cb703633abb5a505a771942b7db9b1915f31aeea541b3685f` | Native PE32+ x86-64 component with no CLR directory; entry `0x1400125c0` derived from original image base/RVA |
| FreeDOS EDLIN 2.24 `BIN/EDLIN.EXE` | 31,492 | `96b2b6d543e2d8bdc83e313756444e103339eb5ee2c1229abe3607539b31ad6e` | Original UPX-compressed DOS MZ; admitted entry `0x10000`, independently verified static load image |
Acquisition URLs, archive sizes/digests and exact regular ZIP members are in
[corpus.json](corpus.json). EDLIN's package `APPINFO/EDLIN.LSM` reports its
version and UPX compression. No binary was executed, unpacked or committed.
The independent PE header does not establish Windows runtime behavior.
DOS load-image verification and unpacking-stub pseudocode do not recover the
editor's application logic or establish DOS execution. DOS COM is still untested.
The SDK and frozen model runtime share the exact `dist/` and `bridge/` file
table digest:
`e2b67eb0966072fd8b159edfab074cbaf1db9bfc0ac9c57d25ba1435cc0fdbcf`.
The model copy was independently checked against all 1,375 compiled files and
30 bridge files. Runtime copies and detailed receipts remain outside Git.
## Public SDK observations
The workflow opens the selected target with Ghidra, resolves the entry,
calls `analyze_function` once, reads retained procedure/pseudocode/callers/callees
facets, and closes the ephemeral session. DOS obtains its address from
`inspect_native_load_image` before resolving the procedure. Each facet is checked
against the complete producer facts, original parent ID, target digest and distinct
derived Evidence ID. The actual SDK validates named advertised output contracts.
| Entry | Complete dossier JSON bytes | Four facet replies combined | Workflow seconds | First provider query seconds | Last-observed family CPU seconds | Sampled family peak MiB |
| ------------ | --------------------------: | --------------------------: | ---------------: | ---------------------------: | -------------------------------: | ----------------------: |
| ShareX PE | 50,936 | 68,257 | 63.123 | 57.490 | 63.660 | 1,197.85 |
| EDLIN DOS MZ | 224,670 | 70,539 | 26.436 | 21.366 | 26.899 | 939.25 |
These are exploratory observations, not a paired implementation performance
cohort. JSON byte counts include the SDK tool-result representations, excluding
catalog discovery and wire framing; they are not model token counts. Four PE
facets cost about 34% more bytes than that dossier. The DOS facets cost about
69% fewer bytes **when reading already-retained Evidence**. Their first analysis
still returned the full dossier; summing both paths increases first-task traffic.
The first provider query includes the observable wait for the imported Program
and its analysis, not an independently measured engine-only stage.
The observed PE entry contains 18 analyzed bytes, zero recorded callers and two
resolved callees. Ghidra's terminal-call caveat remains explicit. The DOS entry
contains 53 analyzed bytes and zero recorded callers/callees; overlapping
instruction and abnormal stack-frame warnings remain in the pseudocode.
Neither zero count establishes absence of unresolved runtime calls.
An earlier PE probe completed production analysis and two facets, then failed
its harness assertion: a pseudocode page is `{text, unit}`, not a string. That
failed attempt remains archived and is excluded from successful workflow figures.
The corrected exploratory SDK driver fingerprints are
`4876c0ecaa84069ddc508e29649715c6c914bd3c4960a76fa9724b5992123699`
and native-helper `76023ad45cd1edab57dcd4a8ccf29a9b8a8378029ff2d9711ae35c73940e80d6`.
The published helper in `6d7f6885c` removes redundant scopes; replaying the actual
PE/DOS replies reproduces every answer field and the same 9/10 calls. Recorded
real jq entry and entry/main replies also preserve their selected facts, profile
and 4/12-call ordering. These replays are driver regression checks, not fresh
provider runs or timing measurements.
## Real Codex CLI observations
Three serial runs used Codex CLI 0.161.0, requested alias `gpt-5.6-terra`, high
reasoning, temporary isolated profiles and the frozen modified REA MCP runtime.
Resolved server-side model identity is not inferred. The same explicit seven-tool
subset was enabled: open, containing-procedure resolution, dossier, analysis view,
load image, retained Evidence discovery and close. This is not full-catalog tool
selection verification. Questions are [PE](questions/native-pe.txt) and
[DOS](questions/native-dos.txt).
| Trial | Total input | Cached input | Uncached input | Output | Seconds | Calls / failed |
| ----- | ----------: | -----------: | -------------: | -----: | ------: | -------------: |
| PE 1 | 451,337 | 399,616 | 51,721 | 3,820 | 130.073 | 12 / 2 |
| DOS 1 | 730,578 | 658,944 | 71,634 | 3,310 | 134.435 | 9 / 0 |
| PE 2 | 498,322 | 429,056 | 69,266 | 3,038 | 192.373 | 9 / 1 |
All three answers match the selected original digest, address, procedure
classification/signature/locals, inclusive body ranges, body byte count,
pseudocode prefix and relationship counts. Actual Evidence references were
observed in the responses; target bytes remained unchanged, close completed and
the copied profiles were removed. DOS additionally matches the verified load
status and every supplied load-image metadata field. Manual review preserves
static/packed-target and terminal-flow qualifications.
The first grader expected only particular nested JSON shapes. It rejected PE's
equivalent text-page object/inclusive-range label and could not grade DOS's
explicit `entry @ 0x10000` display. The updated grader compares exact source
values for those representations without parsing displays into lookup identities.
It still rejects wrong text units, returned lengths, body endpoints and missing
facts. Original answers and first grading attempts remain archived; regrading
does not repeat model calls or change their tokens/times.
The PE agent hit the advertised-but-unimplemented native summary recipe: both
trials attempted `view: {kind: "summary"}`; the first also tried the invalid
native facet `summary`. Those failed calls and all subsequent recovery/repeated
reads remain included. The public SDK independently reproduced `invalid_request`
for native summary on both inputs. This pre-existing contract-description mismatch
is recorded in `/tmp/rea-analysis-efficiency-bugs-20261012.md` for team repair,
as requested; this branch does not repair it.
Model sampled peaks were 1,318.74 / 1,017.70 / 1,234.92 MiB, with last-observed
family CPU 72.956 / 71.534 / 74.089 seconds. SDK/model scopes did not abort and
their last-observed limit-event counters were zero. Final cgroup counters remained
unavailable after scope teardown: the strict resource-qualified overall grades
remain unverified. The selected fact/lifecycle checks pass; no universal latency,
OOM absence or CPU/memory saving is inferred from these samples.
## Reproduction and next decision
Use the pinned toolchain and build the selected production revision. Keep its
runtime copy, matching dependencies, provider settings, binaries and receipts
outside the checkout, as described in [README.md](README.md).
```sh
python3 experiments/analysis-efficiency/resource-run.py -- \
node experiments/analysis-efficiency/measure.mjs \
--runtime-root /absolute/frozen-runtime --revision EXACT_PRODUCTION_SHA \
--artifact sharex.exe --path /absolute/ShareX.exe \
--providers /absolute/explicit-providers.json \
--native-question entry-views --schemas selected \
--output /absolute/new-native-measurement
```
For DOS select `--artifact freedos.edlin.exe` and the original extracted
`EDLIN.EXE`. `--native-question entry` retains the existing compact experimental
answer; `entry-views` performs additional verification reads and the explicit
summary refusal probe. It does not select summary delivery from `analyze_function`.
The helper fingerprint participates in comparison, and missing native helper
fingerprints are not treated as a comparable current driver.
The reviewed `entry-views` answer separates selected facet facts from run-specific
references: `evidence_ids.retained_views` retains each facet's original view and
parent ID, while `retained_views` holds its item, coverage, limitations and unknowns.
DOS load-image facts retain their source ID and must match the selected carrier
digest before their entry address can be used; a stale result closes the session
without querying a procedure.
Derived view IDs are checked against every prior producer reference as well as
other derived views. DOS model grades require the actual completed load-image
response and its reported source ID; status, digest, entry and supplied metadata
are checked against that observation. Missing, failed or unreferenced responses
cannot establish load-image verification.
The comparator preserves both runs' reference maps and compares the facts. Existing
`entry`/`entry-and-main` answers keep their ID arrays. Historical SDK receipts above
retain their original pre-review representation; no replies or measurements were
rewritten, and no provider/model runs were repeated for this representation fix.
Relevant validation includes the real workflows above, recorded-reply regression,
grader negative probes, JavaScript/Python syntax, formatting/diff checks and
`npm run check:fast`. The cold type/lint gate passed in 112.602 seconds with
sampled peak 3,220,914,176 bytes and five last-observed `memory.high` events;
this gate is not a performance-qualified experiment. Unrelated domain suites,
packaging and earlier model cohorts were not rerun for this experiment-only change.
The next useful comparison is question-specific native primitives versus a
complete dossier, with identical requested facts and actual model trials.
Larger PE functions and another unpacked DOS/COM application can extend the
coverage progressively. Preserve existing complete defaults and solve the
summary-description bug separately before recommending a native summary route.
@@ -1,272 +0,0 @@
import { open, readFile } from "node:fs/promises";
import { isDeepStrictEqual } from "node:util";
export const NATIVE_ARTIFACTS = ["jq", "sharex.exe", "freedos.edlin.exe"];
const normalized = (value) => value.normalized_result;
const retainedEntryViews = async (
call,
info,
inputSha,
ToolFailure,
sourceEvidenceIds,
) => {
const n = normalized(info);
const retainedViews = [];
const retainedViewEvidence = [];
const observedEvidenceIds = new Set([info.evidence_id, ...sourceEvidenceIds]);
let nativeSummaryOutcome, summaryEvidenceId;
for (const facet of ["procedure", "pseudocode", "callers", "callees"]) {
const selected = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: info.evidence_id },
view: {
kind: "native",
facet,
offset: 0,
limit: facet === "pseudocode" ? 512 : 64,
},
});
const view = normalized(selected);
if (observedEvidenceIds.has(selected.evidence_id))
throw new Error("Retained native view reused an Evidence identity");
const expected =
facet === "procedure"
? n.procedure
: facet === "pseudocode"
? { text: n.pseudocode.slice(0, 512), unit: "utf16-code-units" }
: n[facet].slice(0, 64);
if (
!isDeepStrictEqual(view.item, expected) ||
view.parent_evidence_id !== info.evidence_id ||
view.artifact.sha256 !== inputSha
)
throw new Error(
"Retained native view changed the selected source facts or identity",
);
observedEvidenceIds.add(selected.evidence_id);
retainedViews.push({
facet,
item: view.item,
coverage: view.coverage,
limitations: view.limitations,
unknowns: view.unknowns,
});
retainedViewEvidence.push({
facet,
evidence_id: selected.evidence_id,
parent_evidence_id: view.parent_evidence_id,
});
}
// Exercise the advertised summary recipe separately. A known refusal
// is recorded as such; it does not validate a nonexistent capability.
try {
const summary = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: info.evidence_id },
view: { kind: "summary" },
});
if (observedEvidenceIds.has(summary.evidence_id))
throw new Error("Native summary reused an Evidence identity");
nativeSummaryOutcome = { status: "supported" };
summaryEvidenceId = summary.evidence_id;
} catch (error) {
if (
!(error instanceof ToolFailure) ||
error.value?.error?.code !== "invalid_request"
)
throw error;
nativeSummaryOutcome = {
status: "unsupported",
error: error.value.error,
};
}
return {
retainedViews,
retainedViewEvidence,
nativeSummaryOutcome,
summaryEvidenceId,
};
};
const retainedJqMain = async (call, ToolFailure) => {
// This exact application entry is materialized in the pinned jq entry's
// observed MOV RDI, 0x401f00 instruction, not an original-source claim.
let main;
const mainEvidenceIds = [];
let sourceId;
try {
const completed = await call("analyze_function", {
procedure: "0x401f00",
});
sourceId = completed.evidence_id;
} catch (error) {
const reference =
error instanceof ToolFailure &&
error.value?.error?.code === "resource_constraint"
? error.value.error.details?.reported_limits?.evidence_reference
: undefined;
if (reference?.kind !== "retained-evidence") throw error;
sourceId = reference.evidence_id;
}
mainEvidenceIds.push(sourceId);
main = {};
for (const facet of [
"procedure",
"pseudocode",
"referenced_strings",
"callees",
"callers",
"basic_blocks",
]) {
let offset = 0;
const items = [];
const pages = [];
do {
const selected = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: sourceId },
view: {
kind: "native",
facet,
offset,
limit:
facet === "pseudocode" ? 65536 : facet === "basic_blocks" ? 1 : 64,
},
});
mainEvidenceIds.push(selected.evidence_id);
const v = normalized(selected);
items.push(v.item);
pages.push({
coverage: v.coverage,
limitations: v.limitations,
unknowns: v.unknowns,
});
if (v.coverage.exhausted || facet === "basic_blocks") break;
if (v.coverage.next_offset === null || v.coverage.next_offset <= offset)
throw new Error("Native view did not advance");
offset = v.coverage.next_offset;
} while (true);
main[facet] = { items, pages };
}
return { main, mainEvidenceIds };
};
export const measureNativeEntry = async ({
seed,
values,
call,
inputSha,
ToolFailure,
}) => {
await call("open_binary", { path: values.path, provider_id: "ghidra" });
try {
// DOS addresses follow the actual admitted load image. A file header
// offset is not a provider address or proof of runtime execution.
let loadImage, loadImageEvidenceId;
if (seed === undefined) {
const imageEvidence = await call("inspect_native_load_image", {});
loadImage = normalized(imageEvidence);
if (loadImage.status !== "verified")
throw new Error(
"The shipped DOS load image was not independently verified",
);
if (loadImage.target_sha256 !== inputSha)
throw new Error("The DOS load image belongs to a different target");
loadImageEvidenceId = imageEvidence.evidence_id;
seed = loadImage.entry.linear_address;
}
const address = seed;
const containing = await call("resolve_containing_procedure", {
address,
});
const info = await call("analyze_function", { procedure: address });
const n = normalized(info);
const selected =
values["native-question"] === "entry-views"
? await retainedEntryViews(call, info, inputSha, ToolFailure, [
containing.evidence_id,
...(loadImageEvidenceId === undefined ? [] : [loadImageEvidenceId]),
])
: {};
const { main, mainEvidenceIds = [] } =
values["native-question"] === "entry-and-main"
? await retainedJqMain(call, ToolFailure)
: {};
return {
artifact_sha256: info.subject?.digest.sha256,
entry_address: address,
containing_procedure: normalized(containing),
procedure: n.procedure,
pseudocode_prefix: n.pseudocode.slice(0, 512),
caller_count: n.callers.length,
callee_count: n.callees.length,
...(main === undefined ? {} : { main }),
analysis_profile: info.analysis_profile,
...(loadImage === undefined ? {} : { load_image: loadImage }),
...(selected.retainedViews === undefined
? {}
: {
retained_views: selected.retainedViews,
native_summary_outcome: selected.nativeSummaryOutcome,
}),
evidence_ids:
selected.retainedViews === undefined
? [
containing.evidence_id,
info.evidence_id,
...mainEvidenceIds,
...(loadImageEvidenceId === undefined
? []
: [loadImageEvidenceId]),
]
: {
containing_procedure: containing.evidence_id,
function_dossier: info.evidence_id,
...(loadImageEvidenceId === undefined
? {}
: { native_load_image: loadImageEvidenceId }),
retained_views: selected.retainedViewEvidence,
...(selected.summaryEvidenceId === undefined
? {}
: { native_summary: selected.summaryEvidenceId }),
},
};
} finally {
await call("close_binary", {});
}
};
export const nativeEntrySeed = async (artifact, path) => {
if (artifact === "jq") {
const file = await open(path, "r");
let header;
try {
header = (await file.read(Buffer.alloc(32), 0, 32, 0)).buffer;
} finally {
await file.close();
}
if (header.subarray(0, 6).toString("hex") !== "7f454c460201")
throw new Error("Expected ELF64 little endian entry seed");
return `0x${header.readBigUInt64LE(24).toString(16)}`;
}
if (artifact === "sharex.exe") {
const bytes = await readFile(path);
const pe = bytes.readUInt32LE(0x3c);
const optional = pe + 24;
if (
bytes.subarray(pe, pe + 4).toString("hex") !== "50450000" ||
bytes.readUInt16LE(pe + 4) !== 0x8664 ||
bytes.readUInt16LE(optional) !== 0x20b ||
bytes.readUInt32LE(optional + 108) <= 14 ||
bytes.readUInt32LE(optional + 112 + 14 * 8) !== 0 ||
bytes.readUInt32LE(optional + 116 + 14 * 8) !== 0
)
throw new Error(
"Expected the pinned native PE32+ entry seed without CLR metadata",
);
const address =
bytes.readBigUInt64LE(optional + 24) +
BigInt(bytes.readUInt32LE(optional + 16));
return `0x${address.toString(16)}`;
}
if (artifact === "freedos.edlin.exe") return undefined;
throw new Error("Select a pinned native artifact");
};
@@ -1,208 +0,0 @@
# Task-scoped preset lifecycle verification
Continues [#2016](https://github.com/morluto/rea/issues/2016) after
[#2308](https://github.com/morluto/rea/pull/2308) merged. This increment verifies
existing caller-selected Ghidra settings and immutable JSON snapshots through
actual public CLI/MCP workflows. Production defaults, provider selection and
public contracts remain unchanged; an engine database cache is still deferred.
Runtime baseline is main `f76163c2467db623f9de0bda757c9d8610ca9565`, built with
Node 24.18.0 and matching locked dependencies. Real Ghidra 12.1.4 uses the
existing caller-supplied JDK 21 and 768 MiB Java heap under one CPU. No target
execution, annotation or attached GUI database operation is requested.
## Small shipped input and profile boundaries
The first input is the installed `/usr/bin/true`, 35,664 bytes, SHA-256
`c79bf44242829108e323378531f4ac839513ca1fba45efd6583643526e1e9fd2`.
The local package database reports Debian `coreutils` `9.1-1` `amd64`; these are
installed-artifact observations, not independent archive authenticity proof.
The target itself is never invoked, including for version discovery. REA's
actual `list_procedures` chooses an internal, non-thunk procedure at `0x102000`.
The default profile reports `analyzer_preset: "ghidra-default"`. The selected
alternative reports `ghidra-default+disabled:Decompiler Switch Analysis` and
the exact disabled name in its analysis options. Their profile digests differ.
The selected initializer's complete normalized facts agree, while the profile
and provenance remain distinct. This does not establish equivalence for other
procedures, call graphs or applications. The earlier jq experiment found a
callee body difference; the existing default remains the recommendation.
The public [snapshot verifier](verify-preset-snapshot.mjs) checks:
- The default `analyze_function` actually produces a stored query entry and an
authenticated original Evidence record in the exported snapshot.
- The same profile returns identical task facts, subject, parameters and profile
through a fresh MCP connection. Its limitations explicitly mark snapshot reuse;
its distinct response identity does not masquerade as the original record.
- A disabled profile refuses the default snapshot before headless Ghidra starts,
then successfully analyzes the same caller-selected target with its own profile.
- Restoring the default refuses the disabled snapshot and accepts the original
default snapshot. Original snapshot/source bytes stay unchanged.
- The existing CLI `function --provider ghidra --snapshot ... --json` returns
the original cached Evidence identity and exact task facts without modifying
the source snapshot.
Actual `strace` records the known headless launch command once for fresh default
and once for fresh disabled analysis, and zero times for either rejection or
accepted reuse. The audit covers that known command, not an arbitrary execution
or network-absence guarantee. Source bytes and snapshot bytes remain unchanged.
## Real cancellation and cleanup retry
The [lifecycle verifier](verify-preset-lifecycle.mjs) observes actual pending
startup before the bridge endpoint exists. It verifies the JVM's run token,
launcher relationship and native process start identity with production process
inspection primitives, then cancels through the SDK's normal request signal.
Read-only token sweeps confirm cleanup, including processes outside the old
parent chain; owned runtime/socket directories are removed. The selected target
remains open and a fresh provider query succeeds.
REA preserves the logical run ID when reimporting that selected target. A new
native process start identity proves the new generation; requiring a new logical
ID would test a different contract. No PID/path pair alone establishes ownership.
After recovery, the verifier removes write permission only from the verified,
user-owned temporary Ghidra project directory. The actual public `close_binary`
reports `cleanup_incomplete` with the retained resource and `EACCES` reason.
Permissions are restored, a second close succeeds, and token sweeps/root removal
confirm cleanup. The original executable is unchanged. This is a controlled real
filesystem failure, not a recording provider simulation. The error does not
authorize automatic retry before fixing its cause.
These observations pass for both the default and disabled-switch profiles on the
small input. The source verifier preserves verification and restoration/close
failures together, always attempts cleanup, validates the manifest at its read
boundary and publishes success only after its cleanup callbacks complete.
## Failed harness assumptions and measurement limits
Keep the initial probes and their corrections outside Git:
- A primitive-only `procedure_info` snapshot contained no replay entries. Equal
content-addressed output after another analysis was not proof of cache reuse.
The corrected probe requires a stored `analyze_function` entry, a cache-reuse
marker and actual headless launch traces.
- After cancellation, activity was `not_observed`, rather than `idle`, because
no provider activity snapshot remained. Preserve that unknown; successful fresh
work proves recovery without relabeling absent metadata.
- Reimport preserved the logical run ID. Native start identity, not that logical
ID, establishes the new process generation.
These were verification assumptions, not newly demonstrated REA defects. No
unrelated production repair is made. Existing defects remain in the requested
private `/tmp` record.
The initial complete snapshot/profile/CLI source run takes 91.838 seconds and
samples 1,180,246,016 peak family bytes. The real default/disabled cancellation
and permission-retry prototype takes 66.977 seconds and samples 1,040,846,848
bytes. Their last-observed CPU totals are 90.486 and 65.542 seconds respectively.
Both use one CPU, 4 GiB hard memory, 3 GiB early-stop, no swap and 192 tasks.
No scope abort occurs, but final counters disappear at teardown and remain
unverified. Sampled values are not final OOM/limit-event proof.
These are lifecycle verification costs. Discovery, profile inspection, rejection,
cleanup and syscall tracing make their call sequences different. They are not
paired completed-question performance trials, and contain no model token counts.
Explicit snapshot reuse is existing REA behavior, not a new speedup introduced by
these verifiers. Broader native inputs and failure scenarios remain follow-ups.
## Shipped jq continuation
The same source snapshot verifier additionally passes on the pinned public jq
binary, SHA-256
`b1c22172dd303f3be49e935aa56aa48a8b7a46e0bc838b4997d3bb451495870f`.
Procedure `0x403a50` comes from the earlier actual REA entry observation, rather
than a newly guessed file offset. Default and disabled profiles each perform a
fresh headless analysis. Both profile mismatch directions reject before a
headless launch, both valid default reuses return exact task facts with zero
headless launches, and CLI reuse retains the original Evidence ID and snapshot
bytes. The selected entry agrees across profiles; the earlier differing callee
still prevents a general equivalence or fast-preset recommendation.
Default/disabled fresh `analyze_function` calls take 294.525/298.621 seconds in
this verification; default snapshot calls take 0.222 and 0.168 seconds. The CLI
reuse takes 2.899 seconds. These are calls within different verification sequences,
not repeated completed-question performance cohorts. They demonstrate the existing
explicit snapshot mechanism without an engine database cache; they do not measure
model tokens or introduce a new optimization.
The complete jq verification takes 624.537 seconds, samples 1,218,355,200 peak
family bytes and observes 567.198 CPU seconds before teardown. The final resource
counters remain unknown. The source verifier SHA-256 is
`42060686f9633da06bb5f257fa5c70f588e66569cf0befebe6a1a13f43bf0e88`;
the initial lifecycle verifier hash is
`b1680f4f506ef9328d1beabb4b1fbe97c911b3f06986857f0a59a4b97a3b61d3`.
Both hashes also match completed small-input source runs, including the final
cleanup/error-preservation implementation. Runtime production remains the pinned
main baseline; the follow-up changes only experiment sources and documentation.
## Invalid analyzer failure and healthy peers
Real MCP and CLI requests with `REA_GHIDRA_DISABLED_ANALYZERS` set to
`REA Nonexistent Analyzer 2016` both report `execution_failure`. Their diagnostics
preserve the exact unavailable analyzer name, selected provider, operation,
target identity and Ghidra pre-script failure. MCP still answers a bundled EVM
peer request and closes the selected native target; original target bytes stay
unchanged and the owned Ghidra runtime directory is removed.
The first healthy-peer probe assumed ELF layout support was built in. This main
requires an explicitly supplied pwntools interpreter for that format and correctly
reports `provider_unavailable`; none was configured. The corrected probe uses
the already verified bundled EVM peer. No installer or provider fallback is added.
The first CLI observer also looked inside `error` as if it had MCP's shape. The
actual CLI envelope has an error string and sibling `code`, `message`, `details`
and other fields. Regrading its saved complete reply proves the named diagnostics
are preserved. The original incorrect assertion/report remains archived; no
provider rerun or production repair is needed for that correction.
The invalid-name behavior is reproducible with the existing CLI:
```sh
REA_GHIDRA_DISABLED_ANALYZERS='REA Nonexistent Analyzer 2016' \
node ABS_RUNTIME/scripts/rea.mjs function ABS_TRUE_BINARY 0x102000 \
--provider ghidra --json
```
Use the address actually observed by REA for a different target. The deliberately
invalid name is expected to fail; fixing the setting is required before retrying.
## Reproduction
Build the pinned runtime and supply an explicit string-valued provider settings
JSON, real Ghidra/JDK, a caller-supplied Linux strace executable and a fresh private
output directory. The snapshot verifier streams target hashes and stores actual
SDK/CLI replies, profile commitments and exec traces outside the checkout:
```sh
node experiments/analysis-efficiency/verify-preset-snapshot.mjs \
--runtime-root ABS_RUNTIME --revision SHA --path ABS_NATIVE_TARGET \
--providers ABS_SETTINGS_JSON --strace ABS_STRACE --output NEW_ABS_DIR
```
Select `--procedure` from actual REA evidence when the question already identifies
one; otherwise the verifier uses the actual procedure list. `--timeout-ms` is an
explicit observation window; `--disabled-analyzers` uses the existing setting.
Run cancellation/permission retry as a non-root Linux user:
```sh
node experiments/analysis-efficiency/verify-preset-lifecycle.mjs \
--runtime-root ABS_RUNTIME --revision SHA --path ABS_NATIVE_TARGET \
--providers ABS_SETTINGS_JSON --output NEW_ABS_DIR
```
Runtime revision is caller-supplied; keep the built/frozen runtime receipt alongside
the verifier source fingerprint. Target bytes, provider projects, raw JSON, traces
and profiles are not committed. The scripts acquire no dependencies or change
the user's installed configuration.
## Final cleanup review
The final review adds an independent filesystem check that the recovered
bridge socket directory is absent after permission restoration and close retry,
and preserves its ownership manifest in the receipt. Both default and disabled
profiles pass this related real workflow again. Its source SHA-256 is
`f5d29efdb056032072b99ac1e6fe1d6d2099bbe84c324c75032bd0178bb747c5`. The previous observations and source hashes stay archived;
the jq/model/provider matrices were not repeated for this observer change.
@@ -1,116 +0,0 @@
import { createHash } from "node:crypto";
import { createReadStream } from "node:fs";
import { mkdir, open, readFile, writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { parseArgs } from "node:util";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
const { values } = parseArgs({
options: {
"runtime-root": { type: "string" },
path: { type: "string" },
providers: { type: "string" },
output: { type: "string" },
},
});
if (
!values["runtime-root"] ||
!values.path ||
!values.providers ||
!values.output
)
throw new Error(
"Use --runtime-root ABS --path ABS --providers JSON --output NEW_ABS_DIR",
);
const selected = JSON.parse(await readFile(values.providers, "utf8"));
const expectedName = selected.REA_GHIDRA_DISABLED_ANALYZERS;
if (!expectedName)
throw new Error(
"The probe requires an explicitly selected invalid analyzer name",
);
const digest = async () => {
const hash = createHash("sha256");
for await (const chunk of createReadStream(values.path)) hash.update(chunk);
return hash.digest("hex");
};
const before = await digest();
await mkdir(values.output, { mode: 0o700 });
const file = await open(values.path, "r");
let address;
try {
const header = Buffer.alloc(32);
const { bytesRead } = await file.read(header, 0, header.length, 0);
if (
bytesRead !== 32 ||
header.subarray(0, 6).toString("hex") !== "7f454c460201"
)
throw new Error(
"This counterexample uses a real ELF64 little-endian application",
);
address = `0x${header.readBigUInt64LE(24).toString(16)}`;
} finally {
await file.close();
}
const client = new Client({ name: "rea-analyzer-verification", version: "1" });
const transport = new StdioClientTransport({
command: process.execPath,
args: [resolve(values["runtime-root"], "scripts/rea.mjs"), "mcp"],
env: { ...process.env, ...selected },
stderr: "pipe",
});
const calls = [];
const call = async (name, arguments_) => {
const reply = await client.callTool(
{ name, arguments: arguments_ },
{ timeout: 600_000 },
);
await writeFile(
resolve(values.output, `call-${calls.length + 1}.json`),
JSON.stringify(reply),
);
calls.push({ name, is_error: reply.isError === true });
return reply;
};
let rejected = false;
let named = false;
let failure = null;
try {
await client.connect(transport);
const opened = await call("open_binary", {
path: values.path,
provider_id: "ghidra",
});
const reply = opened.isError
? opened
: await call("resolve_containing_procedure", { address });
rejected = reply.isError === true;
named = rejected && JSON.stringify(reply).includes(expectedName);
} catch (error) {
failure = String(error);
} finally {
try {
await call("close_binary", {});
} catch (error) {
failure = `${failure ?? ""} close: ${String(error)}`;
}
await client.close();
}
const after = await digest();
const report = {
target_sha256: before,
target_sha256_after: after,
expected_analyzer: expectedName,
rejected,
rejection_names_requested_analyzer: named,
failure,
calls,
oracle:
"A syntactically valid but nonexistent analyzer must produce a meaningful public refusal, not successful Evidence claiming that preset. A not-found procedure still means Ghidra reached readiness.",
};
await writeFile(
resolve(values.output, "summary.json"),
JSON.stringify(report, null, 2),
);
process.stdout.write(JSON.stringify(report) + "\n");
if (!rejected || !named || failure || before !== after) process.exitCode = 1;

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