Compare commits
62
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b72592f89 | ||
|
|
fb34ccbec7 | ||
|
|
59be866719 | ||
|
|
8e004522f2 | ||
|
|
d80b55e11b | ||
|
|
85c5477930 | ||
|
|
7724edbdd3 | ||
|
|
0baad58e60 | ||
|
|
1770f38cfc | ||
|
|
c9c40f6f9e | ||
|
|
428eee00fd | ||
|
|
94153f1c75 | ||
|
|
ac6ef95e12 | ||
|
|
b1bf4a70d4 | ||
|
|
7711b00005 | ||
|
|
c9aecde580 | ||
|
|
ae412654d5 | ||
|
|
86de439ba4 | ||
|
|
109769319a | ||
|
|
bfa805decf | ||
|
|
51d6c87cdb | ||
|
|
e4d3e1399d | ||
|
|
7ae3c50a9d | ||
|
|
10400fdb57 | ||
|
|
4a4ae9b2b9 | ||
|
|
0b7145361e | ||
|
|
7c9c1ebdb7 | ||
|
|
d35035780a | ||
|
|
51367cae6f | ||
|
|
90e37f4152 | ||
|
|
df2c08b546 | ||
|
|
58fb372071 | ||
|
|
3159732597 | ||
|
|
4f46eac453 | ||
|
|
5190843f8f | ||
|
|
60259a91d9 | ||
|
|
672bdea21f | ||
|
|
fe4b94a661 | ||
|
|
abc8c6dadf | ||
|
|
621cee192d | ||
|
|
c22111eca2 | ||
|
|
07b36c1489 | ||
|
|
0d5033ad12 | ||
|
|
d1dcebce2c | ||
|
|
79156e5bed | ||
|
|
974f11d010 | ||
|
|
75a4a14fa0 | ||
|
|
b3dec005bc | ||
|
|
d4e8ef7499 | ||
|
|
9b780c47bc | ||
|
|
98d8470d36 | ||
|
|
e9970855ba | ||
|
|
fa87dd2aac | ||
|
|
d864ad5471 | ||
|
|
4a5aec8ad6 | ||
|
|
d8c76b6296 | ||
|
|
e4532b5376 | ||
|
|
966f7cc84b | ||
|
|
6bae774328 | ||
|
|
4573e8cf35 | ||
|
|
69e097a8ca | ||
|
|
0b60a2ce90 |
@@ -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: "39"
|
||||
version: "40"
|
||||
---
|
||||
|
||||
# REA
|
||||
|
||||
@@ -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`, `grok_build`, `omp`, `pi`,
|
||||
`hermes`, `dsh`, or `grok_bot`. If unknown, inspect `doctor --json` before choosing a
|
||||
`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
|
||||
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,6 +11,19 @@ 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.
|
||||
|
||||
@@ -36,6 +36,20 @@ 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.
|
||||
@@ -121,15 +135,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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Packages and extraction
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Design discussion
|
||||
description: Resolve an REA architecture, provider, or contract question before implementation
|
||||
description: Discuss an REA architecture, provider, contract, or scope decision
|
||||
title: "[Design] "
|
||||
labels:
|
||||
- enhancement
|
||||
@@ -9,7 +9,12 @@ body:
|
||||
attributes:
|
||||
value: |
|
||||
Use this for a substantial provider, public/persisted contract, or
|
||||
authority-boundary decision. Keep one decision per discussion.
|
||||
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.
|
||||
|
||||
- type: checkboxes
|
||||
id: before-submitting
|
||||
@@ -18,14 +23,16 @@ body:
|
||||
options:
|
||||
- label: I searched the open and closed issues and pull requests for a related discussion.
|
||||
required: true
|
||||
- label: I removed credentials, tokens, private paths, and sensitive target data.
|
||||
- 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.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: decision
|
||||
attributes:
|
||||
label: Decision needed
|
||||
description: State the exact question maintainers need to resolve.
|
||||
description: What would you like maintainers to help decide? A short question is enough.
|
||||
placeholder: Should REA ... or ...?
|
||||
validations:
|
||||
required: true
|
||||
@@ -34,23 +41,57 @@ body:
|
||||
id: context-evidence
|
||||
attributes:
|
||||
label: Context and evidence
|
||||
description: Explain why the decision is needed now. Separate observed behavior, derived evidence, and inference.
|
||||
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
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: boundary-invariants
|
||||
attributes:
|
||||
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
|
||||
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.
|
||||
|
||||
- type: textarea
|
||||
id: options
|
||||
attributes:
|
||||
label: Options and tradeoffs
|
||||
description: Compare a small number of viable approaches, including platform, compatibility, safety, evidence, and maintenance costs.
|
||||
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
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -58,9 +99,10 @@ body:
|
||||
id: success-criteria
|
||||
attributes:
|
||||
label: Success criteria and open questions
|
||||
description: State what outcome would settle the decision and list only unresolved questions that could change the choice.
|
||||
validations:
|
||||
required: true
|
||||
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.
|
||||
|
||||
- type: textarea
|
||||
id: references
|
||||
|
||||
@@ -8,9 +8,13 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
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.
|
||||
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.
|
||||
|
||||
- type: checkboxes
|
||||
id: before-submitting
|
||||
@@ -19,7 +23,9 @@ body:
|
||||
options:
|
||||
- label: I searched the open and closed issues and pull requests for a related proposal.
|
||||
required: true
|
||||
- label: I removed credentials, tokens, private paths, and sensitive target data.
|
||||
- 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.
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
@@ -36,6 +42,7 @@ body:
|
||||
- MCP or agent integration
|
||||
- Documentation
|
||||
- Other
|
||||
- Not sure yet
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -43,7 +50,7 @@ body:
|
||||
id: current-limitation
|
||||
attributes:
|
||||
label: Current limitation
|
||||
description: What user or agent workflow is blocked, ambiguous, or unnecessarily difficult today?
|
||||
description: What are you trying to understand or do, and what is difficult today? A short example is enough.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -51,23 +58,69 @@ body:
|
||||
id: use-cases
|
||||
attributes:
|
||||
label: Use cases
|
||||
description: Give concrete applications, targets, callers, or investigation workflows. Explain why current tools are insufficient.
|
||||
validations:
|
||||
required: true
|
||||
description: Optional additional examples of applications, targets, or callers. Leave blank if covered above.
|
||||
|
||||
- type: textarea
|
||||
id: desired-outcome
|
||||
attributes:
|
||||
label: Desired outcome and success criteria
|
||||
description: Describe observable behavior, inputs, outputs, evidence, and compatibility criteria that would make this useful.
|
||||
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
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: boundaries
|
||||
attributes:
|
||||
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.
|
||||
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.
|
||||
|
||||
- type: textarea
|
||||
id: alternatives
|
||||
|
||||
@@ -11,7 +11,7 @@ runs:
|
||||
id: plan
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_CACHE_PREFIX: rea-portable-build-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc') }}
|
||||
BUILD_CACHE_PREFIX: rea-portable-build-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc', '.nvmrc', 'package-lock.json') }}
|
||||
run: |
|
||||
npm run --silent test:prepare -- --dry=json |
|
||||
node --input-type=module -e '
|
||||
@@ -25,6 +25,7 @@ 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'
|
||||
@@ -32,9 +33,11 @@ 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 }}
|
||||
|
||||
@@ -19,17 +19,39 @@ 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
|
||||
|
||||
<!-- Complete the applicable lines; use "none" or "not applicable" explicitly. -->
|
||||
<!-- Short answers are welcome. Complete applicable lines; mark unresolved facts as "unknown".
|
||||
Use "none" or "not applicable" only when established. -->
|
||||
|
||||
- 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:
|
||||
- Process execution, authorization, cleanup, or containment impact:
|
||||
- Target selection, authority, upstream behavior, and cleanup details (if applicable):
|
||||
- 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,
|
||||
@@ -68,9 +90,13 @@ limits, security/privacy/containment implications, and meaningful proof gaps. --
|
||||
- Package or release metadata impact:
|
||||
- Security, privacy, process, or containment review:
|
||||
|
||||
## Review checklist
|
||||
## Before merge
|
||||
|
||||
<!-- Draft PRs may leave pending items unchecked. Resolve material scope and
|
||||
authority questions before integration. -->
|
||||
|
||||
- [ ] 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.
|
||||
|
||||
+40
-31
@@ -94,6 +94,9 @@ 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
|
||||
|
||||
@@ -105,7 +108,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shard: [1/4, 2/4, 3/4, 4/4]
|
||||
shard: [1/6, 2/6, 3/6, 4/6, 5/6, 6/6]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
@@ -168,7 +171,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: test-results
|
||||
name: test-timings
|
||||
run-id: ${{ steps.history.outputs.run-id }}
|
||||
github-token: ${{ github.token }}
|
||||
path: .cache/ci-test-history
|
||||
@@ -203,14 +206,10 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Require successful test shards
|
||||
- name: Require successful change classification
|
||||
env:
|
||||
CHANGES_RESULT: ${{ needs.changes.result }}
|
||||
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"
|
||||
run: test "${CHANGES_RESULT}" = "success"
|
||||
- uses: actions/checkout@v4
|
||||
if: needs.changes.outputs.code == 'true' && success()
|
||||
- uses: actions/setup-node@v4
|
||||
@@ -227,6 +226,7 @@ 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 --
|
||||
@@ -240,27 +240,13 @@ jobs:
|
||||
--outputFile.junit=test-results.xml
|
||||
--outputFile.json=test-results.json
|
||||
- name: Summarize slowest test files
|
||||
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
|
||||
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
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: needs.changes.outputs.code == 'true' && always()
|
||||
if: needs.changes.outputs.code == 'true' && !cancelled() && hashFiles('test-results.json') != ''
|
||||
with:
|
||||
name: test-results
|
||||
path: |
|
||||
@@ -269,6 +255,21 @@ 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
|
||||
@@ -372,7 +373,7 @@ jobs:
|
||||
|
||||
apple-artifacts:
|
||||
name: Real Apple artifact CLI/MCP E2E
|
||||
needs: changes
|
||||
needs: [changes, build]
|
||||
if: needs.changes.outputs.apple == 'true'
|
||||
runs-on: macos-15
|
||||
timeout-minutes: 15
|
||||
@@ -383,6 +384,10 @@ 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
|
||||
@@ -445,7 +450,7 @@ jobs:
|
||||
|
||||
windows-curated:
|
||||
name: Windows capability and package lane
|
||||
needs: [changes, windows-native-build]
|
||||
needs: [changes, build, windows-native-build]
|
||||
if: needs.changes.outputs.package == 'true'
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 25
|
||||
@@ -456,8 +461,11 @@ 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
|
||||
@@ -496,6 +504,7 @@ 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
|
||||
|
||||
@@ -47,6 +47,7 @@ Thumbs.db
|
||||
|
||||
# Local reference sources and analysis artifacts
|
||||
/_reference/
|
||||
/experiments/analysis-efficiency/results/
|
||||
|
||||
# Generated website download
|
||||
/website/public/examples/notes-example.zip
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
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.
|
||||
@@ -26,6 +28,31 @@ Parse unknown boundary values and model expected failures with the tagged error
|
||||
|
||||
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
@@ -17,8 +17,108 @@ 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
|
||||
@@ -87,6 +187,10 @@ 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
@@ -0,0 +1,136 @@
|
||||
# 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.
|
||||
@@ -166,6 +166,7 @@ Additional tools and host support depend on the target:
|
||||
| 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) |
|
||||
| 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) |
|
||||
@@ -178,7 +179,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), and
|
||||
[IDA guide](docs/ida-provider.md) (including an optional native MCP bridge), and
|
||||
[experimental Windows Ghidra support](docs/windows-ghidra-p0.md).
|
||||
Ghidra also supports [16-bit DOS analysis](docs/ghidra-dos.md).
|
||||
For large binaries, raise the provider's startup deadline with
|
||||
@@ -331,9 +332,13 @@ Thanks to everyone using REA, reporting bugs, requesting features, testing build
|
||||
|
||||
## Disclaimer
|
||||
|
||||
REA provides tools for lawful reverse-engineering research, analysis, and reconstruction. You are responsible for obtaining any required authorization and complying with applicable laws. The project does not endorse illegal or unauthorized use.
|
||||
See [DISCLAIMER.md](DISCLAIMER.md) for responsible-use guidance.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -348,3 +353,16 @@ 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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ npx rea-agents@latest setup
|
||||
| أجهزة 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) |
|
||||
| الحزم والموارد | قوائم الملفات، والبصمات، وملفات plist، وبنية حزم Apple، والموارد المستخرجة | [دليل تحليل الملفات وJavaScript](docs/javascript-artifact-reconstruction.md)، [تطبيقات Apple](docs/apple-application-analysis.md) |
|
||||
| سلوك العمليات | مخرجات الطرفية، والتفاعلات، وملاحظات الخروج ونظام الملفات، ومقارنات التشغيل | Linux/macOS مع PTY أصلي؛ [تسجيل سلوك العمليات](docs/process-capture.md) |
|
||||
@@ -274,7 +275,13 @@ npx rea-agents@latest setup
|
||||
|
||||
## إخلاء المسؤولية
|
||||
|
||||
يوفّر 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.
|
||||
|
||||
## المساهمة
|
||||
|
||||
@@ -285,3 +292,15 @@ npx rea-agents@latest setup
|
||||
## الترخيص
|
||||
|
||||
[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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA benötigt Node.js 22.x (>=22.19), 24.x (>=24.11) oder 26+ sowie npm. Zusätz
|
||||
| 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) |
|
||||
| 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) |
|
||||
@@ -272,7 +273,13 @@ Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds
|
||||
|
||||
## Haftungsausschluss
|
||||
|
||||
REA stellt Werkzeuge für rechtmäßige Reverse-Engineering-Forschung, Analyse und Rekonstruktion bereit. Du bist dafür verantwortlich, erforderliche Genehmigungen einzuholen und geltendes Recht einzuhalten. Das Projekt unterstützt keine rechtswidrige oder unbefugte Nutzung.
|
||||
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.
|
||||
|
||||
## Mitwirken
|
||||
|
||||
@@ -283,3 +290,15 @@ 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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA requiere Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, además de npm. Las h
|
||||
| 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 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) |
|
||||
@@ -272,7 +273,13 @@ Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban co
|
||||
|
||||
## Aviso legal
|
||||
|
||||
REA proporciona herramientas para la investigación, el análisis y la reconstrucción mediante ingeniería inversa conforme a la ley. Eres responsable de obtener las autorizaciones necesarias y cumplir las leyes aplicables. El proyecto no respalda usos ilegales ni no autorizados.
|
||||
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.
|
||||
|
||||
## Contribuir
|
||||
|
||||
@@ -283,3 +290,15 @@ 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.
|
||||
|
||||
+20
-1
@@ -136,6 +136,7 @@ REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، بههمراه np
|
||||
| دستگاههای اندروید | دستگاهها، بستهها، فرایندها، لاگها، دامپها، اسکرینشاتها و انتقال 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) |
|
||||
| بستهها و منابع | فهرست فایلها، digestها، فایلهای plist، ساختار bundle اپل و منابع استخراجشده | [راهنمای آرتیفکت و JavaScript](docs/javascript-artifact-reconstruction.md)، [برنامههای اپل](docs/apple-application-analysis.md) |
|
||||
| رفتار فرایند | خروجی ترمینال، تعاملات، وضعیت خروج، مشاهدات سیستم فایل و مقایسهٔ اجراها | Linux/macOS با PTY بومی؛ [ضبط فرایند](docs/process-capture.md) |
|
||||
@@ -251,7 +252,13 @@ npx rea-agents@latest setup
|
||||
|
||||
## سلب مسئولیت
|
||||
|
||||
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.
|
||||
|
||||
## مشارکت
|
||||
|
||||
@@ -263,4 +270,16 @@ REA ابزارهایی برای پژوهش، تحلیل و بازسازی قان
|
||||
|
||||
[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>
|
||||
|
||||
+20
-1
@@ -148,6 +148,7 @@ REA nécessite Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, ainsi que npm. Les
|
||||
| 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 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) |
|
||||
@@ -276,7 +277,13 @@ Merci à toutes les personnes qui utilisent REA, signalent des bugs, proposent d
|
||||
|
||||
## Avertissement
|
||||
|
||||
REA fournit des outils destinés à la recherche, à l'analyse et à la reconstruction légales en rétro-ingénierie. Il vous appartient d'obtenir toute autorisation nécessaire et de respecter les lois applicables. Le projet n'encourage aucune utilisation illégale ou non autorisée.
|
||||
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.
|
||||
|
||||
## Contribuer
|
||||
|
||||
@@ -287,3 +294,15 @@ 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.
|
||||
|
||||
+19
-2
@@ -151,6 +151,7 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
|
||||
| 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 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) |
|
||||
@@ -297,9 +298,13 @@ Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fi
|
||||
|
||||
## Penafian
|
||||
|
||||
REA menyediakan alat untuk penelitian, analisis, dan rekonstruksi rekayasa balik yang sah. Anda bertanggung jawab untuk memperoleh otorisasi yang diperlukan dan mematuhi hukum yang berlaku. Proyek ini tidak mendukung penggunaan ilegal atau tanpa izin.
|
||||
Lihat [DISCLAIMER.md](DISCLAIMER.md) untuk panduan penggunaan yang bertanggung jawab.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Kontribusi
|
||||
|
||||
@@ -310,3 +315,15 @@ 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.
|
||||
|
||||
+19
-2
@@ -148,6 +148,7 @@ REA richiede Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, oltre a npm. Strument
|
||||
| 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 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) |
|
||||
@@ -276,9 +277,13 @@ Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, te
|
||||
|
||||
## Disclaimer
|
||||
|
||||
REA fornisce strumenti per la ricerca, l'analisi e la ricostruzione di ingegneria inversa lecita. Sei responsabile di ottenere le eventuali autorizzazioni richieste e di rispettare le leggi applicabili. Il progetto non approva l'uso illegale o non autorizzato.
|
||||
Consulta [DISCLAIMER.md](DISCLAIMER.md) per le indicazioni sull'uso responsabile.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -289,3 +294,15 @@ 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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm
|
||||
| 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) |
|
||||
| パッケージとリソース | ファイル一覧、ダイジェスト、plist、Apple バンドルの構造、抽出されたリソース | [アーティファクトと JavaScript のガイド](docs/javascript-artifact-reconstruction.md)、[Apple アプリケーション](docs/apple-application-analysis.md) |
|
||||
| プロセスの動作 | ターミナル出力、対話、終了とファイルシステムの観測結果、実行の比較 | ネイティブ PTY を備えた Linux/macOS;[プロセスキャプチャ](docs/process-capture.md) |
|
||||
@@ -274,7 +275,13 @@ REA の利用、バグ報告、機能の要望、ビルドのテスト、修正
|
||||
|
||||
## 免責事項
|
||||
|
||||
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.
|
||||
|
||||
## 貢献する
|
||||
|
||||
@@ -285,3 +292,15 @@ REA への貢献を歓迎します
|
||||
|
||||
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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니
|
||||
| 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) |
|
||||
| 패키지 및 리소스 | 파일 목록, 다이제스트, plist, Apple 번들 구조, 추출한 리소스 | [아티팩트 및 JavaScript 가이드](docs/javascript-artifact-reconstruction.md), [Apple 애플리케이션](docs/apple-application-analysis.md) |
|
||||
| 프로세스 동작 | 터미널 출력, 상호작용, 종료 및 파일 시스템 관찰 결과, 실행 비교 | 네이티브 PTY를 지원하는 Linux/macOS; [프로세스 캡처](docs/process-capture.md) |
|
||||
@@ -274,7 +275,13 @@ REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를
|
||||
|
||||
## 면책 조항
|
||||
|
||||
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.
|
||||
|
||||
## 기여
|
||||
|
||||
@@ -285,3 +292,15 @@ 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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA wymaga Node.js 22.x (>=22.19), 24.x (>=24.11) lub 26+ oraz npm. Dodatkowe na
|
||||
| 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) |
|
||||
| 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) |
|
||||
@@ -272,7 +273,13 @@ Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują no
|
||||
|
||||
## Zastrzeżenie
|
||||
|
||||
REA dostarcza narzędzia do zgodnych z prawem badań z zakresu inżynierii wstecznej, analizy i odtwarzania. Odpowiadasz za uzyskanie wymaganych zezwoleń i przestrzeganie obowiązującego prawa. Projekt nie popiera działań nielegalnych ani nieautoryzowanych.
|
||||
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.
|
||||
|
||||
## Współtworzenie
|
||||
|
||||
@@ -283,3 +290,15 @@ 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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ O REA requer Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, além do npm. As fer
|
||||
| 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 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) |
|
||||
@@ -272,7 +273,13 @@ Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam b
|
||||
|
||||
## Aviso legal
|
||||
|
||||
O REA fornece ferramentas para pesquisa, análise e reconstrução por engenharia reversa dentro da lei. Você é responsável por obter as autorizações necessárias e cumprir as leis aplicáveis. O projeto não apoia usos ilegais ou não autorizados.
|
||||
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.
|
||||
|
||||
## Contribuir
|
||||
|
||||
@@ -283,3 +290,15 @@ 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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а так
|
||||
| Устройства 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) |
|
||||
| Пакеты и ресурсы | Списки файлов, хеши, plist, структура пакетов Apple и извлечённые ресурсы | [Руководство по артефактам и JavaScript](docs/javascript-artifact-reconstruction.md), [приложения Apple](docs/apple-application-analysis.md) |
|
||||
| Поведение процессов | Вывод терминала, взаимодействия, наблюдения за завершением и файловой системой, сравнения запусков | Linux/macOS с нативным PTY; [захват процессов](docs/process-capture.md) |
|
||||
@@ -272,7 +273,13 @@ npx rea-agents@latest setup
|
||||
|
||||
## Отказ от ответственности
|
||||
|
||||
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.
|
||||
|
||||
## Участие в проекте
|
||||
|
||||
@@ -283,3 +290,15 @@ REA предоставляет инструменты для законных и
|
||||
## Лицензия
|
||||
|
||||
[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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
|
||||
| อุปกรณ์ 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) |
|
||||
| แพ็กเกจและทรัพยากร | รายการไฟล์ ค่าแฮช plist โครงสร้างบันเดิลของ Apple และทรัพยากรที่แตกออกมา | [คู่มืออาร์ติแฟกต์และ JavaScript](docs/javascript-artifact-reconstruction.md), [แอปพลิเคชัน Apple](docs/apple-application-analysis.md) |
|
||||
| พฤติกรรมของโปรเซส | เอาต์พุตเทอร์มินัล การโต้ตอบ ข้อมูลการสิ้นสุดและระบบไฟล์ที่สังเกตได้ และการเปรียบเทียบการรัน | Linux/macOS ที่มี PTY เนทีฟ; [การบันทึกโปรเซส](docs/process-capture.md) |
|
||||
@@ -272,7 +273,13 @@ npx rea-agents@latest setup
|
||||
|
||||
## ข้อสงวนสิทธิ์
|
||||
|
||||
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.
|
||||
|
||||
## การมีส่วนร่วม
|
||||
|
||||
@@ -283,3 +290,15 @@ REA มีเครื่องมือสำหรับการวิจั
|
||||
## สัญญาอนุญาต
|
||||
|
||||
[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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA; Node.js 22.x (>=22.19), 24.x (>=24.11) veya 26+ ve npm gerektirir. Ek araç
|
||||
| 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) |
|
||||
| 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) |
|
||||
@@ -272,7 +273,13 @@ REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve d
|
||||
|
||||
## Sorumluluk reddi
|
||||
|
||||
REA, yasal tersine mühendislik araştırması, analizi ve yeniden oluşturma için araçlar sağlar. Gerekli izinleri almak ve geçerli yasalara uymak sizin sorumluluğunuzdadır. Proje yasa dışı veya yetkisiz kullanımı desteklemez.
|
||||
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.
|
||||
|
||||
## Katkıda bulunma
|
||||
|
||||
@@ -283,3 +290,15 @@ 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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а та
|
||||
| Пристрої 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) |
|
||||
| Пакети й ресурси | Переліки файлів, хеші, plist, структура пакетів Apple та видобуті ресурси | [Посібник артефактів і JavaScript](docs/javascript-artifact-reconstruction.md), [застосунки Apple](docs/apple-application-analysis.md) |
|
||||
| Поведінка процесів | Вивід термінала, взаємодії, спостереження за завершенням і файловою системою та порівняння запусків | Linux/macOS із нативним PTY; [захоплення процесів](docs/process-capture.md) |
|
||||
@@ -272,7 +273,13 @@ npx rea-agents@latest setup
|
||||
|
||||
## Відмова від відповідальності
|
||||
|
||||
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.
|
||||
|
||||
## Участь у проєкті
|
||||
|
||||
@@ -283,3 +290,15 @@ REA надає інструменти для законних досліджен
|
||||
## Ліцензія
|
||||
|
||||
[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.
|
||||
|
||||
+20
-1
@@ -144,6 +144,7 @@ REA yêu cầu Node.js 22.x (>=22.19), 24.x (>=24.11) hoặc 26+, cùng với np
|
||||
| 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 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) |
|
||||
@@ -272,7 +273,13 @@ 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
|
||||
|
||||
REA cung cấp công cụ cho nghiên cứu dịch ngược, phân tích và tái tạo hợp pháp. Bạn có trách nhiệm có được các quyền cho phép cần thiết và tuân thủ luật áp dụng. Dự án không ủng hộ việc sử dụng trái pháp luật hoặc không được cho phép.
|
||||
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.
|
||||
|
||||
## Đóng góp
|
||||
|
||||
@@ -283,3 +290,15 @@ 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.
|
||||
|
||||
+15
-1
@@ -144,6 +144,7 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
|
||||
| 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) |
|
||||
| 軟體包與資源 | 檔案清單、摘要、plist、Apple bundle 結構和提取的資源 | [製品與 JavaScript 指南](docs/javascript-artifact-reconstruction.md)、[Apple 應用](docs/apple-application-analysis.md) |
|
||||
| 處理程序行為 | 終端輸出、互動、退出和檔案系統觀察結果,以及執行對比 | 支援原生 PTY 的 Linux/macOS;[處理程序擷取](docs/process-capture.md) |
|
||||
@@ -274,7 +275,12 @@ npx rea-agents@latest setup
|
||||
|
||||
## 免責聲明
|
||||
|
||||
REA 為合法的逆向工程研究、分析和重建提供工具。你有責任取得所需授權並遵守適用法律。本專案不認同非法或未經授權的使用。
|
||||
負責任使用的相關指引請見 [DISCLAIMER.md](DISCLAIMER.md)。
|
||||
|
||||
REA 用於合法的研究、教育、互通性、軟體保存,以及分析你擁有或獲准檢查的軟體。
|
||||
|
||||
本專案對非法或未經授權使用的立場涵蓋所有 REA 版本、分發管道和執行平台;
|
||||
每份副本仍適用其隨附的授權。
|
||||
|
||||
## 參與貢獻
|
||||
|
||||
@@ -285,3 +291,11 @@ REA 為合法的逆向工程研究、分析和重建提供工具。你有責任
|
||||
## 授權條款
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
REA 自行編寫的程式碼採用 MIT 授權;第三方內容保留各自的授權和著作權聲明。
|
||||
依賴清單、授權原文及外部工具條款見[第三方聲明](THIRD_PARTY_NOTICES.md)。
|
||||
|
||||
**使用者須自行合法取得商用工具及所需使用權**,包括 IDA Pro / Hex-Rays 反編譯器、
|
||||
Hopper 和 JEB,並遵守各自授權。REA 不提供工具授權、金鑰或啟用權利;試用版和
|
||||
展示版也須遵守廠商對使用者、功能、自動化及輸出分享的限制。不得使用破解副本、
|
||||
竊取或違規共用金鑰,也不得繞過授權限制。本指引不變更 MIT 或第三方授權。
|
||||
|
||||
+15
-1
@@ -144,6 +144,7 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
|
||||
| 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) |
|
||||
| 软件包与资源 | 文件清单、摘要、plist、Apple bundle 结构和提取的资源 | [制品与 JavaScript 指南](docs/javascript-artifact-reconstruction.md)、[Apple 应用](docs/apple-application-analysis.md) |
|
||||
| 进程行为 | 终端输出、交互、退出和文件系统观察结果,以及运行对比 | 支持原生 PTY 的 Linux/macOS;[进程捕获](docs/process-capture.md) |
|
||||
@@ -274,7 +275,12 @@ npx rea-agents@latest setup
|
||||
|
||||
## 免责声明
|
||||
|
||||
REA 为合法的逆向工程研究、分析和重建提供工具。你有责任取得所需授权并遵守适用法律。项目不支持非法或未经授权的使用。
|
||||
负责任使用的相关指引请见 [DISCLAIMER.md](DISCLAIMER.md)。
|
||||
|
||||
REA 用于合法的研究、教育、互操作性、软件保存,以及分析你拥有或获准检查的软件。
|
||||
|
||||
本项目对非法或未经授权使用的立场涵盖所有 REA 版本、分发渠道和运行平台;
|
||||
每份副本仍适用其随附的许可。
|
||||
|
||||
## 参与贡献
|
||||
|
||||
@@ -285,3 +291,11 @@ REA 为合法的逆向工程研究、分析和重建提供工具。你有责任
|
||||
## 许可证
|
||||
|
||||
[MIT](LICENSE)
|
||||
|
||||
REA 自行编写的代码采用 MIT 许可;第三方内容保留各自的许可和著作权声明。
|
||||
依赖清单、许可原文及外部工具条款见[第三方声明](THIRD_PARTY_NOTICES.md)。
|
||||
|
||||
**用户须自行合法取得商用工具及所需使用权**,包括 IDA Pro / Hex-Rays 反编译器、
|
||||
Hopper 和 JEB,并遵守各自许可。REA 不提供工具许可、密钥或激活权利;试用版和
|
||||
演示版也须遵守厂商对用户、功能、自动化及输出分享的限制。不得使用破解副本、
|
||||
窃取或违规共用密钥,也不得绕过许可限制。本指引不变更 MIT 或第三方许可。
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
# 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.
|
||||
|
||||
## 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.
|
||||
@@ -17,6 +17,7 @@ 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" },
|
||||
@@ -42,10 +43,6 @@ export default defineConfig({
|
||||
{ text: "Android applications", link: "/android-analysis" },
|
||||
{ text: "Apple applications", link: "/apple-application-analysis" },
|
||||
{ text: "Firmware", link: "/firmware-analysis" },
|
||||
{
|
||||
text: "Reconstruction readiness",
|
||||
link: "/reconstruction-readiness",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -67,6 +64,11 @@ 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" },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -148,6 +148,11 @@ 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.
|
||||
|
||||
@@ -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"]
|
||||
COMPOSITION["src/composition/<br/>fresh typed provider and session factories<br/>one-shot binding and independent optional loading<br/>static WASM descriptor: named contract, factory, retryable lifetime"]
|
||||
end
|
||||
|
||||
subgraph "Adapters"
|
||||
@@ -27,6 +27,7 @@ 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"]
|
||||
@@ -94,6 +95,9 @@ 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
|
||||
|
||||
@@ -101,7 +101,9 @@ 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: ... })`; the large
|
||||
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
|
||||
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
|
||||
|
||||
@@ -193,7 +193,15 @@ validation and resource bounds. Omitted script metadata makes its affected
|
||||
section explicitly truncated.
|
||||
Disallowed-origin entries are filtered before retention.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -262,8 +262,13 @@ 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 decoded by the browser, not the compressed wire
|
||||
representation. No later fetch is substituted for the original response.
|
||||
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.
|
||||
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
|
||||
|
||||
+1
-1
@@ -93,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](product-catalog.json) lists all CLI commands and MCP
|
||||
The [generated catalog](mcp-contracts.md#generated-catalog) 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
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
# 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.
|
||||
|
||||
## 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.
|
||||
|
||||
## 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.
|
||||
@@ -0,0 +1,488 @@
|
||||
# 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. Its
|
||||
lifecycle checks attempt competing CLI launches for the active target and a
|
||||
different target, requiring rejection before either can change the owning
|
||||
MCP session's documents or procedures. Lease boundary tests also preserve
|
||||
unresponsive or malformed live endpoints while allowing confirmed stale
|
||||
sockets to recover.
|
||||
|
||||
`verify:hopper:fat` is a separate macOS lane requiring installed Hopper and the
|
||||
existing Xcode clang/lipo toolchain. It compiles arm64/x86-64 thin executables and
|
||||
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.
|
||||
@@ -123,8 +123,10 @@ 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. This milestone does
|
||||
not add MIPS/PPC/RISC-V decompilation, raw flash load profiles, bootloader/device
|
||||
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
|
||||
tree semantics, vulnerability scanning, emulation or hardware runtime capture.
|
||||
|
||||
## Resource and lifecycle policy
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
# 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).
|
||||
|
||||
## 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.
|
||||
@@ -0,0 +1,13 @@
|
||||
# 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.
|
||||
+7
-4
@@ -130,8 +130,9 @@ 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. Formats other than MZ and explicit COM return
|
||||
`unsupported` with measured observations, not a successful MZ verification.
|
||||
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.
|
||||
|
||||
`read_bytes` returns initialized provider memory, including loader fixups; an
|
||||
unmapped or uninitialized byte ends the read with an explicit returned length and
|
||||
@@ -150,8 +151,10 @@ 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. Raw COM files and DOS extenders
|
||||
without an admitted MZ real-mode entry are outside this import boundary.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
# 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 15-register ABI 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.
|
||||
+36
-6
@@ -1,6 +1,6 @@
|
||||
# IDA Pro provider
|
||||
# IDA provider
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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,7 +32,33 @@ 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.
|
||||
|
||||
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`.
|
||||
## 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.
|
||||
|
||||
The native MCP 1.1.2 release can navigate in the previously focused pseudocode tab when switching functions. Its producing navigation order must focus the disassembly view **before** jumping to the requested entry. Use a build including [upstream #7](https://github.com/0xshlomil/ida-free-mcp/pull/7), merged in `6adf2c615a2a03661059673e9c136ef28d0dc778`, or a release containing that correction. REA does not repair stale GUI output. Verify two different functions before claiming reliable switching. The initial Linux verification used a local version of this upstream correction.
|
||||
|
||||
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`.
|
||||
|
||||
## Give REA a target for headless analysis
|
||||
|
||||
@@ -58,7 +84,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 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.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -98,9 +124,9 @@ For guided registration, set `REA_IDA_MCP_CONFIG` before `rea setup --client <cl
|
||||
|
||||
## Coverage and evidence
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -110,4 +136,8 @@ 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.
|
||||
|
||||
To verify GUI function switching, add `--second-procedure other_function --second-marker unique_second_body_text`. 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 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.
|
||||
|
||||
@@ -43,4 +43,26 @@ 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.
|
||||
|
||||

|
||||
|
||||
+248
-436
@@ -1,84 +1,199 @@
|
||||
# Installation and setup
|
||||
|
||||
REA separates installing its CLI from configuring external software and agents.
|
||||
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) |
|
||||
|
||||
## Start setup
|
||||
|
||||
Start setup with:
|
||||
|
||||
```bash
|
||||
npx rea-agents setup
|
||||
```
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
The short command can use a REA version installed in the current project. To
|
||||
request the latest release explicitly, use:
|
||||
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:
|
||||
|
||||
```bash
|
||||
npx rea-agents@latest setup
|
||||
rea setup --client codex --client cursor --skill=false --dry-run
|
||||
```
|
||||
|
||||
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.
|
||||
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 an intentional rollback, make the package request explicit:
|
||||
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
|
||||
npm exec --yes --package=rea-agents@2.4.0 -- rea setup
|
||||
rea setup --yes --all-detected --install-hopper --json
|
||||
```
|
||||
|
||||
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.
|
||||
### Skill destinations
|
||||
|
||||
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.
|
||||
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 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.
|
||||
`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.
|
||||
|
||||
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.
|
||||
`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`.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
The optional curl wrapper installs only the global npm package:
|
||||
## 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.
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/morluto/rea/main/install.sh | bash
|
||||
rea update
|
||||
rea uninstall
|
||||
rea uninstall --purge-data
|
||||
```
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
Pass options with `bash -s --`:
|
||||
### Update the owning installation
|
||||
|
||||
```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.
|
||||
`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.
|
||||
|
||||
## Released package and main
|
||||
|
||||
@@ -143,8 +258,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 is
|
||||
listed after the table because its connector is not one of these files:
|
||||
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).
|
||||
|
||||
| Client | `--client` value |
|
||||
| ------------------ | ---------------- |
|
||||
@@ -165,356 +280,24 @@ listed after the table because its connector is not one of these files:
|
||||
| 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.
|
||||
|
||||
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.
|
||||
See [client configuration and troubleshooting](client-configuration.md) for
|
||||
configuration paths, profiles, trust policies, and schema-limit workarounds.
|
||||
|
||||
### 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.
|
||||
See [the Cordis patch and launcher setup](client-configuration.md#deepseek-harness).
|
||||
|
||||
### 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).
|
||||
See [OpenCode, Grok Build, and Grok Bot settings](client-configuration.md#other-client-settings).
|
||||
|
||||
## Hopper
|
||||
|
||||
@@ -650,29 +433,8 @@ 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.
|
||||
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.
|
||||
For cursor navigation, string decoding, symbol-name limits, and regex matching,
|
||||
see [Hopper analysis behavior](native-investigation.md#hopper-analysis-behavior).
|
||||
|
||||
Closing or switching a target closes its bound Hopper document, shuts down REA's
|
||||
bridge and removes its temporary socket directory while preserving the Hopper
|
||||
@@ -732,7 +494,8 @@ 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 and explicitly selected COM; PE returns its measurements with that limitation.
|
||||
supports DOS MZ, explicitly selected COM, and explicit raw-binary imports;
|
||||
PE returns measurements with an unsupported attestation status.
|
||||
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
|
||||
@@ -785,7 +548,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 mode-0700
|
||||
pathname would exceed the host's byte limit, REA allocates a separate owner-only
|
||||
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
|
||||
@@ -982,25 +745,6 @@ 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
|
||||
@@ -1033,3 +777,71 @@ 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.
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
# JavaScript artifact reconstruction
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Public workflow
|
||||
|
||||
@@ -105,141 +100,7 @@ only reduces delivery; source selection reduces text acquisition and analysis.
|
||||
Explicit native provider or snapshot routing rejects `--source-path` rather
|
||||
than ignoring it.
|
||||
|
||||
## 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.
|
||||
## Read the analysis
|
||||
|
||||
`analyze_javascript_application` returns the complete analysis Evidence by
|
||||
default. Select `"detail": "summary"` to retain that complete Evidence in the
|
||||
@@ -251,18 +112,82 @@ workflows as a retained reference. The summary does not repeat or truncate the
|
||||
analysis; a server without session retention refuses summary detail with
|
||||
`capability_unavailable`. CLI output is unchanged and always complete.
|
||||
|
||||
MCP prepares the complete repeated response incrementally against the pinned
|
||||
SDK's 10 MiB stdio receive-buffer budget. Oversized results return an actionable
|
||||
transport constraint and the exact same-session Evidence reference. Use
|
||||
`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.
|
||||
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.
|
||||
|
||||
## What is reconstructed
|
||||
|
||||
@@ -279,14 +204,6 @@ 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.
|
||||
|
||||
@@ -516,6 +433,110 @@ 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
|
||||
|
||||
@@ -26,6 +26,20 @@ 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.
|
||||
|
||||
## Shipped scope
|
||||
|
||||
The canonical parser admits PE/CLI bytes and their metadata/CIL without loading
|
||||
@@ -53,6 +67,12 @@ 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
|
||||
@@ -88,19 +108,39 @@ assembly. Older member Evidence without `selection` remains readable.
|
||||
|
||||
## Analysis objective
|
||||
|
||||
REA's managed-code track is intended to answer five different questions without
|
||||
collapsing them:
|
||||
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](#managednative-boundary-rules)
|
||||
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.
|
||||
|
||||
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?
|
||||
## Member comparison
|
||||
|
||||
The ordinary workflow ends at question four. Static analysis never loads or
|
||||
executes the target.
|
||||
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.
|
||||
|
||||
## NativeAOT metadata recovery
|
||||
|
||||
@@ -122,24 +162,38 @@ 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 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 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'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 as provider observations. Linking those types
|
||||
and report recovered type data with its returned provenance. 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.
|
||||
|
||||
## 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
|
||||
@@ -223,48 +277,6 @@ 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
|
||||
|
||||
+364
-304
@@ -1,14 +1,214 @@
|
||||
# MCP runtime contracts
|
||||
|
||||
## Generated catalog
|
||||
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.
|
||||
|
||||
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.
|
||||
## 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.
|
||||
|
||||
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.
|
||||
|
||||
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`, `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.
|
||||
|
||||
## Identity and discovery
|
||||
|
||||
@@ -23,94 +223,6 @@ 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
|
||||
@@ -172,15 +284,6 @@ 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
|
||||
@@ -216,8 +319,13 @@ 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 observed before completion returns `cancelled` and prevents the
|
||||
provisional result from entering the session ledger; prior Evidence stays usable.
|
||||
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.
|
||||
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
|
||||
@@ -229,6 +337,48 @@ 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.
|
||||
@@ -328,161 +478,6 @@ 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
|
||||
@@ -496,48 +491,6 @@ 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
|
||||
@@ -566,3 +519,110 @@ 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.
|
||||
|
||||
@@ -91,6 +91,12 @@ 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. |
|
||||
|
||||
+179
-122
@@ -1,132 +1,34 @@
|
||||
# Native UI and dispatch investigation
|
||||
<div id="native-ui-and-dispatch-investigation"></div>
|
||||
|
||||
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.
|
||||
# Native binary investigation
|
||||
|
||||
## Static inspection
|
||||
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.
|
||||
|
||||
`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.
|
||||
## Start with a function
|
||||
|
||||
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.
|
||||
Choose an installed provider from [setup](installation.md#hopper). For Ghidra:
|
||||
|
||||
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.
|
||||
```bash
|
||||
rea inspect /absolute/path/to/program --provider ghidra --json
|
||||
rea search /absolute/path/to/program entry --kind procedures --provider ghidra --json
|
||||
```
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
- `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.
|
||||
| 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) |
|
||||
|
||||
## Exact CLI selectors
|
||||
|
||||
@@ -272,6 +174,37 @@ 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
|
||||
@@ -322,6 +255,130 @@ 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.
|
||||
|
||||
+91
-73
@@ -40,7 +40,17 @@ this helper before reporting macOS capture as available.
|
||||
|
||||
## Capture a command
|
||||
|
||||
Write a JSON scenario and pass its path to the CLI:
|
||||
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:
|
||||
|
||||
```sh
|
||||
rea capture-process ./scenario.json --json > capture.json
|
||||
@@ -51,6 +61,85 @@ 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:
|
||||
|
||||
@@ -79,7 +168,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.
|
||||
|
||||
For example:
|
||||
### Scenario with interactions
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -327,74 +416,3 @@ while its token became unavailable after this change; npm changes its title
|
||||
as well. A newly started unreadable process can prevent verified cleanup even
|
||||
after the selected command exits. REA preserves this uncertainty and leaves
|
||||
that process untouched.
|
||||
|
||||
## Hash a report independently of terminal output
|
||||
|
||||
Select the producer's report directory and give `file_bytes` enough room for
|
||||
the complete files you need, including other files in those roots. For example,
|
||||
save this scenario and run `rea capture-process ./scenario.json --json > capture.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"executable": "node",
|
||||
"arguments": [
|
||||
"-e",
|
||||
"const fs=require('node:fs');fs.mkdirSync('reports',{recursive:true});fs.writeFileSync('reports/final.json',JSON.stringify({status:'complete',data:'X'.repeat(131072)}));console.log('x'.repeat(8192));"
|
||||
],
|
||||
"working_directory": ".",
|
||||
"filesystem_observation_paths": ["./reports"],
|
||||
"limits": { "output_bytes": 1024, "file_bytes": 262144 }
|
||||
}
|
||||
```
|
||||
|
||||
The report exceeds the terminal budget but fits the independent 256 KiB hash
|
||||
budget. Its complete SHA-256 appears in `normalized_result.files_after` at
|
||||
`root_0:final.json`; check `truncation_details.filesystem_after` for omissions
|
||||
and actual bytes hashed. The verbose terminal output is truncated without
|
||||
preventing the report digest. The same scenario object is the MCP
|
||||
`capture_process_scenario` input. REA never returns a prefix hash as a full-file
|
||||
digest: an insufficient remaining budget produces a null digest and an
|
||||
explicit omission reason.
|
||||
|
||||
A digest binds the complete bytes observed at that checkpoint, not the
|
||||
producer's notion of a finished report. A stable periodic or running report
|
||||
can also have a complete digest. Choose the final file and verify the
|
||||
producer's documented completion marker, exit outcome and settlement
|
||||
observations before calling it final. `after_settlement` names a filesystem
|
||||
checkpoint, not a guarantee that an application finished successfully or
|
||||
that an unobserved writer will never change the file. REA checks opened-file
|
||||
identity/state around hashing and reports observed changes or unavailable
|
||||
files; cancellation stops the hash. If an external sealer produces a manifest,
|
||||
keep its completion claims and digest separate from REA's checkpoint facts.
|
||||
|
||||
## Compare two captures
|
||||
|
||||
Compare saved capture Evidence with:
|
||||
|
||||
```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.
|
||||
|
||||
@@ -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 |
|
||||
| `declare-request` | exact target, operation, and lifecycle are carried by the request before launch |
|
||||
| `acquire-authority` | missing scope reported, narrow grant resumed, expansion reprompted, and denial launched nothing |
|
||||
| `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 |
|
||||
|
||||
+288
-643
File diff suppressed because it is too large
Load Diff
+6
-4
@@ -48,10 +48,12 @@ 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 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.
|
||||
- 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.
|
||||
- Keep observed, derived, and inferred relationships distinct. Preserve
|
||||
unresolved edges and partial provider facts instead of requiring every
|
||||
provider to supply the same metadata.
|
||||
|
||||
@@ -86,8 +86,22 @@ harm_rank,location,trigger,current_copy,user_risk,proposed_replacement,implement
|
||||
77,install.sh:node missing,node is absent,"Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+ is required; install it from nodejs.org and retry.",Low risk; exact versions and recovery,Keep current copy,unchanged,verified by shell branch inspection
|
||||
78,install.sh:npm missing,npm is absent,npm is required; install it with Node.js and retry.,Low risk; exact recovery,Keep current copy,unchanged,verified by shell branch inspection
|
||||
79,install.sh:node unreadable,node exists but does not report a parseable version,could not determine the active Node.js version.,No cause-local recovery,"The active Node.js version could not be read. Check that node works and is on PATH, then retry.",implemented,verified by exact unreadable-Node-version installer test
|
||||
80,install.sh:Node 22 floor,Node 22 minor version is below 19,"Node.js VERSION is unsupported; use Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+.",Low risk; exact detected version and supported alternatives,Keep current copy,unchanged,verified by exact installer test using Node 20 and branch inspection
|
||||
81,install.sh:Node 24 floor,Node 24 minor version is below 11,"Node.js VERSION is unsupported; use Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+.",Low risk; exact detected version and floor,Keep current copy,unchanged,verified by shell branch inspection
|
||||
80,install.sh:Node 22 floor,Node 22 minor version is below 19,"Node.js VERSION is unsupported; use Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+.",No install guidance; operator must guess between nvm/fnm/system packages/nodejs.org,"Node.js VERSION is unsupported.
|
||||
|
||||
REA requires Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+. Install one via:
|
||||
nvm: nvm install 24 && nvm use 24 (https://github.com/nvm-sh/nvm)
|
||||
fnm: fnm install 24 && fnm use 24 (https://github.com/Schniz/fnm)
|
||||
Direct download for OS/ARCH:
|
||||
https://nodejs.org/dist/latest-v24.x/ (grab the OS-ARCH tarball)
|
||||
Then rerun this installer.",implemented,verified by exact installer test using Node 20 against the `linux/x64` fake host and by shell branch inspection
|
||||
81,install.sh:Node 24 floor,Node 24 minor version is below 11,"Node.js VERSION is unsupported; use Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+.",No install guidance; operator must guess between nvm/fnm/system packages/nodejs.org,"Node.js VERSION is unsupported.
|
||||
|
||||
REA requires Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+. Install one via:
|
||||
nvm: nvm install 24 && nvm use 24 (https://github.com/nvm-sh/nvm)
|
||||
fnm: fnm install 24 && fnm use 24 (https://github.com/Schniz/fnm)
|
||||
Direct download for OS/ARCH:
|
||||
https://nodejs.org/dist/latest-v24.x/ (grab the OS-ARCH tarball)
|
||||
Then rerun this installer.",implemented,verified by shell branch inspection
|
||||
82,install.sh:version syntax,Explicit version is not exact semantic version,version must be an exact semantic version.,Low risk; exact correction,Keep current copy,unchanged,verified by shell branch inspection
|
||||
83,install.sh:release lookup,Latest GitHub release request fails,could not resolve the latest GitHub release.,No fallback despite supporting pinned versions,"The latest REA release could not be resolved. Check network access or pass --version VERSION, then retry.",implemented,verified by exact release-lookup installer test
|
||||
84,install.sh:release response,Latest release response is not valid expected JSON,Node JSON parser stack followed by the safe release-response message,Leaks a parser stack and buries recovery guidance,The release response was invalid. Retry later or pass --version VERSION.,implemented,verified by exact malformed-release test with parser stderr suppressed
|
||||
|
||||
|
@@ -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](../third_party/wabt/README.md) and
|
||||
See [WABT provenance](https://github.com/morluto/rea/blob/main/third_party/wabt/README.md) and
|
||||
[testing](testing.md#offline-wasm-artifacts) for real-tool verification.
|
||||
|
||||
@@ -48,9 +48,14 @@ 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`, matched to
|
||||
completed response bytes by transaction and event identity. URLs never select
|
||||
the response. Binary and empty retained bytes are written exactly.
|
||||
- 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.
|
||||
- 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.
|
||||
@@ -62,8 +67,9 @@ 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. Response bytes
|
||||
are browser-decoded bytes; they do not represent transfer encoding. Declared
|
||||
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
|
||||
redaction is preserved and can change JavaScript syntax; passive captures do
|
||||
not report a byte-redaction flag, so that value remains unknown.
|
||||
|
||||
|
||||
@@ -21,8 +21,10 @@ 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 load-image verification currently supports DOS MZ only. For x64 PE
|
||||
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
|
||||
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
|
||||
|
||||
@@ -0,0 +1,549 @@
|
||||
# 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: [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.
|
||||
|
||||
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 domain matrix is a growing roadmap; native PE and DOS, for
|
||||
example, remain unverified in this study. 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).
|
||||
@@ -0,0 +1,278 @@
|
||||
"""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
|
||||
|
||||
|
||||
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')
|
||||
args = parser.parse_args()
|
||||
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.'
|
||||
)
|
||||
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')
|
||||
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_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,
|
||||
'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', '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', '--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 = {}
|
||||
for line in (args.output / 'events.jsonl').open():
|
||||
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,
|
||||
'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:
|
||||
# Always remove copied credentials, config, caches and profile state.
|
||||
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()
|
||||
@@ -0,0 +1,171 @@
|
||||
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",
|
||||
"native_question",
|
||||
"javascript_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;
|
||||
@@ -0,0 +1,184 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
# 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. It preserves the attached GUI database.
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,695 @@
|
||||
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 { 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" },
|
||||
"native-question": { type: "string", default: "entry" },
|
||||
"javascript-question": { type: "string", default: "inventory" },
|
||||
schemas: { type: "string", default: "default" },
|
||||
},
|
||||
});
|
||||
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) ||
|
||||
(!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 info = await call("inspect_managed_artifact", { path: values.path });
|
||||
const boundaries = await call("inspect_managed_native_boundaries", {
|
||||
path: values.path,
|
||||
});
|
||||
return {
|
||||
artifact_sha256: targetSha(info),
|
||||
artifact: normalized(info),
|
||||
boundaries: normalized(boundaries),
|
||||
evidence_ids: [info.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,
|
||||
};
|
||||
};
|
||||
|
||||
const workflows = {
|
||||
"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 pkg = await call("inspect_android_package", { path: values.path });
|
||||
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: normalized(pkg).package_name,
|
||||
version_name: normalized(pkg).version_name,
|
||||
version_code: normalized(pkg).version_code,
|
||||
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,
|
||||
"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": async () => {
|
||||
const info = await call("inspect_evm_interface", {
|
||||
path: values.path,
|
||||
encoding: "hex",
|
||||
});
|
||||
const n = normalized(info);
|
||||
return {
|
||||
artifact_sha256: targetSha(info),
|
||||
artifact: n.artifact,
|
||||
bytecode: n.bytecode,
|
||||
functions: n.functions,
|
||||
discovery_completeness: n.discovery_completeness,
|
||||
runtime_execution: n.runtime_execution,
|
||||
limitations: n.limitations,
|
||||
evidence_ids: [info.evidence_id],
|
||||
};
|
||||
},
|
||||
...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,
|
||||
native_question: NATIVE_ARTIFACTS.includes(values.artifact)
|
||||
? values["native-question"]
|
||||
: null,
|
||||
javascript_question:
|
||||
values.artifact === "obsidian.asar" ? values["javascript-question"] : 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;
|
||||
@@ -0,0 +1,178 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,272 @@
|
||||
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");
|
||||
};
|
||||
@@ -0,0 +1,116 @@
|
||||
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;
|
||||
@@ -0,0 +1,85 @@
|
||||
import { mkdir, 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" },
|
||||
scenario: { type: "string" },
|
||||
output: { type: "string" },
|
||||
},
|
||||
});
|
||||
if (!values["runtime-root"] || !values.scenario || !values.output)
|
||||
throw new Error(
|
||||
"Use --runtime-root ABS --scenario JSON --output NEW_ABS_DIR",
|
||||
);
|
||||
await mkdir(values.output, { mode: 0o700 });
|
||||
const scenario = JSON.parse(await readFile(values.scenario, "utf8"));
|
||||
const client = new Client({ name: "rea-real-browser-app", version: "1" });
|
||||
const transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [resolve(values["runtime-root"], "scripts/rea.mjs"), "mcp"],
|
||||
env: {
|
||||
...process.env,
|
||||
REA_LOG_LEVEL: "silent",
|
||||
NODE_OPTIONS: "--max-old-space-size=512",
|
||||
},
|
||||
stderr: "pipe",
|
||||
});
|
||||
let failure;
|
||||
try {
|
||||
await client.connect(transport);
|
||||
transport.stderr?.resume();
|
||||
const reply = await client.callTool(
|
||||
{ name: "capture_browser_scenario", arguments: scenario },
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
await writeFile(resolve(values.output, "reply.json"), JSON.stringify(reply));
|
||||
const value =
|
||||
reply.structuredContent ??
|
||||
JSON.parse(
|
||||
reply.content.find((item) => item.type === "text")?.text ?? "null",
|
||||
);
|
||||
if (reply.isError) {
|
||||
failure = value.error;
|
||||
} else {
|
||||
const capture = value.normalized_result;
|
||||
await writeFile(
|
||||
resolve(values.output, "summary.json"),
|
||||
JSON.stringify(
|
||||
{
|
||||
evidence_id: value.evidence_id,
|
||||
browser: capture.browser,
|
||||
scenario: capture.scenario,
|
||||
completeness: capture.completeness,
|
||||
step_count: capture.steps.length,
|
||||
event_count: capture.events.retained,
|
||||
limitations: value.limitations,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
);
|
||||
process.stdout.write(
|
||||
JSON.stringify({
|
||||
evidence_id: value.evidence_id,
|
||||
browser: capture.browser,
|
||||
step_count: capture.steps.length,
|
||||
}) + "\n",
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
if (failure) {
|
||||
await writeFile(
|
||||
resolve(values.output, "failure.json"),
|
||||
JSON.stringify(failure, null, 2),
|
||||
);
|
||||
process.stdout.write(
|
||||
JSON.stringify({ code: failure.code, message: failure.message }) + "\n",
|
||||
);
|
||||
process.exitCode = 1;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"namespace_prefixes": ["REA_", "HOPPER_"],
|
||||
"additional_keys": [
|
||||
"GHIDRA_INSTALL_DIR",
|
||||
"JAVA_HOME",
|
||||
"JAVA_TOOL_OPTIONS",
|
||||
"JDK_JAVA_OPTIONS",
|
||||
"_JAVA_OPTIONS"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
Statically investigate the actual shipped APK at {{artifact_path}} using only the registered REA tools. Report the exact artifact SHA-256, package name, version name/code, every class-name match for the case-sensitive substring MainActivity, and all onCreate method descriptors reported for org.schabi.newpipe.MainActivity. Preserve reported signatures and explicit unknowns. For each onCreate entry include reported_signature, overload_index and dex_descriptor exactly as reported, preserving null. Final answer must be JSON with artifact_sha256, package_name, version_name, version_code, matches, onCreate, evidence_ids, limitations. Include real Evidence IDs supporting each result. Do not execute the APK or use shell, host file tools, network or other agents. Stop once these facts are supported.
|
||||
|
||||
When a client JavaScript executor is available, compose the required REA calls in one execution and return only selected facts from normalized_result, real Evidence IDs, target identity from subject.digest.sha256 and limitations. Parse original MCP text content if necessary. Do not return raw_result, whole Evidence or unrelated inventories. All matching classes and onCreate overloads must still be included.
|
||||
@@ -0,0 +1 @@
|
||||
Observe the real public Excalidraw application through REA capture_browser_scenario using exactly this authorized fresh-profile headless scenario: {"browser": {"mode": "launch", "executable_path": "/home/yann/.cache/ms-playwright/chromium-1234/chrome-linux64/chrome", "headless": true}, "start_url": {"url": "https://excalidraw.com/", "query": []}, "actions": [{"step_id": "settled", "action": "wait_for_timeout", "duration_ms": 2000}], "capture": {"at_end": ["url", "dom", "accessibility"], "events": ["network", "page-errors"]}}. Report actual browser product/version, start origin, final sanitized URL, DOM/accessibility artifact SHA-256 and byte counts when captured, step count, network/page-error observations, completeness, provider-owned process cleanup, real Evidence ID and limitations. Preserve unavailable and partial capture states. This is one runtime observation, not a claim about original source or all behavior. Do not supply credentials, interact with other targets or inject JavaScript. Final JSON fields: browser, start_origin, final_url, dom, accessibility, step_count, network, page_errors, completeness, evidence_ids, limitations.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inventory {{artifact_path}} using only the registered REA tools. Open this ASAR as an archive, inspect its artifact inventory, and close the session. Report exact target SHA-256, the complete inventory manifest, counts of every entry_kind across all occurrences, the original occurrence records for root paths package.json, main.js and preload.js if present, all integrity contradictions, inspection coverage, unexplored branches, real Evidence IDs and limitations. This question asks about package bytes and inventory, not AST interpretation or runtime behavior. Do not execute target code, analyze all JavaScript, extract files, launch a GUI, use shell/file tools/network or other agents. When a client JavaScript executor is available, compose original calls in dependency order and return only requested fields from normalized_result; the full inventory is the Evidence nested in the inspect_artifact inventory_artifact substep. Use Evidence.subject.digest.sha256 for the target identity and retain both inspection and inventory Evidence IDs. Final JSON fields: artifact_sha256, manifest, entry_kind_counts, requested_paths, integrity_contradictions, coverage, unexplored_branches, evidence_ids, limitations. Stop when these facts and cleanup are supported.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect the published historical WETH hex carrier at {{artifact_path}} using only REA inspect_evm_interface with encoding hex. Report original carrier SHA-256/byte count, decoded bytecode SHA-256/byte count, every inferred function selector with bytecode_offset, dispatch, inferred_arguments and inferred_state_mutability exactly including null. Preserve evidence_kind, discovery_completeness, bytecode kind/hardfork/deployment_authenticity, runtime_execution, real Evidence IDs and limitations. This file comes from the official Ethereum published historical eth_getCode example; do not infer live deployment authenticity, original source signatures or runtime behavior. No RPC, transactions, target execution, shell/file tools or other agents. Final JSON fields: artifact_sha256, artifact_bytes, bytecode_sha256, bytecode_bytes, functions, evidence_kind, discovery_completeness, bytecode_kind, hardfork, deployment_authenticity, runtime_execution, evidence_ids, limitations.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect {{artifact_path}} using only the registered REA tools. Report exact target SHA-256 and every reported firmware region with offsets, signatures, reported extents, provider provenance and examined coverage. Preserve unknowns and limitations; a signature scan does not prove partition boundaries or boot/runtime validity. Do not execute target code, extract files, launch a GUI, use shell/file tools/network or other agents. When a client JavaScript executor is available, select the requested normalized_result fields, Evidence.subject.digest.sha256 and real Evidence IDs before returning output. Final JSON fields: artifact_sha256, result, evidence_ids, limitations. Stop when the requested facts are supported.
|
||||
@@ -0,0 +1 @@
|
||||
Investigate the actual shipped Obsidian ASAR at {{artifact_path}} using REA analyze_javascript_application with source_paths ["package.json","main.js"] and detail summary. Keep complete inventory identity while analyzing only those exact sources. Read retained module views for each main.js module identity; module pages may contain several identities for a path, so preserve their exact node_id values. package.json is package metadata and need not be a module. Report selected input path/root artifact SHA-256, requested_paths and unselected_files, graph/statistics, Electron observations, exact selected main.js module identities/types/digests, analysis and semantic coverage, retained source Evidence ID, view Evidence IDs and limitations. Do not execute target JavaScript, analyze other sources, extract files, use network/shell/file tools or other agents. Static AST results do not prove actual runtime behavior or original source. Final JSON fields: input_path, artifact_sha256, source_selection, statistics, electron, modules, coverage, evidence_ids, limitations.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect the shipped ShareX HelpersLib assembly at {{artifact_path}} using only registered REA tools. Report exact target SHA-256 and module MVID, native ModuleRef/PInvoke/native-implementation counts, every original ModuleRef record, the first three complete PInvoke declaration records in producer order, coverage and limitations. Preserve tokens, import scope/name, flags, nulls and verification states exactly; declarations do not prove native-library/export availability or runtime behavior. No assembly load, native symbol lookup, target execution, GUI, shell/file tools, network or other agents. Final JSON fields: artifact_sha256, module_mvid, summary, module_refs, pinvoke_first3, coverage, evidence_ids, limitations. Stop once those selected facts are supported. Use compact selected evidence when the client supports it, but do not invent fields hidden by client output clipping.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect {{artifact_path}} using only the registered REA tools. Report exact target SHA-256, assembly name/version, module name/MVID, managed classification and architecture with its evidence, every reported target framework, and all declared native ModuleRef/PInvoke boundaries with coverage and limitations. Do not load or execute the assembly, launch a GUI, use shell/file tools/network or other agents. When a client JavaScript executor is available, compose the required original MCP calls and return only requested normalized_result fields, target identity from subject.digest.sha256 and real Evidence IDs. Do not return whole Evidence, raw_result or unrelated resources/custom-attribute inventories. Preserve dependency order for operations sharing the selected managed target. Final JSON fields: artifact_sha256, assembly, module, classification, target_frameworks, native_boundaries, coverage, evidence_ids, limitations. Stop when these facts are supported.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect {{artifact_path}} using only the registered REA tools and Ghidra. This is the original UPX-compressed FreeDOS EDLIN 2.24 DOS MZ executable; inspect its admitted load image and entry stub, without running or unpacking it. Keep default auto-analysis enabled. Open the target with provider_id ghidra, call inspect_native_load_image, and use its verified entry.linear_address as the seed. Resolve the containing procedure, analyze that procedure once, and close the ephemeral session after obtaining the facts. If a result is clipped, use retained native facets without reanalysis. Report exact target SHA-256, entry_address, containing_procedure, complete procedure metadata including classification, signature, locals and inclusive body ranges, the first 512 UTF-16 units of pseudocode, caller_count, callee_count, real Evidence IDs and limitations. Preserve missing/partial facts and terminal-flow caveats. Verified static import and unpacking-stub pseudocode do not prove DOS execution or recovery of the editor's application logic. Do not execute targets, launch a GUI, or use shell/file tools/network or other agents. Final JSON fields: artifact_sha256, load_image_status, entry_address, containing_procedure, procedure, pseudocode_prefix, caller_count, callee_count, evidence_ids, limitations. Stop when these facts and cleanup are supported; report unsupported outcomes explicitly.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect {{artifact_path}} using only the registered REA tools and Ghidra. The independently read, pinned PE32+ header reports image base 0x140000000 and entry RVA 0x125c0, so use address 0x1400125c0 as the analyst seed. This is a native x86-64 Windows PE component with no CLR directory, inspected on Linux; do not claim Windows runtime behavior. Keep default auto-analysis enabled. Open the target with provider_id ghidra, resolve the containing procedure, analyze that procedure once, and close the ephemeral session after obtaining the facts. If a result is clipped, use retained native facets without reanalysis. Report exact target SHA-256, entry_address, containing_procedure, complete procedure metadata including classification, signature, locals and inclusive body ranges, the first 512 UTF-16 units of pseudocode, caller_count, callee_count, real Evidence IDs and limitations. Preserve terminal-flow caveats and unresolved static edges; recovered pseudocode is not original source. Do not execute targets, launch a GUI, or use shell/file tools/network or other agents. Final JSON fields: artifact_sha256, entry_address, containing_procedure, procedure, pseudocode_prefix, caller_count, callee_count, evidence_ids, limitations. The seed applies only to the pinned ShareX.exe in corpus.json. Stop when these facts and cleanup are supported.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect {{artifact_path}} using only the registered REA tools and Ghidra. The pinned ELF header was independently observed to report entry address 0x403a50; treat that address as the analyst's seed, not as a function-name assumption. Keep default auto-analysis enabled and allow at least 600 seconds for native analysis (including the script deadline if using a bridge). Open the target with provider_id ghidra, resolve the containing procedure for that address, analyze it, and close the ephemeral session in a finally block or a subsequent cleanup call. Report exact target SHA-256, the entry_address, containing_procedure, procedure metadata, the first 512 UTF-16 units of pseudocode, caller_count, callee_count, real Evidence IDs and limitations. Do not execute target code, launch a GUI, use shell/file tools/network or other agents. When a client JavaScript executor is available, compose the original calls in dependency order and select requested fields before returning output; use Evidence.subject.digest.sha256 for the target identity. Final JSON fields: artifact_sha256, entry_address, containing_procedure, procedure, pseudocode_prefix, caller_count, callee_count, evidence_ids, limitations. The address seed applies only to the pinned jq artifact in corpus.json. Stop when these facts and cleanup are supported.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect the real shipped WASM module at {{artifact_path}} using only REA tools. Report exact selected artifact SHA-256, valid/invalid status, section count, import count, export count, first four complete export WAT forms in producer order, decoded WAT SHA-256 and code-unit length, WABT release/source commit, and exact runtime_execution/network_fetch states. If complete delivery exceeds the MCP frame, use the exact retained reference for summary and wasm exports views. Preserve original strings, uncertainties and real Evidence IDs. Do not execute WASM, fetch URLs or use shell/file tools. Final JSON fields: artifact_sha256, validation, section_count, import_count, export_count, exports_first4, wat_sha256, wat_code_units, wabt_release, wabt_source_commit, runtime_execution, network_fetch, evidence_ids, limitations.
|
||||
@@ -0,0 +1 @@
|
||||
Statically inspect the real shipped SQLite WASM at {{artifact_path}} using only REA tools. Report exact selected artifact SHA-256, valid/invalid status, section count, import count, export count, first four complete export WAT forms in producer order, decoded WAT SHA-256 and code-unit length, WABT release/source commit, and exact runtime_execution/network_fetch states. If complete delivery exceeds the MCP frame, use the exact retained reference for summary and wasm exports views. Preserve original strings, uncertainties and real Evidence IDs. Do not execute WASM, fetch URLs or use shell/file tools. Final JSON fields: artifact_sha256, validation, section_count, import_count, export_count, exports_first4, wat_sha256, wat_code_units, wabt_release, wabt_source_commit, runtime_execution, network_fetch, evidence_ids, limitations.
|
||||
@@ -0,0 +1,158 @@
|
||||
"""Run one owned experiment in a bounded, transient Linux systemd scope."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
|
||||
|
||||
def available_bytes():
|
||||
for line in Path('/proc/meminfo').read_text().splitlines():
|
||||
if line.startswith('MemAvailable:'):
|
||||
return int(line.split()[1]) * 1024
|
||||
raise RuntimeError('MemAvailable unavailable')
|
||||
|
||||
|
||||
def scope_has_processes(group):
|
||||
if group is None:
|
||||
return False
|
||||
try:
|
||||
return bool((group / 'cgroup.procs').read_text().strip())
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
|
||||
|
||||
def final_resource_events(group):
|
||||
"""An exited transient cgroup may disappear; missing counters are unknown."""
|
||||
if group is None:
|
||||
return None
|
||||
try:
|
||||
result = {name: dict((key, int(value)) for key, value in
|
||||
(line.split() for line in (group / name).read_text().splitlines()))
|
||||
for name in ['memory.events', 'pids.events']}
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
required = {'memory.events': ['high', 'max', 'oom', 'oom_kill'],
|
||||
'pids.events': ['max']}
|
||||
if not all(all(key in result[name] for key in keys)
|
||||
for name, keys in required.items()):
|
||||
return None
|
||||
return result
|
||||
|
||||
|
||||
def stop_owned_scope(unit, process, group):
|
||||
subprocess.run(['systemctl', '--user', 'stop', '--no-block', unit],
|
||||
check=False, timeout=5)
|
||||
for attempt in range(2):
|
||||
deadline = time.monotonic() + 10
|
||||
while process.poll() is None or scope_has_processes(group):
|
||||
if time.monotonic() >= deadline:
|
||||
break
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
return
|
||||
if attempt == 1:
|
||||
raise RuntimeError('Cleanup unverified; retain owned scope ' + unit)
|
||||
subprocess.run(['systemctl', '--user', 'kill', '--kill-who=all',
|
||||
'--signal=SIGKILL', unit], check=False, timeout=5)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--task-ceiling', type=int, default=192)
|
||||
parser.add_argument('command', nargs=argparse.REMAINDER)
|
||||
options = parser.parse_args()
|
||||
if options.task_ceiling <= 0:
|
||||
parser.error('--task-ceiling must be positive')
|
||||
args = options.command
|
||||
if args and args[0] == '--':
|
||||
args = args[1:]
|
||||
if not args:
|
||||
raise SystemExit('Usage: resource-run.py -- COMMAND ARGS...')
|
||||
gib = 1024 ** 3
|
||||
if available_bytes() < 8 * gib:
|
||||
raise SystemExit('Refusing experiment: less than 8 GiB available')
|
||||
unit = 'rea-efficiency-' + uuid.uuid4().hex + '.scope'
|
||||
cpu = max(os.sched_getaffinity(0))
|
||||
command = [
|
||||
'systemd-run', '--user', '--scope', '--unit=' + unit,
|
||||
'-p', 'MemoryMax=4G', '-p', 'MemoryHigh=3G', '-p', 'MemorySwapMax=0',
|
||||
'-p', 'CPUQuota=100%', '-p', 'TasksMax=' + str(options.task_ceiling),
|
||||
'taskset', '-c', str(cpu), *args,
|
||||
]
|
||||
process = subprocess.Popen(command)
|
||||
peak = 0
|
||||
peak_tasks = 0
|
||||
events = {}
|
||||
cpu_stats = {}
|
||||
abort = None
|
||||
final_events = None
|
||||
started = time.monotonic()
|
||||
try:
|
||||
group = None
|
||||
while process.poll() is None:
|
||||
if group is None:
|
||||
reply = subprocess.run(
|
||||
['systemctl', '--user', 'show', unit, '--value',
|
||||
'--property=ControlGroup'],
|
||||
capture_output=True, text=True, check=False,
|
||||
)
|
||||
path = reply.stdout.strip()
|
||||
if path:
|
||||
group = Path('/sys/fs/cgroup') / path.lstrip('/')
|
||||
current = group / 'memory.current' if group else None
|
||||
if current and current.exists():
|
||||
try:
|
||||
peak = max(peak, int(current.read_text()))
|
||||
peak_tasks = max(peak_tasks, int((group / 'pids.current').read_text()))
|
||||
cpu_stats = dict((key, int(value)) for key, value in
|
||||
(line.split() for line in (group / 'cpu.stat').read_text().splitlines()))
|
||||
for event_file in ['memory.events', 'pids.events']:
|
||||
events[event_file] = dict(
|
||||
(key, int(value)) for key, value in
|
||||
(line.split() for line in (group / event_file).read_text().splitlines())
|
||||
)
|
||||
except FileNotFoundError:
|
||||
# A completed transient scope can disappear between reads.
|
||||
pass
|
||||
if peak > 3 * gib:
|
||||
abort = 'scope_memory_early_stop'
|
||||
elif available_bytes() < 4 * gib:
|
||||
abort = 'host_available_memory_early_stop'
|
||||
elif events.get('pids.events', {}).get('max', 0):
|
||||
abort = 'scope_task_limit_observed'
|
||||
if abort:
|
||||
stop_owned_scope(unit, process, group)
|
||||
break
|
||||
time.sleep(0.1)
|
||||
# Read while the owned group still exists, before wait/cleanup can remove it.
|
||||
final_events = final_resource_events(group)
|
||||
code = process.wait()
|
||||
except BaseException:
|
||||
stop_owned_scope(unit, process, group)
|
||||
raise
|
||||
finally:
|
||||
if scope_has_processes(group):
|
||||
final_events = None
|
||||
stop_owned_scope(unit, process, group)
|
||||
print(json.dumps({
|
||||
'resource_scope': unit, 'peak_cgroup_bytes_sampled': peak,
|
||||
'elapsed_seconds': round(time.monotonic() - started, 3),
|
||||
'abort': abort, 'hard_memory_bytes': 4 * gib,
|
||||
'early_stop_bytes': 3 * gib, 'cpu_quota_percent': 100,
|
||||
'cpu_affinity': [cpu],
|
||||
'task_ceiling': options.task_ceiling, 'peak_tasks_sampled': peak_tasks,
|
||||
'resource_events_last_observed': events,
|
||||
'resource_events_final': final_events,
|
||||
'resource_counters_verified': final_events is not None,
|
||||
'cpu_stat_last_observed': cpu_stats,
|
||||
}), file=sys.stderr)
|
||||
raise SystemExit(125 if abort else code)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,309 @@
|
||||
"""Check selected model facts against public producer observations, not exit status."""
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
|
||||
def read(path):
|
||||
return json.loads(path.read_text())
|
||||
|
||||
|
||||
def strings(value):
|
||||
if isinstance(value, str):
|
||||
yield value
|
||||
elif isinstance(value, list):
|
||||
for entry in value:
|
||||
yield from strings(entry)
|
||||
elif isinstance(value, dict):
|
||||
for entry in value.values():
|
||||
yield from strings(entry)
|
||||
|
||||
|
||||
def evidence_ids(value):
|
||||
return {s for s in strings(value) if re.fullmatch(r'ev_[a-f0-9]{64}', s)}
|
||||
|
||||
|
||||
def decode(result):
|
||||
value = result.get('structured_content', result.get('structuredContent'))
|
||||
if value is not None:
|
||||
return value
|
||||
for entry in result.get('content', []):
|
||||
if entry.get('type') == 'text':
|
||||
try:
|
||||
return json.loads(entry['text'])
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--domain', choices=['wasm', 'evm', 'android', 'managed', 'managed-nonempty', 'firmware', 'inventory', 'javascript', 'native', 'browser'], required=True)
|
||||
parser.add_argument('--trial', type=Path, required=True)
|
||||
parser.add_argument('--reference', type=Path)
|
||||
parser.add_argument('--resource-log', type=Path, required=True)
|
||||
parser.add_argument('--output', type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
summary = read(args.trial / 'summary.json')
|
||||
settings = read(args.trial / 'trial-settings.json')
|
||||
answer_text = (args.trial / 'answer.txt').read_text().strip()
|
||||
fenced = answer_text.startswith('```json\n') and answer_text.endswith('\n```')
|
||||
answer = json.loads(answer_text[8:-4] if fenced else answer_text)
|
||||
reference = read(args.reference / 'answer.json') if args.reference else None
|
||||
observed_ids = set()
|
||||
producer_results = {}
|
||||
tool_errors = []
|
||||
for line in (args.trial / 'events.jsonl').open():
|
||||
event = json.loads(line)
|
||||
item = event.get('item', {})
|
||||
if event.get('type') != 'item.completed' or item.get('type') != 'mcp_tool_call':
|
||||
continue
|
||||
result = item.get('result') or {}
|
||||
parsed = decode(result)
|
||||
if item['status'] == 'completed':
|
||||
# Only response text contributes observed IDs, never model arguments.
|
||||
for text in strings(result):
|
||||
observed_ids.update(re.findall(r'ev_[a-f0-9]{64}', text))
|
||||
if parsed is not None:
|
||||
producer_results.setdefault(item['tool'], []).append(parsed)
|
||||
else:
|
||||
tool_errors.append({'tool': item['tool'], 'arguments': item['arguments'], 'response': parsed if parsed is not None else result})
|
||||
if parsed is not None and parsed.get('error', {}).get('code') == 'resource_constraint':
|
||||
reference_value = parsed['error'].get('details', {}).get('reported_limits', {}).get('evidence_reference')
|
||||
observed_ids.update(evidence_ids(reference_value))
|
||||
reported_ids = evidence_ids(answer.get('evidence_ids'))
|
||||
checks = {
|
||||
'reported_evidence_ids_observed_in_responses': bool(reported_ids) and reported_ids <= observed_ids,
|
||||
'temporary_profile_removed': read(args.trial / 'cleanup.json')['profile_removed'],
|
||||
}
|
||||
if summary.get('selected_artifact_sha256_before') is not None:
|
||||
checks['selected_artifact_bytes_unchanged'] = summary['selected_artifact_bytes_unchanged']
|
||||
if reference is not None:
|
||||
checks['target_digest'] = answer.get('artifact_sha256') == reference['artifact_sha256']
|
||||
differences = {}
|
||||
|
||||
def check(name, actual, expected):
|
||||
checks[name] = actual == expected
|
||||
if not checks[name]:
|
||||
differences[name] = {'answer': actual, 'producer': expected}
|
||||
|
||||
domain = args.domain
|
||||
if domain == 'wasm':
|
||||
for key in ['validation', 'section_count', 'import_count', 'export_count', 'exports_first4', 'wat_sha256', 'wat_code_units', 'runtime_execution', 'network_fetch']:
|
||||
check(key, answer.get(key), reference[key])
|
||||
for key in ['release', 'source_commit']:
|
||||
check('wabt_' + key, answer.get('wabt_' + key), reference['tool_profile'][key])
|
||||
elif domain == 'evm':
|
||||
n = producer_results['inspect_evm_interface'][-1]['normalized_result']
|
||||
for key, expected in {'artifact_bytes': n['artifact']['bytes'], 'bytecode_sha256': n['bytecode']['sha256'], 'bytecode_bytes': n['bytecode']['bytes'], 'functions': n['functions'], 'evidence_kind': n['evidence_kind'], 'discovery_completeness': n['discovery_completeness'], 'runtime_execution': n['runtime_execution'], 'bytecode_kind': n['bytecode']['kind'], 'hardfork': n['bytecode']['hardfork'], 'deployment_authenticity': n['bytecode']['deployment_authenticity']}.items():
|
||||
check(key, answer.get(key), expected)
|
||||
elif domain == 'android':
|
||||
for key in ['package_name', 'version_name', 'version_code', 'matches']:
|
||||
check(key, answer.get(key), reference[key])
|
||||
fields = ['reported_signature', 'overload_index', 'dex_descriptor']
|
||||
checks['onCreate_fields_present_including_explicit_null'] = all(all(k in row for k in fields) for row in answer.get('onCreate', []))
|
||||
check('all_onCreate_descriptors', [{k: row.get(k) for k in fields} for row in answer.get('onCreate', [])], [{k: row[k] for k in fields} for row in reference['onCreate']])
|
||||
elif domain == 'managed':
|
||||
n = reference['artifact']
|
||||
for group, fields in [('assembly', ['name', 'version']), ('module', ['name', 'mvid'])]:
|
||||
for field in fields:
|
||||
check(group + '.' + field, answer.get(group, {}).get(field), n[group][field])
|
||||
for key in ['classification', 'target_frameworks']:
|
||||
check(key, answer.get(key), n[key])
|
||||
for key in ['module_refs', 'pinvoke_imports']:
|
||||
check(key, answer.get('native_boundaries', {}).get(key), reference['boundaries'][key])
|
||||
check('artifact_coverage', answer.get('coverage', {}).get('artifact'), n['coverage'])
|
||||
check('native_boundaries_coverage', answer.get('coverage', {}).get('native_boundaries'), reference['boundaries']['coverage'])
|
||||
elif domain == 'managed-nonempty':
|
||||
n = reference['boundaries']
|
||||
check('module_mvid', answer.get('module_mvid'), n['module']['mvid'])
|
||||
check('summary', {key: answer.get('summary', {}).get(key) for key in n['summary']}, n['summary'])
|
||||
check('all_original_module_refs', answer.get('module_refs'), n['module_refs'])
|
||||
check('first3_complete_pinvoke_records', answer.get('pinvoke_first3'), n['pinvoke_imports'][:3])
|
||||
check('coverage', answer.get('coverage'), n['coverage'])
|
||||
elif domain == 'firmware':
|
||||
source = producer_results['inspect_firmware_regions'][-1]
|
||||
n = source['normalized_result']
|
||||
result = answer['result']
|
||||
check('input_size', result.get('input_size'), n['input_size'])
|
||||
check('examined_coverage', result.get('coverage', result.get('examined_coverage')), n['coverage'])
|
||||
fields = ['provider_id', 'offset', 'reported_size', 'signature', 'description', 'reported_confidence', 'size_basis']
|
||||
check('all_original_region_records', [{k: row.get(k) for k in fields} for row in result.get('regions', [])], [{k: row[k] for k in fields} for row in n['regions']])
|
||||
engine = result.get('engine', result.get('provider_provenance', {}).get('engine', {}))
|
||||
for key in ['name', 'version']:
|
||||
check('engine.' + key, engine.get(key), n['engine'][key])
|
||||
check('engine_executable_digest', engine.get('executable_sha256', engine.get('artifact_sha256')), n['engine']['executable_sha256'])
|
||||
elif domain == 'inventory':
|
||||
for key in ['manifest', 'entry_kind_counts', 'integrity_contradictions']:
|
||||
check(key, answer.get(key), reference[key])
|
||||
original = producer_results['inspect_artifact'][-1]['normalized_result']
|
||||
if original.get('kind') == 'summary':
|
||||
branches = original['summary']['inspection']['unexplored_branches']
|
||||
else:
|
||||
branches = original['unexplored_branches']
|
||||
# Caller-selected integrity policy participates in atomic Evidence and
|
||||
# branch identity. Match those IDs to this original response, not a
|
||||
# reference invocation that may use a different policy.
|
||||
check('unexplored_branches_with_original_ids', answer.get('unexplored_branches'), branches)
|
||||
coverage = answer.get('coverage', {})
|
||||
check('inspection_coverage', coverage.get('inspection', coverage), reference['coverage'])
|
||||
paths = answer.get('requested_paths')
|
||||
if isinstance(paths, dict):
|
||||
paths = [row for value in paths.values() for row in (value if isinstance(value, list) else [value]) if row is not None]
|
||||
canonical = lambda row: json.dumps(row, sort_keys=True, separators=(',', ':'))
|
||||
check('original_selected_path_records', sorted(map(canonical, paths or [])), sorted(map(canonical, reference['requested_paths'])))
|
||||
elif domain == 'javascript':
|
||||
for key in ['input_path', 'source_selection', 'statistics', 'electron']:
|
||||
check(key, answer.get(key), reference[key])
|
||||
coverage = answer['coverage']
|
||||
expected = reference['coverage']
|
||||
for key in ['application_unknowns', 'semantic_unknowns']:
|
||||
check('coverage.' + key, coverage.get(key), expected[key])
|
||||
for layer in ['application', 'semantic']:
|
||||
for key, value in expected[layer].items():
|
||||
if key in ['limits', 'families']: continue
|
||||
check('coverage.' + layer + '.' + key, coverage[layer].get(key), value)
|
||||
# Budgets vary with parent heap and belong to this actual invocation.
|
||||
# Exact optional provenance remains a separate strict check; omissions
|
||||
# must not be hidden by accepting the coarse coverage summary.
|
||||
original = producer_results['analyze_javascript_application'][-1]['normalized_result']['summary']['coverage']
|
||||
check('full_coverage_provenance', coverage, original)
|
||||
# The question names types/digests, not literal answer property names.
|
||||
# Exact node IDs select the producer's main.js records. No source or
|
||||
# Evidence values are rewritten to accept these answer labels.
|
||||
select = lambda rows: sorted([{
|
||||
'node_id': row.get('node_id'),
|
||||
'kind': row.get('kind', row.get('type')),
|
||||
'identity': row.get('identity'),
|
||||
'hashes': row.get('hashes', row.get('digests')),
|
||||
} for row in rows], key=lambda row: row['node_id'])
|
||||
check('all_selected_module_identities', select(answer.get('modules', [])), select(reference['modules']))
|
||||
elif domain == 'native':
|
||||
for key in ['entry_address', 'caller_count', 'callee_count']:
|
||||
check(key, answer.get(key), reference[key])
|
||||
prefix = answer.get('pseudocode_prefix')
|
||||
if isinstance(prefix, dict) and prefix.get('unit') == 'utf16-code-units':
|
||||
text = prefix.get('text')
|
||||
if 'requested' in prefix:
|
||||
check('pseudocode_prefix.requested', prefix['requested'], 512)
|
||||
if 'returned' in prefix:
|
||||
check('pseudocode_prefix.returned', prefix['returned'], len(reference['pseudocode_prefix'].encode('utf-16-le')) // 2)
|
||||
prefix = text
|
||||
check('pseudocode_prefix', prefix, reference['pseudocode_prefix'])
|
||||
containing = answer.get('containing_procedure')
|
||||
expected_containing = reference['containing_procedure']['procedure']
|
||||
if isinstance(containing, str):
|
||||
# Compare the explicitly reported display to the known source;
|
||||
# never parse a display name into a canonical lookup identity.
|
||||
check('containing_procedure.display', containing,
|
||||
expected_containing['name'] + ' @ ' + expected_containing['address'])
|
||||
else:
|
||||
containing = containing if isinstance(containing, dict) else {}
|
||||
nested = containing.get('procedure')
|
||||
nested = nested if isinstance(nested, dict) else {}
|
||||
for key in ['address', 'name']:
|
||||
check('containing_procedure.' + key, containing.get(key, nested.get(key)), expected_containing[key])
|
||||
procedure = answer.get('procedure')
|
||||
procedure = procedure if isinstance(procedure, dict) else {}
|
||||
expected = reference['procedure']
|
||||
for key in ['address', 'name', 'classification', 'signature', 'locals']:
|
||||
check('procedure.' + key, procedure.get(key), expected[key])
|
||||
body = procedure.get('body')
|
||||
body = body if isinstance(body, dict) else {}
|
||||
check('procedure.body_ranges', procedure.get('body_ranges', body.get('ranges', body.get('ranges_inclusive'))), expected['body']['ranges'])
|
||||
check('procedure.total_bytes', procedure.get('total_bytes', body.get('total_bytes')), expected['body']['total_bytes'])
|
||||
if 'load_image' in reference:
|
||||
sources = [source for source in producer_results.get('inspect_native_load_image', [])
|
||||
if isinstance(source, dict)
|
||||
and source.get('operation') == 'inspect_native_load_image'
|
||||
and isinstance(source.get('evidence_id'), str)
|
||||
and source.get('evidence_id') in reported_ids
|
||||
and isinstance(source.get('normalized_result'), dict)]
|
||||
checks['load_image_source_observed_and_referenced'] = bool(sources)
|
||||
load = sources[-1]['normalized_result'] if sources else {}
|
||||
entry = load.get('entry')
|
||||
entry = entry if isinstance(entry, dict) else {}
|
||||
check('load_image.target_sha256', load.get('target_sha256'), reference['artifact_sha256'])
|
||||
check('load_image.source_status', load.get('status'), reference['load_image']['status'])
|
||||
check('load_image.source_entry', entry.get('linear_address'), reference['entry_address'])
|
||||
status = answer.get('load_image_status')
|
||||
check('load_image_status', status.get('status') if isinstance(status, dict) else status, load.get('status'))
|
||||
if isinstance(status, dict):
|
||||
for key in ['format', 'load_segment', 'header_bytes', 'module_bytes', 'overlay_bytes']:
|
||||
if key in status:
|
||||
check('load_image.' + key, status[key], load.get(key))
|
||||
if 'entry_linear_address' in status:
|
||||
check('load_image.entry_linear_address', status['entry_linear_address'], entry.get('linear_address'))
|
||||
calls = summary['completed_mcp_calls']
|
||||
checks['default_analysis_not_disabled'] = all(not call['arguments'].get('skip_auto_analysis', False) for call in calls if call['tool'] == 'open_binary')
|
||||
checks['session_close_completed'] = any(call['tool'] == 'close_binary' and call['status'] == 'completed' for call in calls)
|
||||
elif domain == 'browser':
|
||||
source = producer_results['capture_browser_scenario'][-1]
|
||||
n = source['normalized_result']
|
||||
for key in ['browser', 'completeness']:
|
||||
check(key, answer.get(key), n[key])
|
||||
check('start_origin', answer.get('start_origin'), n['scenario']['start_origin'])
|
||||
step_count = answer.get('step_count')
|
||||
check('step_count', step_count.get('captured_steps') if isinstance(step_count, dict) else step_count, len(n['steps']))
|
||||
final = n['steps'][-1]
|
||||
expected_url = final['after_url'] if isinstance(answer.get('final_url'), dict) else final['after_url']['url']
|
||||
check('final_url', answer.get('final_url'), expected_url)
|
||||
for key in ['dom', 'accessibility']:
|
||||
expected = final['artifacts'][key]
|
||||
actual = answer.get(key, {})
|
||||
if expected['state'] == 'captured':
|
||||
actual = actual.get('value', actual)
|
||||
for field in ['sha256', 'bytes']:
|
||||
check(key + '.' + field, actual.get(field), expected['value'][field])
|
||||
else:
|
||||
check(key + '.state', actual.get('state'), expected['state'])
|
||||
checks['owned_browser_terminated'] = n['browser']['cleanup'] == 'terminated-owned-process'
|
||||
events = n['events']['items']
|
||||
page_errors = [event for event in events if event['kind'] == 'page-error']
|
||||
if isinstance(answer.get('page_errors'), dict):
|
||||
check('page_error_count', answer['page_errors'].get('count'), len(page_errors))
|
||||
network = answer.get('network', {})
|
||||
if 'observed_transactions' in network:
|
||||
check('network_transaction_count', network['observed_transactions'], len({event['transaction_id'] for event in events if event.get('transaction_id') is not None}))
|
||||
if 'observed_response_statuses' in network:
|
||||
statuses = {}
|
||||
for event in events:
|
||||
if event['kind'] == 'response':
|
||||
status = str(event['status'])
|
||||
statuses[status] = statuses.get(status, 0) + 1
|
||||
check('network_response_statuses', network['observed_response_statuses'], statuses)
|
||||
scopes = [json.loads(line) for line in args.resource_log.read_text().splitlines() if line.startswith('{')]
|
||||
scope = next(value for value in reversed(scopes) if 'resource_scope' in value)
|
||||
checks['no_resource_abort'] = scope['abort'] is None
|
||||
events = scope.get('resource_events_final')
|
||||
checks['resource_counters_verified'] = scope.get('resource_counters_verified') is True
|
||||
checks['no_observed_oom_or_task_limit'] = (
|
||||
isinstance(events, dict)
|
||||
and all(events.get('memory.events', {}).get(k) == 0 for k in ['max', 'oom', 'oom_kill'])
|
||||
and events.get('pids.events', {}).get('max') == 0
|
||||
)
|
||||
checks['no_resource_limit_event'] = (
|
||||
checks['resource_counters_verified']
|
||||
and checks['no_observed_oom_or_task_limit']
|
||||
and events['memory.events'].get('high') == 0
|
||||
)
|
||||
report = {
|
||||
'review_source_sha256': hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),
|
||||
'domain': domain, 'checks': checks, 'all_selected_checks_pass': all(checks.values()),
|
||||
'differences': differences, 'tool_errors': tool_errors, 'summary': summary,
|
||||
'fingerprints': {key: value for key, value in settings.items() if 'sha256' in key or key in ['runtime_revision', 'enabled_tools', 'authority']},
|
||||
'answer_file_sha256': hashlib.sha256((args.trial / 'answer.txt').read_bytes()).hexdigest(),
|
||||
'answer_had_json_fence': fenced, 'reported_evidence_ids': sorted(reported_ids), 'resource': scope,
|
||||
'scope': 'Fixed selected-fact review against actual public producer observations. Equivalent explicitly named answer representations are accepted; unknowns/nulls remain checked. Limitations, unsupported claims and broader behavior still require transcript review. Token usage and failed calls are retained; zero exit status is not a factual grade.',
|
||||
}
|
||||
with args.output.open('x') as output:
|
||||
output.write(json.dumps(report, indent=2, ensure_ascii=False) + '\n')
|
||||
print(json.dumps({'domain': domain, 'passed': report['all_selected_checks_pass'], 'failed_checks': [key for key, value in checks.items() if not value]}))
|
||||
raise SystemExit(0 if report['all_selected_checks_pass'] else 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,163 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { createHash } from "node:crypto";
|
||||
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
||||
import { isAbsolute, 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" },
|
||||
revision: { type: "string" },
|
||||
bundle: { type: "string" },
|
||||
"inspection-reply": { type: "string" },
|
||||
output: { type: "string" },
|
||||
},
|
||||
});
|
||||
for (const key of ["runtime-root", "bundle", "inspection-reply", "output"])
|
||||
assert.ok(values[key] && isAbsolute(values[key]), `Supply --${key} ABS`);
|
||||
assert.ok(values.revision);
|
||||
await mkdir(values.output, { mode: 0o700 });
|
||||
const sha = (value) => createHash("sha256").update(value).digest("hex");
|
||||
const bundleBytes = await readFile(values.bundle);
|
||||
const oldBundle = JSON.parse(bundleBytes.toString("utf8"));
|
||||
const oldWasm = oldBundle.records.find(
|
||||
(record) => record.operation === "inspect_wasm_artifact",
|
||||
);
|
||||
assert.ok(oldWasm);
|
||||
const inspectionBytes = await readFile(values["inspection-reply"]);
|
||||
const oldInspection = JSON.parse(
|
||||
inspectionBytes.toString("utf8"),
|
||||
).structuredContent;
|
||||
assert.equal(oldInspection.operation, "inspect_artifact");
|
||||
const definitions = new Map();
|
||||
const client = new Client({
|
||||
name: "rea-real-evidence-migration",
|
||||
version: "1",
|
||||
});
|
||||
// An absent explicitly selected WABT directory makes accidental re-analysis
|
||||
// fail. Imported/portable views must operate on existing Evidence alone.
|
||||
const transport = new StdioClientTransport({
|
||||
command: process.execPath,
|
||||
args: [resolve(values["runtime-root"], "scripts/rea.mjs"), "mcp"],
|
||||
env: {
|
||||
...process.env,
|
||||
REA_LOG_LEVEL: "silent",
|
||||
NODE_OPTIONS: "--max-old-space-size=512",
|
||||
REA_WABT_BIN_DIRECTORY: resolve(values.output, "absent-wabt"),
|
||||
},
|
||||
stderr: "pipe",
|
||||
});
|
||||
const calls = [];
|
||||
const call = async (name, arguments_) => {
|
||||
const reply = await client.callTool(
|
||||
{ name, arguments: arguments_ },
|
||||
{ toolDefinition: definitions.get(name), timeout: 120_000 },
|
||||
);
|
||||
await writeFile(
|
||||
resolve(values.output, `call-${calls.length + 1}.json`),
|
||||
JSON.stringify(reply),
|
||||
);
|
||||
assert.notEqual(reply.isError, true, JSON.stringify(reply));
|
||||
const result = reply.structuredContent ?? JSON.parse(reply.content[0].text);
|
||||
calls.push({
|
||||
name,
|
||||
arguments:
|
||||
name === "inspect_analysis_view" && arguments_.source.kind === "inline"
|
||||
? {
|
||||
source: {
|
||||
kind: "inline",
|
||||
original_evidence_id: arguments_.source.evidence.evidence_id,
|
||||
},
|
||||
view: arguments_.view,
|
||||
}
|
||||
: arguments_,
|
||||
evidence_id: result.evidence_id ?? null,
|
||||
});
|
||||
return result;
|
||||
};
|
||||
let report;
|
||||
try {
|
||||
await client.connect(transport);
|
||||
transport.stderr?.resume();
|
||||
for (const definition of (await client.listTools()).tools)
|
||||
definitions.set(definition.name, definition);
|
||||
await call("import_evidence_bundle", { path: values.bundle });
|
||||
const source = {
|
||||
kind: "retained-evidence",
|
||||
evidence_id: oldWasm.evidence_id,
|
||||
};
|
||||
const summary = await call("inspect_analysis_view", {
|
||||
source,
|
||||
view: { kind: "summary" },
|
||||
});
|
||||
const exports = await call("inspect_analysis_view", {
|
||||
source,
|
||||
view: { kind: "wasm", facet: "exports", offset: 0, limit: 4 },
|
||||
});
|
||||
assert.equal(
|
||||
summary.normalized_result.parent_evidence_id,
|
||||
oldWasm.evidence_id,
|
||||
);
|
||||
assert.equal(summary.subject.digest.sha256, oldWasm.subject.digest.sha256);
|
||||
assert.equal(
|
||||
summary.normalized_result.summary.wat.sha256,
|
||||
oldWasm.normalized_result.wat.sha256,
|
||||
);
|
||||
assert.deepEqual(
|
||||
exports.normalized_result.item,
|
||||
oldWasm.normalized_result.exports.slice(0, 4),
|
||||
);
|
||||
const inventory = await call("inspect_analysis_view", {
|
||||
source: { kind: "inline", evidence: oldInspection },
|
||||
view: { kind: "summary" },
|
||||
});
|
||||
assert.equal(
|
||||
inventory.normalized_result.parent_evidence_id,
|
||||
oldInspection.evidence_id,
|
||||
);
|
||||
const oldAtomic = oldInspection.normalized_result.substeps[0].evidence;
|
||||
assert.deepEqual(
|
||||
inventory.normalized_result.summary.manifest,
|
||||
oldAtomic.normalized_result.manifest,
|
||||
);
|
||||
assert.deepEqual(inventory.normalized_result.summary.inventory_evidence_ids, [
|
||||
oldAtomic.evidence_id,
|
||||
]);
|
||||
const exportedPath = resolve(values.output, "exported-after-import.json");
|
||||
await call("export_evidence_bundle", { path: exportedPath });
|
||||
const exported = JSON.parse(await readFile(exportedPath, "utf8"));
|
||||
assert.deepEqual(
|
||||
exported.records.find(
|
||||
(record) => record.evidence_id === oldWasm.evidence_id,
|
||||
),
|
||||
oldWasm,
|
||||
);
|
||||
assert.equal(sha(await readFile(values.bundle)), sha(bundleBytes));
|
||||
assert.equal(
|
||||
sha(await readFile(values["inspection-reply"])),
|
||||
sha(inspectionBytes),
|
||||
);
|
||||
report = {
|
||||
runtime_revision: values.revision,
|
||||
original_bundle_sha256: sha(bundleBytes),
|
||||
original_inspection_reply_sha256: sha(inspectionBytes),
|
||||
source_files_unchanged: true,
|
||||
imported_wasm_source_evidence_id: oldWasm.evidence_id,
|
||||
original_wasm_record_preserved_exactly: true,
|
||||
typed_summary_and_first4_exports_match: true,
|
||||
portable_old_inspection_and_atomic_inventory_identity_preserved: true,
|
||||
original_inventory_evidence_id: oldAtomic.evidence_id,
|
||||
calls,
|
||||
scope:
|
||||
"Actual old complete Evidence imported or passed inline to the new runtime; original authentication, IDs, records, source bytes and selected facts preserved. WABT is unavailable and no producer analysis is requested. Existing file import/export is used, not an engine database cache.",
|
||||
};
|
||||
} finally {
|
||||
await client.close();
|
||||
}
|
||||
await writeFile(
|
||||
resolve(values.output, "summary.json"),
|
||||
JSON.stringify(report, null, 2),
|
||||
);
|
||||
process.stdout.write(JSON.stringify(report) + "\n");
|
||||
@@ -0,0 +1,149 @@
|
||||
# WASM first-call summary delivery
|
||||
|
||||
Refs [#2016](https://github.com/morluto/rea/issues/2016). This bounded follow-up
|
||||
adds optional MCP `inspect_wasm_artifact detail: summary`. Omitted/complete MCP
|
||||
requests and CLI output remain complete. Full original Evidence is retained;
|
||||
delivery selection is stripped before provider inputs, and exact export views
|
||||
read the original parent without another WABT invocation.
|
||||
|
||||
## Pinned repeated public SDK cohort
|
||||
|
||||
- Control: `18e5d6275965c5f1d3ef9fe373d1792822098003`.
|
||||
- Candidate: `45831c622a13368494d2a8f3a9718effa91c937c`.
|
||||
- Runtime file-table SHA-256: control `ef65527c2d41b621f71059b7553050660d801ad905a61a71b81aba266f70e1ec`;
|
||||
candidate `353f5513ea09b0a627fa99814cebe0a1231c6c8f7e0e12a28205521133478b1a`.
|
||||
- Actual WABT 1.0.42, identical explicitly selected provider configuration and
|
||||
effective search-path fingerprint, pinned Node 24.18.0 and locked SDK.
|
||||
- Three paired fresh-process trials per digest-pinned shipped module, serial
|
||||
on one CPU: control/candidate, candidate/control, control/candidate.
|
||||
- Same validation/counts/first-four complete export forms/WAT identity/provider
|
||||
identity/execution and fetch states; complete original source Evidence ID is
|
||||
also compared. All nine pairs preserve these selected facts and source IDs.
|
||||
|
||||
| Shipped module | Result JSON bytes, control → summary | Calls / errors | Median seconds, control → summary (ranges) |
|
||||
| ----------------------------- | -----------------------------------: | -------------- | ----------------------------------------------- |
|
||||
| `sqlite.wasm` | 20,118 → 18,533 | 3/1 → 2/0 | 15.962 (15.719–21.138) → 18.171 (10.242–18.649) |
|
||||
| `vscode.tree-sitter-css.wasm` | 20,366 → 18,781 | 3/1 → 2/0 | 4.920 (4.885–4.936) → 5.191 (4.971–5.232) |
|
||||
| `vscode.tree-sitter.wasm` | 6,433,872 → 18,891 | 1/0 → 2/0 | 5.225 (5.172–5.519) → 4.763 (4.729–4.830) |
|
||||
|
||||
Byte counts include all investigation call results, including failed delivery
|
||||
and extra views. They exclude catalog responses, raw wire framing and file
|
||||
exports; they are not actual model tokens. The complete catalog is 2,359,082
|
||||
versus 2,362,451 JSON bytes (+3,369 bytes, about 0.14%). An extra export-view
|
||||
call is included when summary replaces an otherwise fitting complete reply.
|
||||
|
||||
| Shipped module | Median owned CPU seconds, control → summary | Median sampled family MiB, control → summary (maxima) |
|
||||
| ----------------------------- | ------------------------------------------- | ----------------------------------------------------- |
|
||||
| `sqlite.wasm` | 15.376 → 15.954 | 660.84 (671.27) → 633.07 (671.51) |
|
||||
| `vscode.tree-sitter-css.wasm` | 5.760 → 6.027 | 692.91 (694.93) → 678.98 (693.88) |
|
||||
| `vscode.tree-sitter.wasm` | 6.134 → 5.663 | 674.04 (695.66) → 550.66 (553.47) |
|
||||
|
||||
All 18 scopes have no sampled abort and their last observations contain no
|
||||
memory-high/hard/OOM/OOM-kill or task-limit event. Final counters are unverified
|
||||
under the subsequent closeout audit below. Sampling can miss brief peaks. Application caches are cold per process;
|
||||
host page caches are not flushed. SDK elapsed time includes startup, discovery,
|
||||
schema work and persistence, not just provider analysis. Three observations
|
||||
give descriptive medians/ranges, not a statistical or cross-domain speed claim.
|
||||
|
||||
SQLite and the CSS grammar already recovered an oversized complete result
|
||||
through retained views in the control. The new path removes the initial error
|
||||
and one call; result-byte savings are correspondingly modest. The Tree-sitter
|
||||
runtime fits the MCP frame but delivers megabytes of unneeded WAT; its summary
|
||||
plus exact exports greatly reduces delivery. Full provider analysis and complete
|
||||
Evidence retention still occur, so this does not establish an engine shortcut.
|
||||
|
||||
An earlier 18-run cohort did not activate the treatment: the driver looked
|
||||
for an inline enum and missed SDK-generated `$ref` definitions. Those original
|
||||
runs and their source are archived separately and excluded from benefit claims.
|
||||
The corrected driver validates the actual advertised 2020-12 request schema.
|
||||
|
||||
## Real model verification
|
||||
|
||||
Ten actual Codex CLI 0.161.0 trials request `gpt-5.6-terra` high: three paired
|
||||
SQLite repetitions and one pair for each published VS Code component. The
|
||||
resolved server-side model identity is not inferred from the requested alias.
|
||||
Same question, fixed developer instructions, four allowlisted REA tools and
|
||||
explicit WABT settings; private profiles, shell/web/other-agent restrictions
|
||||
and target-byte preservation remain verified.
|
||||
|
||||
All ten answers match the 12 requested producer facts, including exact export
|
||||
forms and explicit execution/fetch states. Reported Evidence IDs occur in real
|
||||
responses; all copied profiles are removed. Manual review retains static-analysis
|
||||
limitations and makes no original-source/runtime claim. Every candidate chooses
|
||||
`detail: summary` on its first inspection and then reads exports without WABT
|
||||
rerun. Original control errors and client-context clipping remain in transcripts.
|
||||
|
||||
| Module / observations per side | Total input, control → summary | Cached input | Uncached input | Output |
|
||||
| --------------------------------- | -----------------------------: | ----------------: | --------------: | ------------: |
|
||||
| `sqlite.wasm` / 3 | 96,832 → 79,264 | 70,656 → 51,456 | 26,215 → 28,004 | 1,470 → 1,512 |
|
||||
| `vscode.tree-sitter-css.wasm` / 1 | 247,889 → 79,389 | 207,872 → 61,440 | 40,017 → 17,949 | 1,931 → 1,327 |
|
||||
| `vscode.tree-sitter.wasm` / 1 | 556,424 → 282,165 | 478,208 → 239,360 | 78,216 → 42,805 | 2,560 → 2,110 |
|
||||
|
||||
SQLite rows show medians of three observations; VS Code rows are single pairs.
|
||||
Usage is the CLI-reported total for the turn, with cached/uncached input listed
|
||||
separately. Lower total input does not imply a proportional monetary saving,
|
||||
uncached-input reduction or faster answer.
|
||||
|
||||
| Module | Calls / observed errors, control → summary | Seconds, control → summary |
|
||||
| ----------------------------- | ------------------------------------------ | ----------------------------------------------- |
|
||||
| `sqlite.wasm` | 3/1 → 2/0 | 61.521 (54.301–80.579) → 55.656 (42.960–62.145) |
|
||||
| `vscode.tree-sitter-css.wasm` | 3/1 → 2/0 | 87.126 → 106.580 |
|
||||
| `vscode.tree-sitter.wasm` | 4/0 → 2/0 | 56.952 → 104.999 |
|
||||
|
||||
SQLite total input falls about 18% and median answer time about 10%, while
|
||||
its median uncached input rises about 7%. The two VS Code pairs reduce total
|
||||
input by about 49% and 68%, but observed answer time rises about 84% and 22%.
|
||||
These data support optional smaller delivery; they do not establish uniform
|
||||
model speedup. The runtime control also makes one protocol resource-discovery
|
||||
call, included in the four-call count. Cache state, model reasoning and service
|
||||
latency are not separated by this small sample.
|
||||
|
||||
The model and SDK cohorts ran with the original resource wrapper. Their final
|
||||
receipts retain last-sampled cgroup counters, not verified final counters.
|
||||
The subsequent closeout correction regrades all ten existing answers: selected
|
||||
facts, real IDs, unchanged target bytes and profile cleanup still pass, while
|
||||
the final resource conditions are **unverified**. No model/build/provider run
|
||||
was repeated for that review-only correction. Last-sampled peaks are 656–944
|
||||
MiB for model scopes with no observed limit events; one CPU, 4 GiB hard ceiling,
|
||||
3 GiB early-stop and no-swap controls were active. This is not a proof of absent
|
||||
late resource events or a fully resource-qualified performance conclusion.
|
||||
The original transcripts/usage and regrades remain archived separately.
|
||||
|
||||
## Reproduction and verification
|
||||
|
||||
Use [the common measurement/model instructions](README.md) with the public
|
||||
digest-pinned inputs in [corpus.json](corpus.json), `--schemas selected` and
|
||||
`--delivery summary`. For each artifact run the above three paired orders
|
||||
against separately frozen runtimes, then `compare.mjs`. Use the same
|
||||
[WASM interface question](questions/wasm-interface.txt), four exact enabled
|
||||
tools (`inspect_wasm_artifact`, `inspect_analysis_view`, `get_evidence_bundle`,
|
||||
`export_evidence_bundle`), explicit WABT settings and resource scope for models.
|
||||
|
||||
The VS Code artifacts are two published components from
|
||||
[@vscode/tree-sitter-wasm 0.3.1](https://github.com/microsoft/vscode-tree-sitter-wasm).
|
||||
The selected regular archive members have verified digests and package SHA-512
|
||||
integrity. This is component analysis, not proof of the whole VS Code runtime.
|
||||
|
||||
The prototype passes 54 focused assertions and full static/docs gates. After
|
||||
rebasing, 29 focused assertions and 42 actual installed-package WABT CLI/MCP
|
||||
cases pass; the final rebased snapshot passes build/fast static and seven WASM
|
||||
MCP workflows again. Omitted/explicit-complete behavior, retained identity,
|
||||
fixed-server absence of retention, oversized continuation and invalid WAT
|
||||
digest remain checked. No version publication or target execution occurs.
|
||||
The final static/build scope has 51 soft memory-high events and no hard/OOM
|
||||
events; this is not credited as a performance trial.
|
||||
|
||||
Detailed JSON, transcripts, target bytes, profiles and acquisition receipts
|
||||
stay outside Git. Source inputs, scripts and this concise measured scope are
|
||||
reviewable in the repository.
|
||||
|
||||
## Main integration checkpoint
|
||||
|
||||
Prerequisite #2122 is merged at `58fb372071e56da9c5df0e37593ee3f0da6b64bc`.
|
||||
The follow-up is rebased directly onto latest fetched main. Intervening changes
|
||||
outside the prerequisite concern CLI/logging/CI planning rather than WASM
|
||||
production/delivery. Seven focused WASM MCP workflows and one fresh real-WABT
|
||||
SQLite public-SDK request pass against the new build: selected facts and original
|
||||
source ID match the pinned candidate, summary uses two calls with no tool error.
|
||||
Only the relevant integration checks and required pre-push gate are repeated;
|
||||
earlier measurements retain their original runtimes, not the new main label.
|
||||
+55
-15
@@ -25,6 +25,46 @@ fail() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Bash can return status 0 while parsing an incomplete [[ condition. Keep that
|
||||
# grammar in a constant quoted expression so truncated downloads fail while
|
||||
# parsing the outer brace group. eval parses only this literal; the arguments
|
||||
# are expanded as data by the conditional, not interpolated into shell code.
|
||||
matches() {
|
||||
eval '[[ "$1" =~ $2 ]]'
|
||||
}
|
||||
|
||||
# Resolve the current host's Node.js tarball label pair; a label we cannot map
|
||||
# is kept verbatim so the operator can still read it. Falls back on the raw
|
||||
# `uname` outputs rather than inventing a label the Node.js release index does
|
||||
# not publish, so a mismatch is obvious instead of silently wrong.
|
||||
node_host_labels() {
|
||||
case "$(uname -m)" in
|
||||
arm64|aarch64) node_arch_label="arm64" ;;
|
||||
x86_64|amd64) node_arch_label="x64" ;;
|
||||
*) node_arch_label="$(uname -m)" ;;
|
||||
esac
|
||||
case "$(uname -s)" in
|
||||
Darwin) node_os_label="darwin" ;;
|
||||
Linux) node_os_label="linux" ;;
|
||||
*) node_os_label="$(uname -s | tr '[:upper:]' '[:lower:]')" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Exit with actionable remediation when the active Node.js is unsupported.
|
||||
# The engine floor stays in sync with package.json#engines.node — change both.
|
||||
fail_node_version() {
|
||||
local observed="$1"
|
||||
node_host_labels
|
||||
printf 'REA installation failed: Node.js %s is unsupported.\n\n' "$observed" >&2
|
||||
printf 'REA requires Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+. Install one via:\n' >&2
|
||||
printf ' nvm: nvm install 24 && nvm use 24 (https://github.com/nvm-sh/nvm)\n' >&2
|
||||
printf ' fnm: fnm install 24 && fnm use 24 (https://github.com/Schniz/fnm)\n' >&2
|
||||
printf ' Direct download for %s/%s:\n' "$node_os_label" "$node_arch_label" >&2
|
||||
printf ' https://nodejs.org/dist/latest-v24.x/ (grab the %s-%s tarball)\n' "$node_os_label" "$node_arch_label" >&2
|
||||
printf 'Then rerun this installer.\n' >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: install.sh [--version VERSION] [--dry-run] [--no-setup] [--no-prompt] [--verbose]
|
||||
@@ -63,41 +103,41 @@ main() {
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ "$verbose" == true ]]; then
|
||||
if [ "$verbose" = true ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
platform="$(uname -s)"
|
||||
[[ "$platform" == "Darwin" || "$platform" == "Linux" ]] || fail "REA supports macOS and selected 64-bit Linux distributions."
|
||||
[ "$platform" = "Darwin" ] || [ "$platform" = "Linux" ] || fail "REA supports macOS and selected 64-bit Linux distributions."
|
||||
command -v curl >/dev/null 2>&1 || fail "curl is required. Install curl, then rerun this installer."
|
||||
command -v node >/dev/null 2>&1 || fail "Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+ is required; install it from https://nodejs.org and retry."
|
||||
command -v npm >/dev/null 2>&1 || fail "npm is required; install it with Node.js and retry."
|
||||
|
||||
node_version="$(node -p 'process.versions.node' 2>/dev/null || true)"
|
||||
IFS=. read -r node_major node_minor _node_patch <<<"$node_version"
|
||||
[[ "$node_major" =~ ^[0-9]+$ && "$node_minor" =~ ^[0-9]+$ ]] || fail "the active Node.js version could not be read. Check that node works and is on PATH, then retry."
|
||||
if ! [[ "$_node_patch" =~ ^[0-9]+(\+[0-9A-Za-z.-]+)?$ ]] ||
|
||||
matches "$node_major" '^[0-9]+$' && matches "$node_minor" '^[0-9]+$' || fail "the active Node.js version could not be read. Check that node works and is on PATH, then retry."
|
||||
if ! matches "$_node_patch" '^[0-9]+(\+[0-9A-Za-z.-]+)?$' ||
|
||||
! ((node_major == 22 && node_minor >= 19 || node_major == 24 && node_minor >= 11 || node_major >= 26)); then
|
||||
fail "Node.js $node_version is unsupported; use Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+."
|
||||
fail_node_version "$node_version"
|
||||
fi
|
||||
|
||||
if [[ -n "$version" ]]; then
|
||||
[[ "$version" =~ ^${version_pattern}$ ]] || fail "version must be an exact semantic version."
|
||||
if [ -n "$version" ]; then
|
||||
matches "$version" "^${version_pattern}$" || fail "version must be an exact semantic version."
|
||||
else
|
||||
release_json="$(curl -fsSL --proto '=https' --tlsv1.2 --retry 3 -H 'Accept: application/vnd.github+json' "https://api.github.com/repos/$REPOSITORY/releases/latest")" || fail "the latest REA release could not be resolved. Check network access or pass --version VERSION, then retry."
|
||||
tag="$(printf '%s' "$release_json" | node -e 'let s="";process.stdin.on("data",c=>s+=c).on("end",()=>{const v=JSON.parse(s).tag_name;if(typeof v!=="string")process.exit(1);process.stdout.write(v)})' 2>/dev/null)" || fail "the release response was invalid. Retry later or pass --version VERSION."
|
||||
[[ "$tag" =~ ^rea-agents-(${version_pattern})$ ]] || fail "the latest release tag was invalid. Retry later or pass --version VERSION."
|
||||
matches "$tag" "^rea-agents-(${version_pattern})$" || fail "the latest release tag was invalid. Retry later or pass --version VERSION."
|
||||
version="${BASH_REMATCH[1]}"
|
||||
fi
|
||||
|
||||
# npm's exact-version resolver cleans build metadata from the requested version,
|
||||
# so it may install the base release and make the post-install identity check fail.
|
||||
if [[ "$version" =~ \+ ]]; then
|
||||
if matches "$version" '\+'; then
|
||||
fail "npm cannot install an exact version with build metadata. Pass a version without build metadata, then retry."
|
||||
fi
|
||||
|
||||
install_args=(install --global)
|
||||
if [[ "$platform" == "Linux" ]]; then
|
||||
if [ "$platform" = "Linux" ]; then
|
||||
install_args+=(--prefix "$HOME/.local")
|
||||
install_bin="$HOME/.local/bin/rea"
|
||||
else
|
||||
@@ -113,21 +153,21 @@ main() {
|
||||
printf ' %q' npm "${install_args[@]}"
|
||||
printf '\n'
|
||||
printf ' Binary: %s\n' "$install_bin"
|
||||
printf ' Setup: %s\n' "$([[ "$start_setup" == true ]] && printf 'start when a terminal is available' || printf 'skipped')"
|
||||
printf ' Setup: %s\n' "$([ "$start_setup" = true ] && printf 'start when a terminal is available' || printf 'skipped')"
|
||||
|
||||
if [[ "$dry_run" == true ]]; then
|
||||
if [ "$dry_run" = true ]; then
|
||||
printf 'Dry run complete; no changes made.\n'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf 'Installing %s@%s...\n' "$PACKAGE" "$version"
|
||||
npm "${install_args[@]}" || fail "npm could not install REA. Check registry access and npm permissions, then retry."
|
||||
[[ -x "$install_bin" ]] || fail "npm completed without installing the rea command. Check the npm global bin directory and PATH, then retry."
|
||||
[ -x "$install_bin" ] || fail "npm completed without installing the rea command. Check the npm global bin directory and PATH, then retry."
|
||||
installed_version="$("$install_bin" --version 2>/dev/null | tr -d '[:space:]')" || fail "the installed REA version could not be read. Reinstall the requested version, then retry."
|
||||
[[ "$installed_version" == "$version" ]] || fail "installed version $installed_version does not match $version. Reinstall the requested version, then retry."
|
||||
[ "$installed_version" = "$version" ] || fail "installed version $installed_version does not match $version. Reinstall the requested version, then retry."
|
||||
|
||||
printf 'REA %s is installed.\n' "$version"
|
||||
if [[ "$start_setup" == true && -r /dev/tty && -w /dev/tty && -t 1 ]]; then
|
||||
if [ "$start_setup" = true ] && [ -r /dev/tty ] && [ -w /dev/tty ] && [ -t 1 ]; then
|
||||
printf 'Starting REA setup...\n'
|
||||
"$install_bin" setup </dev/tty >/dev/tty
|
||||
else
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"src/contracts/errorSchemas.ts",
|
||||
"src/evaluation/AgentEvaluationFixtures.ts",
|
||||
"src/application/RealHopperAssertions.ts",
|
||||
"scripts/verify/fridaBindingsCompatibility.ts",
|
||||
"scripts/verify/termux/browser.mjs",
|
||||
"scripts/verify-real-ghidra-noreturn.mjs",
|
||||
"tests/processOwnershipRunner.ts"
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,73 @@
|
||||
GCC RUNTIME LIBRARY EXCEPTION
|
||||
|
||||
Version 3.1, 31 March 2009
|
||||
|
||||
Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
This GCC Runtime Library Exception ("Exception") is an additional
|
||||
permission under section 7 of the GNU General Public License, version
|
||||
3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
|
||||
bears a notice placed by the copyright holder of the file stating that
|
||||
the file is governed by GPLv3 along with this Exception.
|
||||
|
||||
When you use GCC to compile a program, GCC may combine portions of
|
||||
certain GCC header files and runtime libraries with the compiled
|
||||
program. The purpose of this Exception is to allow compilation of
|
||||
non-GPL (including proprietary) programs to use, in this way, the
|
||||
header files and runtime libraries covered by this Exception.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
A file is an "Independent Module" if it either requires the Runtime
|
||||
Library for execution after a Compilation Process, or makes use of an
|
||||
interface provided by the Runtime Library, but is not otherwise based
|
||||
on the Runtime Library.
|
||||
|
||||
"GCC" means a version of the GNU Compiler Collection, with or without
|
||||
modifications, governed by version 3 (or a specified later version) of
|
||||
the GNU General Public License (GPL) with the option of using any
|
||||
subsequent versions published by the FSF.
|
||||
|
||||
"GPL-compatible Software" is software whose conditions of propagation,
|
||||
modification and use would permit combination with GCC in accord with
|
||||
the license of GCC.
|
||||
|
||||
"Target Code" refers to output from any compiler for a real or virtual
|
||||
target processor architecture, in executable form or suitable for
|
||||
input to an assembler, loader, linker and/or execution
|
||||
phase. Notwithstanding that, Target Code does not include data in any
|
||||
format that is used as a compiler intermediate representation, or used
|
||||
for producing a compiler intermediate representation.
|
||||
|
||||
The "Compilation Process" transforms code entirely represented in
|
||||
non-intermediate languages designed for human-written code, and/or in
|
||||
Java Virtual Machine byte code, into Target Code. Thus, for example,
|
||||
use of source code generators and preprocessors need not be considered
|
||||
part of the Compilation Process, since the Compilation Process can be
|
||||
understood as starting with the output of the generators or
|
||||
preprocessors.
|
||||
|
||||
A Compilation Process is "Eligible" if it is done using GCC, alone or
|
||||
with other GPL-compatible software, or if it is done without using any
|
||||
work based on GCC. For example, using non-GPL-compatible Software to
|
||||
optimize any GCC intermediate representations would not qualify as an
|
||||
Eligible Compilation Process.
|
||||
|
||||
1. Grant of Additional Permission.
|
||||
|
||||
You have permission to propagate a work of Target Code formed by
|
||||
combining the Runtime Library with Independent Modules, even if such
|
||||
propagation would otherwise violate the terms of GPLv3, provided that
|
||||
all Target Code was generated by Eligible Compilation Processes. You
|
||||
may then convey such a combination under terms of your choice,
|
||||
consistent with the licensing of the Independent Modules.
|
||||
|
||||
2. No Weakening of GCC Copyleft.
|
||||
|
||||
The availability of this Exception does not imply any general
|
||||
presumption that third-party software is unaffected by the copyleft
|
||||
requirements of the license of GCC.
|
||||
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,18 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,240 @@
|
||||
MinGW-w64 runtime licensing
|
||||
***************************
|
||||
|
||||
This program or library was built using MinGW-w64 and statically
|
||||
linked against the MinGW-w64 runtime. Some parts of the runtime
|
||||
are under licenses which require that the copyright and license
|
||||
notices are included when distributing the code in binary form.
|
||||
These notices are listed below.
|
||||
|
||||
|
||||
========================
|
||||
Overall copyright notice
|
||||
========================
|
||||
|
||||
Copyright (c) 2009, 2010, 2011, 2012, 2013 by the mingw-w64 project
|
||||
|
||||
This license has been certified as open source. It has also been designated
|
||||
as GPL compatible by the Free Software Foundation (FSF).
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions in source code must retain the accompanying copyright
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the accompanying
|
||||
copyright notice, this list of conditions, and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. Names of the copyright holders must not be used to endorse or promote
|
||||
products derived from this software without prior written permission
|
||||
from the copyright holders.
|
||||
4. The right to distribute this software or to use it for any purpose does
|
||||
not give you the right to use Servicemarks (sm) or Trademarks (tm) of
|
||||
the copyright holders. Use of them is covered by separate agreement
|
||||
with the copyright holders.
|
||||
5. If any files are modified, you must cause the modified files to carry
|
||||
prominent notices stating that you changed the files and the date of
|
||||
any change.
|
||||
|
||||
Disclaimer
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
========================================
|
||||
getopt, getopt_long, and getop_long_only
|
||||
========================================
|
||||
|
||||
Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
Sponsored in part by the Defense Advanced Research Projects
|
||||
Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
|
||||
* * * * * * *
|
||||
|
||||
Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
All rights reserved.
|
||||
|
||||
This code is derived from software contributed to The NetBSD Foundation
|
||||
by Dieter Baron and Thomas Klausner.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
===============================================================
|
||||
gdtoa: Converting between IEEE floating point numbers and ASCII
|
||||
===============================================================
|
||||
|
||||
The author of this software is David M. Gay.
|
||||
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001 by Lucent Technologies
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of Lucent or any of its entities
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
||||
* * * * * * *
|
||||
|
||||
The author of this software is David M. Gay.
|
||||
|
||||
Copyright (C) 2005 by David M. Gay
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that the copyright notice and this permission notice and warranty
|
||||
disclaimer appear in supporting documentation, and that the name of
|
||||
the author or any of his current or former employers not be used in
|
||||
advertising or publicity pertaining to distribution of the software
|
||||
without specific, written prior permission.
|
||||
|
||||
THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
|
||||
NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE
|
||||
LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
|
||||
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
* * * * * * *
|
||||
|
||||
The author of this software is David M. Gay.
|
||||
|
||||
Copyright (C) 2004 by David M. Gay.
|
||||
All Rights Reserved
|
||||
Based on material in the rest of /netlib/fp/gdota.tar.gz,
|
||||
which is copyright (C) 1998, 2000 by Lucent Technologies.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of Lucent or any of its entities
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
||||
|
||||
=========================
|
||||
Parts of the math library
|
||||
=========================
|
||||
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunSoft, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
|
||||
* * * * * * *
|
||||
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
|
||||
* * * * * * *
|
||||
|
||||
FIXME: Cephes math lib
|
||||
Copyright (C) 1984-1998 Stephen L. Moshier
|
||||
|
||||
It sounds vague, but as to be found at
|
||||
<http://lists.debian.org/debian-legal/2004/12/msg00295.html>, it gives an
|
||||
impression that the author could be willing to give an explicit
|
||||
permission to distribute those files e.g. under a BSD style license. So
|
||||
probably there is no problem here, although it could be good to get a
|
||||
permission from the author and then add a license into the Cephes files
|
||||
in MinGW runtime. At least on follow-up it is marked that debian sees the
|
||||
version a-like BSD one. As MinGW.org (where those cephes parts are coming
|
||||
from) distributes them now over 6 years, it should be fine.
|
||||
|
||||
===================================
|
||||
Headers and IDLs imported from Wine
|
||||
===================================
|
||||
|
||||
Some header and IDL files were imported from the Wine project. These files
|
||||
are prominent maked in source. Their copyright belongs to contributors and
|
||||
they are distributed under LGPL license.
|
||||
|
||||
Disclaimer
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user