mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 03:39:49 -10:00
Compare commits
174
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b9b6cc78b | ||
|
|
b1f473fcf8 | ||
|
|
24053f7ee2 | ||
|
|
a344650a7b | ||
|
|
9e0bc71e78 | ||
|
|
1f9bf8af0e | ||
|
|
419956f56e | ||
|
|
c5ee066022 | ||
|
|
3230f50b16 | ||
|
|
0a15246d32 | ||
|
|
9108d9a627 | ||
|
|
3c3d405c00 | ||
|
|
43d9c9d19b | ||
|
|
86059108b1 | ||
|
|
35fbec9df5 | ||
|
|
b394d50943 | ||
|
|
694edef951 | ||
|
|
d4b9a33348 | ||
|
|
b06df804d6 | ||
|
|
df2d018b30 | ||
|
|
6c1faaed75 | ||
|
|
1fcf50518e | ||
|
|
437e65d349 | ||
|
|
df5103e26d | ||
|
|
f328b49d22 | ||
|
|
70e4653feb | ||
|
|
1883578b67 | ||
|
|
97b5503f39 | ||
|
|
645735fc0f | ||
|
|
25885b05c0 | ||
|
|
2c27c2a43b | ||
|
|
ab1b9e35d0 | ||
|
|
bf271ba3fb | ||
|
|
dda2d40295 | ||
|
|
0b1a945d69 | ||
|
|
425581e838 | ||
|
|
f047624018 | ||
|
|
62a2814756 | ||
|
|
400a91b5f9 | ||
|
|
8dc2d7bec4 | ||
|
|
908d9c0726 | ||
|
|
6a24e801ea | ||
|
|
5e61ae0b0e | ||
|
|
7baed55130 | ||
|
|
512bcf5cdb | ||
|
|
31b6db72c6 | ||
|
|
3e1f70096b | ||
|
|
e8d1bbc98b | ||
|
|
e66e92904e | ||
|
|
8c64eb511f | ||
|
|
e304de99bc | ||
|
|
d307ece767 | ||
|
|
4fde832260 | ||
|
|
97fe58d3fe | ||
|
|
7c821cfea1 | ||
|
|
f46e9a8479 | ||
|
|
29768c6f53 | ||
|
|
cc13c5d095 | ||
|
|
897caa814d | ||
|
|
a874cef9af | ||
|
|
a6c10a28f4 | ||
|
|
9536ebb7ca | ||
|
|
8358cfcab3 | ||
|
|
94728785ea | ||
|
|
38be5fd9f2 | ||
|
|
f20f05536e | ||
|
|
4df630e16a | ||
|
|
c546e6d12c | ||
|
|
875f729070 | ||
|
|
dcf481c11a | ||
|
|
ca456efcbf | ||
|
|
891371e738 | ||
|
|
068c319e82 | ||
|
|
4a1c4a59ba | ||
|
|
95382c2ba0 | ||
|
|
5d5fe72218 | ||
|
|
bd0642e0a4 | ||
|
|
2c6f981667 | ||
|
|
84f3401dcf | ||
|
|
99d00d1041 | ||
|
|
228ca6a9da | ||
|
|
4b27c51724 | ||
|
|
b46f4fcebd | ||
|
|
78a84d75c0 | ||
|
|
c78c8aed40 | ||
|
|
6b3372e259 | ||
|
|
52fe342c73 | ||
|
|
4d7c6efe9a | ||
|
|
0b42dc56d1 | ||
|
|
0d3a2b815e | ||
|
|
a961db280f | ||
|
|
9d0e87f331 | ||
|
|
94182f331e | ||
|
|
5553acfe50 | ||
|
|
44d232fccb | ||
|
|
5a25d42f23 | ||
|
|
3602b64c45 | ||
|
|
d9c9e6ea67 | ||
|
|
9e78606e2b | ||
|
|
00a6524b9a | ||
|
|
90c95a6b64 | ||
|
|
4063bfda97 | ||
|
|
21a5179105 | ||
|
|
4b4abcc2ee | ||
|
|
d0fd1b05fc | ||
|
|
c0c6488ae9 | ||
|
|
25d3c7237f | ||
|
|
b4b881116f | ||
|
|
88cf498036 | ||
|
|
559083be29 | ||
|
|
5044e20171 | ||
|
|
08637b0c24 | ||
|
|
c5ed046d6e | ||
|
|
03a3fcbcea | ||
|
|
72d5e72e6d | ||
|
|
c818ca9042 | ||
|
|
2ac8578827 | ||
|
|
b81da90354 | ||
|
|
887b99888e | ||
|
|
0b028cc75a | ||
|
|
1a0e2c77f2 | ||
|
|
b40b0b8665 | ||
|
|
015a02d57b | ||
|
|
688dca3e90 | ||
|
|
197a296664 | ||
|
|
aa2c1c61ce | ||
|
|
2d25a09c0f | ||
|
|
9109e6f6a7 | ||
|
|
cc58263ee0 | ||
|
|
56fb5219ce | ||
|
|
f3c21665d8 | ||
|
|
ce45f92219 | ||
|
|
f912a68417 | ||
|
|
6ca4e1368c | ||
|
|
1071ad867c | ||
|
|
c06b53644b | ||
|
|
352a846127 | ||
|
|
5679ed66f4 | ||
|
|
a67525cdf1 | ||
|
|
d5b5808f91 | ||
|
|
cbd4bd4a66 | ||
|
|
31278c7b5a | ||
|
|
db0b9ac20c | ||
|
|
18cc16141c | ||
|
|
60f9a4c69a | ||
|
|
4bb53000a3 | ||
|
|
c928bb8d80 | ||
|
|
ee54b2e7cf | ||
|
|
70fd7923ef | ||
|
|
10de107fd5 | ||
|
|
407d7f698d | ||
|
|
79da7ea8fa | ||
|
|
ff542ada47 | ||
|
|
75ff321e9e | ||
|
|
33b4762d5c | ||
|
|
6cf4e768e8 | ||
|
|
ad597388a4 | ||
|
|
110932cd5e | ||
|
|
5cafea5ebe | ||
|
|
872890bef3 | ||
|
|
ab9dc4569f | ||
|
|
1596d6a275 | ||
|
|
80427af8cc | ||
|
|
e47bb152c2 | ||
|
|
81c09888bf | ||
|
|
106ba1730f | ||
|
|
f7dc5489b3 | ||
|
|
3e8a5f76d0 | ||
|
|
ac30fbd658 | ||
|
|
5d21bddb18 | ||
|
|
2e2f981ccf | ||
|
|
f8bb792f15 | ||
|
|
0ecf3a4cbf | ||
|
|
8842092671 |
No files matched your search
@@ -10,8 +10,8 @@ equivalent completed investigations. A useful outcome can also be a measured
|
||||
decision to leave an implementation alone.
|
||||
|
||||
Follow the checkout's [performance priorities](../../../AGENTS.md#performance),
|
||||
[tool design](../../../docs/tool-design.md), and
|
||||
[testing guide](../../../docs/testing.md). This skill supplies an optimization
|
||||
[tool design](../../../docs/development/tool-design.md), and
|
||||
[testing guide](../../../docs/development/testing.md). This skill supplies an optimization
|
||||
workflow, not additional permission to execute targets, publish, or merge.
|
||||
Use the current contracts, provider prerequisites, and user authorization.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Prepare or rewrite REA release changelogs and GitHub release notes
|
||||
# REA changelog update
|
||||
|
||||
Use this for release-note preparation and contributor attribution. Read
|
||||
[docs/releasing.md](../../../docs/releasing.md) from the repository root for
|
||||
[docs/development/releasing.md](../../../docs/development/releasing.md) from the repository root for
|
||||
publication authority and the existing checkpoint checks. This skill prepares
|
||||
notes; it does not authorize merging, tagging, or publishing.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Establish which checks still catch real regressions and which costs can be
|
||||
removed without losing that protection. The outcome may be a verified fix,
|
||||
an evidence-backed recommendation, or an explicit decision to stop.
|
||||
|
||||
Follow the checkout's `AGENTS.md`, [testing guide](../../../docs/testing.md),
|
||||
Follow the checkout's `AGENTS.md`, [testing guide](../../../docs/development/testing.md),
|
||||
and [contribution rules](../../../CONTRIBUTING.md). Use their current commands
|
||||
and pinned toolchain, rather than commands remembered from an earlier audit.
|
||||
Preserve the requested scope: investigation alone does not authorize edits;
|
||||
|
||||
@@ -5,7 +5,7 @@ description: Audit, investigate, design, or change REA investigation tools, CLI/
|
||||
|
||||
# REA tool design
|
||||
|
||||
Use the [tool-design guide](../../../docs/tool-design.md) for tool boundaries,
|
||||
Use the [tool-design guide](../../../docs/development/tool-design.md) for tool boundaries,
|
||||
contract semantics, provider ownership, and discoverability. Inspect the current
|
||||
contract and nearest existing tool relevant to the analyst question; source,
|
||||
documentation, and live catalogs may describe different versions.
|
||||
@@ -14,12 +14,12 @@ For provider-backed work, exercise the analyst's task through REA and compare
|
||||
relevant native provider and independent artifact observations where available.
|
||||
Check applicable partial results, recovery and session boundaries; report what
|
||||
was not exercised. For failure guidance, follow [design recovery around the
|
||||
failure](../../../docs/tool-design.md#design-recovery-around-the-failure).
|
||||
Use [workflow verification](../../../docs/testing.md#provider-backed-workflow-verification)
|
||||
failure](../../../docs/development/tool-design.md#design-recovery-around-the-failure).
|
||||
Use [workflow verification](../../../docs/development/testing.md#provider-backed-workflow-verification)
|
||||
to select evidence for the proposed contract instead of seeking provider API
|
||||
parity.
|
||||
|
||||
For an audit, follow [audit existing tools](../../../docs/tool-design.md#audit-existing-tools):
|
||||
For an audit, follow [audit existing tools](../../../docs/development/tool-design.md#audit-existing-tools):
|
||||
scope representative tasks, exercise the live workflow, and distinguish
|
||||
reproduced bugs, supported limitations, design opportunities and unverified
|
||||
claims. Check relevant rendered MCP prompts, guided workflows and packaged skill
|
||||
@@ -30,7 +30,7 @@ For a design request, return the proposed boundary, input/result shape, Evidence
|
||||
semantics, nearest alternative, and verification approach. Implement when
|
||||
requested, preserving the user's scope and existing authorization.
|
||||
|
||||
For implementation or verification, consult [testing](../../../docs/testing.md)
|
||||
For implementation or verification, consult [testing](../../../docs/development/testing.md)
|
||||
for the affected consumer and provider lanes, and
|
||||
[contributing](../../../CONTRIBUTING.md) for generated-file ownership. Read
|
||||
provider/workflow guides only as the task requires.
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: reverse-engineer-anything
|
||||
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA, and build agent environments (AgentEnv bundles) of web applications from a live instance or a capture. 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.
|
||||
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA, and build agent environments (AgentEnv bundles) of web applications from a live instance or a capture, and of Linux desktop apps with a task from a request. 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: "60"
|
||||
version: "61"
|
||||
---
|
||||
|
||||
# REA
|
||||
@@ -108,7 +108,7 @@ explicit path or endpoint and do not need it.
|
||||
- Firmware image: `inspect_firmware_regions` when advertised. Use
|
||||
`extract_firmware` when extraction is requested, with a caller-selected new
|
||||
absolute output directory. These tools use caller-supplied Binwalk/Unblob on
|
||||
Linux; see the [firmware guide](https://github.com/morluto/rea/blob/main/docs/firmware-analysis.md).
|
||||
Linux; see the [firmware guide](https://github.com/morluto/rea/blob/main/docs/guides/firmware/firmware-analysis.md).
|
||||
- ESP32-family app or bootloader image (`0xE9` magic): `inspect_artifact`
|
||||
without a provider; see the ESP section of `references/native-and-artifacts.md`.
|
||||
- .NET NativeAOT PE/ELF: native Ghidra analysis. Native code can yield pseudocode;
|
||||
@@ -140,6 +140,10 @@ explicit path or endpoint and do not need it.
|
||||
- Task for a desktop application's exported environment, from a
|
||||
`capture-desktop-application` folder: read
|
||||
[desktop application tasks](references/environments.md#tasks-for-a-desktop-application-environment).
|
||||
- Environment of a Linux desktop app with a task, from a request such as
|
||||
"build me an Inkscape environment where the agent changes a poster's
|
||||
headline": read [desktop builds](references/desktop-build.md). You drive the
|
||||
app on a build computer from `start_build_computer`, then export and witness.
|
||||
- Fiddler Everywhere traffic or a native `.saz` capture: read the
|
||||
[Fiddler workflow](references/runtime-observation.md#fiddler-everywhere-traffic-debugging).
|
||||
Inspect saved SAZ with `inspect_web_network_capture` and `format: "saz"`;
|
||||
@@ -150,7 +154,7 @@ explicit path or endpoint and do not need it.
|
||||
old-generation heap is `REA_CAPTURE_DECODER_OLD_GENERATION_MIB` (default 192 MiB,
|
||||
floor 8, maximum 16384), set where REA starts. Host memory and `NODE_OPTIONS` do not
|
||||
raise it. See
|
||||
[historical captures](https://github.com/morluto/rea/blob/main/docs/web-network-captures.md) for the exact upstream
|
||||
[historical captures](https://github.com/morluto/rea/blob/main/docs/guides/web/web-network-captures.md) for the exact upstream
|
||||
profile and credential exclusions. Qlog support starts with aioquic 1.5.0
|
||||
JSON 0.3; stream coverage and endpoint loss declarations do not recover bodies
|
||||
or establish network loss. Prefer detail summary, then kind qlog trace/stream
|
||||
@@ -165,7 +169,7 @@ explicit path or endpoint and do not need it.
|
||||
display filters and decode-as rules. Requires Linux, util-linux prlimit and
|
||||
TShark 4.x on an absolute `PATH` entry or via the optional absolute
|
||||
`REA_TSHARK_COMMAND` override; see
|
||||
[capture guide](https://github.com/morluto/rea/blob/main/docs/packet-captures.md).
|
||||
[capture guide](https://github.com/morluto/rea/blob/main/docs/guides/data/packet-captures.md).
|
||||
Packet limits count input packets before filtering. Output defaults to 50 matching
|
||||
frames; use `match_offset` / `match_limit` for later pages, or explicit null
|
||||
limit for complete matching output. Preserve the source digest across pages.
|
||||
@@ -173,7 +177,7 @@ explicit path or endpoint and do not need it.
|
||||
For address/DNS/SNI/protocol summaries use `inspect_pcap_capture` with MCP
|
||||
detail summary, then retained kind pcap pages. Requires Wireshark 4.x tshark
|
||||
and capinfos, with Linux prlimit or Windows Job Objects; see
|
||||
[packet summaries](https://github.com/morluto/rea/blob/main/docs/pcap-analysis.md).
|
||||
[packet summaries](https://github.com/morluto/rea/blob/main/docs/guides/data/pcap-analysis.md).
|
||||
Select an exact DNS question for address pages; page exhaustion does not prove
|
||||
network completeness. This reads recordings and does not acquire traffic.
|
||||
- Decoder discovery: `inspect_signal_decoders` searches installed decoder IDs
|
||||
@@ -181,7 +185,7 @@ explicit path or endpoint and do not need it.
|
||||
relevant details before choosing settings; this does not scan hardware.
|
||||
- Recorded logic/signal traces: `decode_signal_recording` with explicit decoder,
|
||||
channel and protocol settings. On Linux with util-linux prlimit, supply sigrok-cli 0.7.2 through
|
||||
`REA_SIGROK_COMMAND`; see [recording guide](https://github.com/morluto/rea/blob/main/docs/signal-recordings.md).
|
||||
`REA_SIGROK_COMMAND`; see [recording guide](https://github.com/morluto/rea/blob/main/docs/guides/signals/signal-recordings.md).
|
||||
Output defaults to 50 literal lines; select annotation classes and page with
|
||||
`line_offset` / `line_limit`, or explicit null for all remaining output.
|
||||
Window counts are display lines, not annotations or samples. Preserve source digests across pages.
|
||||
@@ -190,7 +194,7 @@ explicit path or endpoint and do not need it.
|
||||
through `REA_WABT_BIN_DIRECTORY`; retain exact byte/tool identity and decoded WAT.
|
||||
Select JavaScript glue and candidate paths explicitly and preserve URL/path
|
||||
ambiguity. No implicit fetch or target execution; WAT is not original source.
|
||||
See the [WASM guide](https://github.com/morluto/rea/blob/main/docs/wasm-artifacts.md).
|
||||
See the [WASM guide](https://github.com/morluto/rea/blob/main/docs/guides/wasm/wasm-artifacts.md).
|
||||
- Explicit local Android APK (or ZIP/AAB) signing: `inspect_apk_signature`.
|
||||
Prefer its summary or selected signer/digest/lineage page; retain complete
|
||||
Evidence and use `inspect_analysis_view` kind `apk-signature` for follow-ups.
|
||||
@@ -209,13 +213,17 @@ explicit path or endpoint and do not need it.
|
||||
Evidence stays retained under its original identity. Use the returned
|
||||
`parent_evidence_id` for exact function or `bytecode_hex`/stdout/stderr pages.
|
||||
Candidate coverage does not establish interface completeness. See the
|
||||
[EVM bytecode guide](https://github.com/morluto/rea/blob/main/docs/evm-bytecode.md).
|
||||
- Embedded Go compiler, module or build-setting metadata: `inspect_go_binary`
|
||||
with the explicit local file. This built-in target-free inspection requires no
|
||||
Go installation or disassembler. Preserve raw module bytes and source ranges;
|
||||
absent metadata does not prove a binary is not Go, and unparsed text records
|
||||
remain explicit. See the
|
||||
[Go binary guide](https://github.com/morluto/rea/blob/main/docs/go-binaries.md).
|
||||
[EVM bytecode guide](https://github.com/morluto/rea/blob/main/docs/guides/evm/evm-bytecode.md).
|
||||
- Embedded Go compiler, module, build-setting metadata, or static `(ptr, len)`
|
||||
string literals: `inspect_go_binary` with the explicit local file (pass
|
||||
`include_string_literals: true` and optional `max_string_literals` for bounded
|
||||
inferred static string-header recovery, and page retained rows with
|
||||
`inspect_analysis_view` kind `go` collection `string_literals`). This built-in
|
||||
target-free inspection requires no Go installation or disassembler. Preserve
|
||||
raw module bytes and source ranges; absent metadata does not prove a binary is
|
||||
not Go, static string recovery excludes compiler-inlined stack or immediate
|
||||
strings, and unparsed text records remain explicit. See the
|
||||
[Go binary guide](https://github.com/morluto/rea/blob/main/docs/guides/native/go-binaries.md).
|
||||
- Embedded CUDA/HIP code objects: `inspect_gpu_code_objects`; inventory targets
|
||||
first, then decode selected payloads and query retained GPU Evidence.
|
||||
- Bundled GGUF or safetensors model declarations: `inspect_model_artifact`
|
||||
@@ -268,6 +276,14 @@ explicit path or endpoint and do not need it.
|
||||
proof the image never imported APIs through another table. Bound snapshots
|
||||
and loaded IAT contents remain unobserved. See the
|
||||
[PE import guide](https://github.com/morluto/rea/blob/main/docs/pe-imports.md).
|
||||
- Windows Shell Link shortcuts: `inspect_windows_shortcut` with the explicit
|
||||
local `.lnk` file. This built-in target-free inspection requires no Windows
|
||||
SDK or COM. Preserve header flags and FILETIMEs, IDList items, LinkInfo
|
||||
volume and network names, StringData arguments and icon location, ExtraData
|
||||
signatures, and Tracker droid facts labelled derived. Unknown IDList items
|
||||
and ExtraData signatures stay raw with SHA-256. The target path is not
|
||||
resolved or executed. See the
|
||||
[Windows shortcut guide](https://github.com/morluto/rea/blob/main/docs/guides/native/windows-shortcut.md).
|
||||
- PE TLS callbacks and load configuration: `inspect_pe_load_config` with the
|
||||
explicit local PE32/PE32+ file. This built-in target-free inspection requires
|
||||
no Windows SDK. Preserve callback VAs as strings with their RVA, file offset
|
||||
@@ -332,17 +348,17 @@ explicit path or endpoint and do not need it.
|
||||
20 rows; request `schema_scope: "database"` for the complete stored schema. Preserve both database and existing sibling WAL identity; row samples
|
||||
report truncation and have unspecified order. Use a quiescent snapshot rather
|
||||
than assuming a live database/WAL pair was copied atomically. See the
|
||||
[SQLite guide](https://github.com/morluto/rea/blob/main/docs/sqlite-databases.md).
|
||||
[SQLite guide](https://github.com/morluto/rea/blob/main/docs/guides/data/sqlite-databases.md).
|
||||
- Explicit Linux ELF file for offline layout, symbols, relocations or static
|
||||
mitigation evidence: `inspect_binary_layout`. This target-free operation uses
|
||||
caller-supplied pwntools without opening a disassembler database. Preserve its
|
||||
raw locations and inference/coverage limits; see the
|
||||
[offline binary guide](https://github.com/morluto/rea/blob/main/docs/binary-diagnostics.md).
|
||||
[offline binary guide](https://github.com/morluto/rea/blob/main/docs/guides/native/binary-diagnostics.md).
|
||||
- Supplied Linux x86-64 ELF core: `inspect_recorded_crash`. Read every recorded
|
||||
thread, raw note and source-bound register without opening a live target.
|
||||
Historical PIDs do not select live processes. Request `include_debugger_context`
|
||||
only when core-only mapping candidates help; see the
|
||||
[recorded crash guide](https://github.com/morluto/rea/blob/main/docs/recorded-crashes.md).
|
||||
[recorded crash guide](https://github.com/morluto/rea/blob/main/docs/guides/native/recorded-crashes.md).
|
||||
- PE resource type/name/language trees and static icon group references:
|
||||
`inspect_pe_resources` with an explicit path. This portable operation requires
|
||||
no active target or engine; opaque payloads retain file ranges and SHA-256.
|
||||
@@ -358,9 +374,9 @@ The legacy attached profile binds the already-open GUI input by SHA-256 and
|
||||
leaves its database open. The modern headless profile creates and closes an
|
||||
owned private database without saving. Installation and registration reuse
|
||||
[mrexodia/ida-pro-mcp](https://github.com/mrexodia/ida-pro-mcp); see the
|
||||
[IDA provider guide](https://github.com/morluto/rea/blob/main/docs/ida-provider.md).
|
||||
[IDA provider guide](https://github.com/morluto/rea/blob/main/docs/providers/ida-provider.md).
|
||||
For migration to the separate native IDA MCP plugin, follow the guide's
|
||||
[legacy attached migration](https://github.com/morluto/rea/blob/main/docs/ida-provider.md#migrate-a-legacy-attached-registration).
|
||||
[legacy attached migration](https://github.com/morluto/rea/blob/main/docs/providers/ida-provider.md#migrate-a-legacy-attached-registration).
|
||||
Replace the upstream registration explicitly; modern mrexodia tools are not the
|
||||
native profile. Native attachment preserves the database but does not provide
|
||||
direct callers; check session availability and the guide's verification limits.
|
||||
@@ -539,6 +555,8 @@ as complete while required questions remain open.
|
||||
[references/environments.md](references/environments.md)
|
||||
- Tasks for a desktop application's exported environment:
|
||||
[references/environments.md](references/environments.md#tasks-for-a-desktop-application-environment)
|
||||
- A desktop app environment from a request, built and witnessed on build
|
||||
computers: [references/desktop-build.md](references/desktop-build.md)
|
||||
|
||||
## Finish the task
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Preserve slot/relocation provenance and source coverage: matched means observed
|
||||
candidate presence; partial scans do not establish uniqueness or absence.
|
||||
This reads DEX/ELF bytes without loading the APK into the decompiler or executing
|
||||
target code. Runtime registration and loading remain unknown. See the
|
||||
[JNI guide](https://github.com/morluto/rea/blob/main/docs/android-analysis.md#link-native-declarations-to-jni-candidates).
|
||||
[JNI guide](https://github.com/morluto/rea/blob/main/docs/guides/android/android-analysis.md#link-native-declarations-to-jni-candidates).
|
||||
|
||||
For an R8/ProGuard release build with its `mapping.txt`, pass the absolute
|
||||
`mapping_path` to `inspect_android_class` or `inspect_android_method`. Prefer
|
||||
|
||||
@@ -11,7 +11,7 @@ main and an older release expose the same arguments. Tool-name prefixes belong
|
||||
to the client: find the canonical REA operation in its actual tool listing and
|
||||
server association before concluding that it is absent. A shared prefix alone
|
||||
does not establish which server an approval wildcard covers. See
|
||||
[client tool names and discovery](https://github.com/morluto/rea/blob/main/docs/client-configuration.md#client-tool-names-and-discovery).
|
||||
[client tool names and discovery](https://github.com/morluto/rea/blob/main/docs/getting-started/client-configuration.md#client-tool-names-and-discovery).
|
||||
|
||||
## Choose the remedy from the observed failure
|
||||
|
||||
|
||||
@@ -0,0 +1,438 @@
|
||||
# Desktop app environments from a request
|
||||
|
||||
Use this when someone asks for an environment of a Linux desktop app with a
|
||||
task, such as "Build me an Inkscape environment where the agent changes a
|
||||
poster's headline and saves it". You are the building agent: you drive the
|
||||
app on a build computer through REA's MCP tools, write the task, export the
|
||||
bundle and witness it in a fresh computer. REA runs no model. The tools are
|
||||
MCP-only and need Docker, `REA_AGENT_ENV_COMMAND` and
|
||||
`REA_BUILD_COMPUTER_REA_ARCHIVE` where the REA server starts; when a start
|
||||
reports one missing, tell the person what to set and stop.
|
||||
|
||||
For the whole build:
|
||||
|
||||
- Drive the app only with `act_on_build_computer`. Never script it, run
|
||||
commands in the computer or write its files another way.
|
||||
- Ask the upfront questions once, then work on your own. Pause only when
|
||||
blocked.
|
||||
- The seed's content is synthetic. Never put real personal data in it.
|
||||
- Close every computer you start, on success and on failure.
|
||||
- Note the time you start; the report gives the build time.
|
||||
|
||||
## Ask once, upfront
|
||||
|
||||
In one message, ask only what the request leaves open, and keep the list for
|
||||
the report:
|
||||
|
||||
1. The app and the task, if either is unclear: what changes, in which
|
||||
document.
|
||||
2. Whether they have a starting file of their own; otherwise you make one.
|
||||
3. Whether they want solver runs after the witness: how many (the budget)
|
||||
and with which model.
|
||||
4. If so, whether they want to review the task before those runs.
|
||||
|
||||
## When you are blocked
|
||||
|
||||
Stop, say what you need and wait only for:
|
||||
|
||||
- a licence the app or its installer asks someone to accept: never accept it
|
||||
yourself; name it and where to read it, and go on only once the person
|
||||
says they accept it;
|
||||
- credentials: they may only be typed as handles you never see, and the
|
||||
build tools have none yet, so say the app needs a sign-in and stop. Never
|
||||
ask for a password in chat;
|
||||
- a signed-in state in the seed: ask before seeding one;
|
||||
- an install this flow cannot do, below.
|
||||
|
||||
Decide everything else yourself and note it in the report.
|
||||
|
||||
## Choose the install
|
||||
|
||||
The computer is Ubuntu 24.04 (noble) on this host's architecture only. Use
|
||||
the first source that has the app:
|
||||
|
||||
| Source | `install` |
|
||||
| ---------------------------- | --------------------------------------------------------------------------------- |
|
||||
| Ubuntu archive | `{"kind": "archive", "package": "inkscape"}` |
|
||||
| PPA or vendor apt repository | `{"kind": "apt_repository", "package", "uri", "suite", "components", "key_file"}` |
|
||||
| `.deb` by URL | `{"kind": "package_file", "url", "sha256", "architecture", "dependencies"}` |
|
||||
|
||||
- A PPA's `uri` is `https://ppa.launchpadcontent.net/OWNER/NAME/ubuntu`,
|
||||
`suite` `noble`, `components` `["main"]`. `key_file` is the repository's
|
||||
signing key saved on this host; for a PPA, fetch it from
|
||||
keyserver.ubuntu.com by the fingerprint its Launchpad page shows.
|
||||
- For a `.deb`, ask the requester for its URL and SHA-256; do not fetch a
|
||||
vendor's download page yourself. List its `Depends` as `dependencies`:
|
||||
it installs with the network off.
|
||||
- Flatpak, AppImage and snaps are not supported yet: say so and stop. An
|
||||
archive package that only installs a snap, such as noble's `firefox`,
|
||||
counts as a snap. A package with no build for this host's architecture
|
||||
(some PPAs are amd64 only) cannot be installed either.
|
||||
- `desktop_entry` is the package's `.desktop` file name under
|
||||
`/usr/share/applications` without `.desktop`, such as
|
||||
`org.inkscape.Inkscape`. Add `window_class` when you know it; Inkscape's
|
||||
is `Inkscape`. AbiWord's entry is `abiword` and its class `Abiword`.
|
||||
- To find the entry, read the package's file list: its page on
|
||||
packages.ubuntu.com, or `apt-get download PKG && dpkg -c PKG_*.deb` where
|
||||
apt runs. The entry may ship in a companion `-data` or `-common` package,
|
||||
as Planner's in `planner-data`: read that package's list too. The entry's `StartupWMClass` may not be the window's real
|
||||
class, so do not take `window_class` from it: MuseScore 3's says
|
||||
`mscore3`, its window's is `MuseScore3`. The export uses the class the
|
||||
capture saw.
|
||||
|
||||
## Drive the app
|
||||
|
||||
- Pass `computer_id` and the action's fields at the top level: click
|
||||
`{x, y, count}`, scroll `{x, y, direction, amount}`, a screenshot region
|
||||
`[x0, y0, x1, y1]`. The rest are in
|
||||
[the build-computer guide](https://github.com/morluto/rea/blob/main/docs/desktop-build-computer.md).
|
||||
- Take a `screenshot` before pointing: points are pixels of the latest
|
||||
frame. If a response is too large, ask for a `region`, or `jpeg` with a
|
||||
lower `quality`. A region crops the latest frame and becomes it: take a
|
||||
full screenshot before pointing again.
|
||||
- A drawn caret does not prove keyboard focus. After using a toolbar
|
||||
control, click into the document, then type a few characters and look
|
||||
before a long text.
|
||||
- Confirm a dialog with `key` Return, not a trailing `\n` in `type`.
|
||||
- An action's own screenshot is taken at once. After opening a menu, a
|
||||
dialog or a window, look with
|
||||
`{"action": "wait", "ms": 500, "screenshot": true}`.
|
||||
- On a computer started from a request the app is not open at first, and
|
||||
`start_build_capture` opens it: never open it yourself before that. Do not
|
||||
close it while capturing; the capture ends when the app exits. When the
|
||||
app is closed at any other time, open it from Applications → Other → the
|
||||
environment's name.
|
||||
- Prefer shortcuts and typing to long pointer paths: `key` takes `keys`, an
|
||||
array holding one chord's keys, such as
|
||||
`{"action": "key", "keys": ["Control", "s"]}`, and `type` turns `\n` into
|
||||
Enter.
|
||||
- Before `type`, check in a screenshot that a text cursor or a focused
|
||||
field is there. In apps with single-key shortcuts, such as Inkscape, text
|
||||
typed without one runs as commands.
|
||||
- Save As differs by app. Check the dialog's current folder first: most
|
||||
open in the home, so click Documents in the sidebar, but Scribus opens in
|
||||
`~/Documents` and its sidebar has no Documents entry. Type only the file
|
||||
name. A dialog taller than the 1280×800 screen hides its buttons:
|
||||
maximize it from its title bar, or confirm it with `key` Return, as when
|
||||
HomeBank's Save button is off-screen.
|
||||
- Answer the app's save questions, such as keeping the format, then check
|
||||
the saved path in the title or status bar, or the dialog's folder when
|
||||
the app shows only the name, and that it shows no unsaved mark, before
|
||||
you mark a checkpoint or check. Where the title never shows one, as in
|
||||
HomeBank, a greyed Save or Revert, or the file reopened from recent
|
||||
files, confirms the save.
|
||||
- Qt spin boxes change their value on scroll: move the pointer off them
|
||||
before you scroll.
|
||||
- What the app saved under the home before `seed`, such as a document in
|
||||
`~/Documents` or its settings, is part of the seed. A file you move to the
|
||||
Trash is left out, and the export lists it in `limitations`. Trash a stray
|
||||
file rather than starting over.
|
||||
- Dismiss first-run dialogs, such as a welcome screen, before `seed`. A
|
||||
choice the app saves only later, such as Inkscape's "show this every
|
||||
time", may not reach the seed, so expect the dialog in the witness too.
|
||||
- Give what the task changes a stable name where the app has one, such as an
|
||||
id in Inkscape's Object Properties, so a check can select it.
|
||||
- Expect apps to split text into runs: Writer's revision ids split an
|
||||
edited paragraph into spans and may give it an automatic style such as
|
||||
`P1`, and AbiWord wraps each insertion in `<c>`. Check such text whole
|
||||
with `text_equals` (see Write the task), and find the paragraph by
|
||||
something the edit keeps, such as AbiWord's `xid`.
|
||||
|
||||
## Build the seed and the edit
|
||||
|
||||
1. `start_build_computer` with
|
||||
`{"source": {"kind": "request", "desktop_entry": ..., "install": ...}}`.
|
||||
The first start of an app builds its image, and starts at the same time
|
||||
on this host wait for each other; either can take minutes. A failed
|
||||
start returns the build's error: fix the request, or stop when the
|
||||
install cannot work, and close any `computer_id` the error names.
|
||||
2. `start_build_capture`. It returns once the app's window is open. A
|
||||
`package_lists_error` may stop the capture finding the package's
|
||||
sources; the export says when that matters. When the app exits before
|
||||
its window opens, the error gives its exit code and the end of its
|
||||
stderr, which may name what it lacks, such as a Java runtime: try
|
||||
another install source, or stop as for an install this flow cannot do.
|
||||
- REA counts a file as the app's document only when the app's window
|
||||
title shows its file name or `~/` path. When the title shows something
|
||||
else, such as MuseScore's score title, pass the path you will save the
|
||||
document at in `state_paths`, relative to the home:
|
||||
`{"computer_id": ..., "state_paths": ["Documents/MuseScore3/Scores/Morning_Song.mscz"]}`.
|
||||
It need not exist yet. Add the app's settings folder when its name
|
||||
differs from the app's, such as `.config/MuseScore`, so the seed keeps
|
||||
the dismissed first-run dialogs. Do not pass the document as a launch
|
||||
argument to make REA see it: `state_paths` is the way.
|
||||
- An app whose document is a folder of pages, such as a Zim notebook
|
||||
(`Notebooks/Notes`, a `.txt` file per page), never shows a file in its
|
||||
title: pass the folder in `state_paths`. Every page in it is then a
|
||||
document, so the bundle opens none at launch and the app starts where
|
||||
it keeps its place; check the page the task changes.
|
||||
3. Make the seed through the app and save it from the app under
|
||||
`~/Documents`: build the document in the app, or write its source where
|
||||
the app edits its format as text, then save it again from the app. Make
|
||||
it look real but synthetic: the thing the task changes, plus a few things
|
||||
the change must leave alone. Keep it to one document: the bundle's app
|
||||
opens the seed's document at launch only when there is exactly one, and
|
||||
otherwise starts on its own screen. For a starting file of the requester's,
|
||||
read it here and rebuild it in the app with synthetic data in place of
|
||||
personal data; REA cannot copy a file into the computer.
|
||||
- An app that keeps its own data and saves after every change, such as
|
||||
Osmo's contacts in `~/.local/share/osmo/contacts_records.xml`, has no
|
||||
document: that state is the seed. Build it in the app and mark `seed`
|
||||
once the app has written. To see whether it has, mark a throwaway
|
||||
checkpoint, such as `probe-1`, and read its `changed_files`: up to ten
|
||||
files that changed since the checkpoint before, those under
|
||||
`state_paths` first, then those the app held open, caches last, with
|
||||
`more_changed_files` counting the rest.
|
||||
- The app's own compressed format works when it is gzip, such as
|
||||
Gnumeric's `.gnumeric`, Dia's `.dia` or Inkscape's `.svgz`: REA reads
|
||||
the document inside, and checks point into it as into the same
|
||||
document uncompressed. A format REA reads as binary, such as one
|
||||
compressed with xz, has no view: save in a format the app offers that
|
||||
REA reads, then reopen the file once and check that a plain Ctrl+S
|
||||
keeps that format.
|
||||
4. Only once the seed is saved, `mark_build_checkpoint` with name `seed`.
|
||||
5. Make the change the task asks for, as a user would, and save it.
|
||||
6. Only once the change is saved, `mark_build_checkpoint` with name `end`.
|
||||
7. `stop_build_capture`. Read `draft.files` (each file that changed, with
|
||||
its net change and its `values`), `draft.task.checks` (suggested
|
||||
checks), `draft.guards`, `draft.notes` and `limitations`. When `draft`
|
||||
is null, read `draft_refusal` first: a missing `seed` or `end`
|
||||
checkpoint means capturing again on a new build computer, while a failed
|
||||
draft command names its own cause to fix. When `draft.files` is empty,
|
||||
`draft.notes` says why:
|
||||
- `no_change`: nothing was saved between `seed` and `end`. Capture again
|
||||
on a new build computer, and save before marking `end`.
|
||||
- `unowned_changes` with `no_document`: the app saved your document
|
||||
where REA did not count it as the app's. Its `files` list what changed,
|
||||
with their roles; the document is among them. Close the computer and
|
||||
capture again on a new one with that path in `state_paths`; the export
|
||||
refuses a check on a file outside the owned paths.
|
||||
- `uncheckable_changes`: the app saved the change in dconf, as gedit does
|
||||
its preferences, and no check reads dconf. Saving again does not help:
|
||||
choose a change the app saves in a file, and capture again on a new
|
||||
build computer.
|
||||
- `unreadable_changes`: a dconf database changed but REA could not read
|
||||
it; `error` says why. This is not evidence the app saved there: report
|
||||
the error rather than changing the task.
|
||||
|
||||
A note with a `file` says why that file's suggestions are thin:
|
||||
- `by_position`: only position names what changed; its `elements` lack
|
||||
a naming attribute. Check an ancestor's text, or give the element a
|
||||
name in the app, such as an id, and capture again.
|
||||
- `view_state_only`: every change is view state, a renumbered id or a
|
||||
time the app stamps, and its `pointers` are the checks kept. The edit
|
||||
was likely not saved: capture again and save it before `end`.
|
||||
- `long_text`: the element's text is too long to check whole; check a
|
||||
phrase in it with `text_contains`.
|
||||
- `cut_view` or `unreadable_view`: REA's view holds only part of the
|
||||
file, or none a check can read, such as a binary format (step 3).
|
||||
|
||||
## Write the task
|
||||
|
||||
Write `{"name", "prompt", "checks"}` from the draft and what you did.
|
||||
|
||||
- `name`: lowercase letters, digits and hyphens, not `smoke`.
|
||||
- `prompt`: what the requester wants, in their words and the app's terms,
|
||||
naming the document as a user would and ending with saving it: "Change the
|
||||
poster's headline in Documents/poster.svg to Summer Bake Sale and save
|
||||
it." Leave saving out for an app that saves on its own, after every change
|
||||
or a few seconds after the last one, such as Osmo or Gnote: grading waits
|
||||
until the app's files have held for 3 s, so the solving agent need not
|
||||
wait for the save. A save more than 3 s after the agent stops is still
|
||||
missed; name such an app in the report. Never say how the file stores it,
|
||||
and never give the checks.
|
||||
- Checks are file-based: content checks that prove the edit, never only that
|
||||
a file exists or changed. Start from the suggestions; keep those that say
|
||||
what the user did and drop what follows from how the app saves.
|
||||
- Compare exact values, so a typo or a wrong number fails.
|
||||
- Read each file's `values` before writing checks: every value the change
|
||||
added, changed and removed, with `before` and `after` (a scalar, or an
|
||||
element as compact XML, cut at 600 characters) at the pointer a check
|
||||
names it by, so copy the pointer and the `after` value into a check.
|
||||
Only XML files, archives, JSON and key files have values: a text file's
|
||||
or SQLite database's `change` already lists its lines and rows.
|
||||
`refers_to` says what a number stands for, such as `category="44"`
|
||||
naming `<cat key="44" name="Groceries"/>`; use it for the prompt's words.
|
||||
Skip entries whose `note` is `by_position` (no check can use that
|
||||
pointer) or noise (`view_state`, `renumbered`, `volatile`,
|
||||
`timestamp`, `upkeep`). `values_cut` means a limit left some out.
|
||||
- Select elements by what they hold, never by position: SVG text by id,
|
||||
`/root/children/[name=g][@inkscape:label=Layer 1]/children/[name=text][@id=headline]/children/[name=tspan]/children/0`,
|
||||
or an ODF paragraph by style,
|
||||
`/entries/[name=content.xml]/view/root/children/[name=office:body]/children/[name=office:text]/children/[name=text:p][@text:style-name=Title]/children/0`.
|
||||
A selector must match exactly one element, so give the target a unique id
|
||||
or style in the seed. The draft's pointers already do this: a name-like
|
||||
attribute such as Scribus's `ANNAME` before a coordinate, and two
|
||||
attributes together where one is not enough, as a spreadsheet cell's
|
||||
`[@Col=3][@Row=2]`. Only an element's text is read by position, as
|
||||
`children/0`.
|
||||
- When an app may split an element's text into runs, check it whole:
|
||||
`text_equals` (or `text_contains` for a value inside a sentence) on the
|
||||
element compares all its text, however it is split. Add
|
||||
`normalize_whitespace: true` when the app may reflow spaces. Example, an
|
||||
AbiWord paragraph by its stable id:
|
||||
`{"kind": "text_contains", "file": "Documents/memo.abw", "pointer": "/root/children/[name=section]/children/[name=p][@xid=6]", "value": "at 3:30 PM"}`.
|
||||
Point a text check at the paragraph or another element the edit keeps,
|
||||
never at a run such as AbiWord's `[name=c]`: a reopened document splits
|
||||
the text into several runs. The draft lists only what changed; an
|
||||
unchanged element is in `draft.guards` when it is a like sibling of a
|
||||
changed one, and otherwise use the app's usual numbering, such as another
|
||||
paragraph's `xid`, and let the export confirm it.
|
||||
- In an ODS spreadsheet no attribute names a row or a cell. Name the sheet
|
||||
in the seed, and check its whole text: `text_equals` on
|
||||
`/entries/[name=content.xml]/view/root/children/[name=office:body]/children/[name=office:spreadsheet]/children/[name=table:table][@table:name=Q1 Sales]`,
|
||||
or a stretch of it with `text_contains`. Cell texts join with nothing
|
||||
between, so a row reads `February23100`.
|
||||
- For a line added to free text, such as an item on a note's list, the
|
||||
draft compares the whole text with `text_equals`. This rejects longer or
|
||||
negated items, but can reject a correct edit with different ordering or
|
||||
spacing. Report that limitation when the task permits such variations.
|
||||
- Some apps keep text in an attribute, such as Scribus's `<ITEXT CH=...>`.
|
||||
`text_equals` cannot join it, so check the attribute with `value_equals`:
|
||||
`/root/children/[name=DOCUMENT]/children/[name=PAGEOBJECT][@ANNAME=Headline]/children/[name=StoryText]/children/[name=ITEXT]/attributes/CH`.
|
||||
A partial edit the app restyles splits the text into several runs and
|
||||
fails that check; list it in the report's limitations.
|
||||
- When the draft shows no values or no checks, a scratch export can expose
|
||||
`envs/<env>/seed/` only after the task has at least one valid check: it must
|
||||
pass on the captured end state and fail on the seed. Before the first
|
||||
successful export, use `act_on_build_computer` to open the saved file in an
|
||||
available GUI text editor or viewer and inspect its actual representation
|
||||
without changing it. Use the visible saved content and the task's edit to
|
||||
write a check; an export refusal can also name the end state's value, such
|
||||
as `is "44", not "1"`. If the file cannot be inspected or expressed by a
|
||||
supported check, report the limitation instead of guessing a check.
|
||||
- Where easy, add one check that the rest is untouched, such as another
|
||||
text's value the edit must leave alone. `draft.guards` offers them at
|
||||
their seed values, which the end holds too: a field on the nearest like
|
||||
siblings, one the user sets, such as Planner's `work`, before a default
|
||||
they all share; the text an addition kept; a text file's lines beside its
|
||||
new one. Copy one or two into `checks`; they pass on the seed, which is
|
||||
fine, since the export needs only one check to fail there.
|
||||
- The draft suggests a decimal the app writes as text, such as `146.83`,
|
||||
as a number with `tolerance: 0.001`; keep the tolerance for any number
|
||||
you check that way.
|
||||
- When the draft shows an XML document's changes as `lines`, REA read it
|
||||
as text, for example because its DOCTYPE declares entities. Selectors are
|
||||
impossible there, and `line_count` with `contains` only approximates a
|
||||
value: `3:30` also matches `13:30`. Bound it with neighbouring text and
|
||||
name the check as approximate in the report's limitations.
|
||||
- Some apps save a document reloaded from disk differently from one typed
|
||||
in the same session: AbiWord wraps each new insertion in its own markup.
|
||||
Your build's end state hides this, which is why whole-text checks matter;
|
||||
expect the witness to show the real format.
|
||||
|
||||
The kinds and pointer rules are in
|
||||
[the desktop tasks section](environments.md#pick-the-checks).
|
||||
|
||||
## Export
|
||||
|
||||
`export_build_environment` with `task` and `directory`, the absolute path of
|
||||
a new or empty folder here, such as `<home>/rea-builds/poster/bundle`. The
|
||||
export seeds what was saved at `seed`, replaces the computer's host name,
|
||||
`user@host` and home path (a bare user name, such as AbiWord's author
|
||||
`user`, stays), and checks the task against `seed` and `end`. It refuses a task
|
||||
unless at least one check fails on the seed and every check passes at the
|
||||
end, and says why, such as a pointer that names nothing at the end. A
|
||||
check that the rest is untouched passes on the seed too, which is fine. On
|
||||
a refusal, fix the task and export again, into another folder if that one
|
||||
is no longer empty. Keep
|
||||
`seed_files`, `scrubbed_files`, `unscrubbed_files` and `limitations` for the
|
||||
report.
|
||||
|
||||
The limitations name the folders the app wrote that the bundle neither owns
|
||||
nor seeds, such as `~/.config/MuseScore`, so the app starts without them:
|
||||
expect its first-run wizard, a tour or a "restore session?" question at every
|
||||
boot. If the witness shows one, capture again on a new build computer with
|
||||
those folders in `state_paths`, and dismiss the dialogs before `seed`. Lock
|
||||
files the app holds while it runs, such as LibreOffice's `.lock` and
|
||||
`.~lock.<name>#`, are left out of the seed and listed after "Left out of the
|
||||
seed", so you need not close the document or delete them before `seed`. The
|
||||
limitations also name seeded WebKit or Chromium storage and caches; when the
|
||||
witness's boot is clean, list them in the report.
|
||||
|
||||
Keep the build computer open until the witness holds: a task fix exports
|
||||
again from it.
|
||||
|
||||
## Witness
|
||||
|
||||
Witness in a fresh computer of the bundle, from the prompt, as a solving
|
||||
agent would. Do not replay the build's actions or coordinates, and do not
|
||||
check between stages to steer the edit: a solving agent never sees the
|
||||
checks. Give every `check_build_task` the task exactly as exported.
|
||||
|
||||
1. `start_build_computer` with
|
||||
`{"source": {"kind": "bundle", "path": "<bundle>"}}`. The app starts
|
||||
with the seed's files in place and opens the seed's document when the
|
||||
seed holds exactly one and the app takes a file. When the export's
|
||||
`limitations` say it opens no document, open it from the prompt's path,
|
||||
as a solving agent would. Take a `wait` screenshot first, since the
|
||||
desktop may not have drawn yet. When the start fails because the
|
||||
computer never got ready, and its error names lock files in the bundle's
|
||||
seed, delete them from the bundle and start again.
|
||||
2. `check_build_task` with `stage: "seed"` and `directory`, the absolute
|
||||
path of a new or empty folder for the record. A check must fail.
|
||||
Recording starts. Later stages take no `directory`.
|
||||
3. Do the task from the prompt with `act_on_build_computer` and save.
|
||||
`check_build_task` with `stage: "after_edit"`: every check must pass.
|
||||
Each check waits until the app's files have held for 3 s, as the
|
||||
bundle's verifier does, so an app that saves on its own needs no wait of
|
||||
yours. A result with `settled: false` means the files were still
|
||||
changing at the 15 s bound, and `read_cut: true` that a slow read was
|
||||
still running there.
|
||||
4. Make a near miss on top of it: a plausible wrong edit, such as a typo or
|
||||
a wrong number, and save. `check_build_task` with `stage: "near_miss"`:
|
||||
a check must fail.
|
||||
5. `act_on_build_computer` with `action: "reset"`, then `check_build_task`
|
||||
with `stage: "after_reset"`: a check must fail again.
|
||||
6. The last stage ends the witness: `witness.record` has the verdict, the
|
||||
path of `witness.json` and the recording's segments in `directory`.
|
||||
`close_build_computer` on the witness computer.
|
||||
|
||||
A stage that does not hold ends the witness as `failed`. Read each check's
|
||||
result and decide:
|
||||
|
||||
- `after_edit` failed though the saved file is right: the check is brittle.
|
||||
Fix it, export again and witness in a new computer.
|
||||
- `after_edit` failed because your edit was wrong: witness again in a new
|
||||
computer; a computer is witnessed once.
|
||||
- `near_miss` passed: the checks are too loose. Tighten them, export again
|
||||
and witness again.
|
||||
- `after_reset` passed: the reset did not restore the seed. Report it as a
|
||||
limitation.
|
||||
|
||||
Stop after three witnesses and report what still fails.
|
||||
|
||||
## Solver runs
|
||||
|
||||
Only if the requester asked for them. If they wanted to review the task
|
||||
first, show them its prompt and checks and wait for their approval. Then run
|
||||
the bundle within the budget, one run at a time, with the runner
|
||||
`REA_AGENT_ENV_COMMAND` names:
|
||||
`agent-env run <bundle> --task <name> --agent claude-code --model <model>`.
|
||||
Count runs reported `passed`. A run `scored below 1` is a miss; one reported
|
||||
`failed` did not finish, so run it again if the budget allows instead of
|
||||
counting it. Never run past the budget.
|
||||
|
||||
## Close and report
|
||||
|
||||
`close_build_computer` on every computer still open, also after a failure.
|
||||
If a close fails, call it again; if it still fails, tell the requester what
|
||||
is left.
|
||||
|
||||
Report:
|
||||
|
||||
- the bundle path and the environment name;
|
||||
- the task's name and prompt;
|
||||
- each check, and why it proves the edit and fails the near miss;
|
||||
- each witness stage with its result, the verdict, and the paths of
|
||||
`witness.json` and the recording;
|
||||
- the seed's contents: `seed_files` and what each holds;
|
||||
- `scrubbed_files` and `unscrubbed_files`; an unscrubbed file still names
|
||||
the host or user, so it needs review before sharing. `recompressed_files`
|
||||
are gzip seeds whose headers were cleared, their content unchanged: give
|
||||
their count;
|
||||
- limitations: the capture's, the export's and anything you could not do;
|
||||
- solver runs, if any: the model, the runs and the passes;
|
||||
- the build time and the questions you asked.
|
||||
|
||||
Never publish or share the bundle yourself.
|
||||
@@ -294,7 +294,9 @@ Use this when the user has a folder from `rea capture-desktop-application` and
|
||||
wants a task for the environment `rea export-desktop-application` makes from
|
||||
it: a prompt for a computer-use agent and checks that grade what the agent
|
||||
left in the app's files. You write the prompt and the checks; REA validates
|
||||
the task against the capture and exports it. These commands are CLI only.
|
||||
the task against the capture and exports it. These commands are CLI only. To
|
||||
build the environment and its task from a request instead, follow
|
||||
[desktop builds](desktop-build.md).
|
||||
|
||||
### Describe the change
|
||||
|
||||
@@ -306,9 +308,20 @@ Run `rea describe-desktop-application-task CAPTURE --format json`. Read:
|
||||
and last version, with its `role`, the `baseline` and `final` versions and
|
||||
the net `change`. Text changes list each added and removed line once, and
|
||||
`line_counts` gives lines found at both ends whose count changed.
|
||||
- `values` in each of those files: what the change added, changed and
|
||||
removed, `before` and `after`, at the pointer a check names it by, with
|
||||
`refers_to` naming the element a key such as `category="44"` stands for.
|
||||
Skip entries noted `by_position` or as noise. Only XML files, archives,
|
||||
JSON and key files have values: a text file's or database's change
|
||||
already lists its lines and rows.
|
||||
- `task`: a draft whose `checks` are suggestions from the net change of the
|
||||
documents the user worked on, or of the app's own state when no document
|
||||
changed.
|
||||
- `guards`: optional checks that the rest kept its seed values, such as a
|
||||
like sibling's field or a text file's neighbouring lines; add one or two
|
||||
to show the rest is untouched.
|
||||
- `notes`: why `files` is empty, or why a file's suggestions are thin, such
|
||||
as `by_position` when no attribute names the changed element.
|
||||
|
||||
### Write the prompt
|
||||
|
||||
@@ -344,7 +357,9 @@ document saved as a zip archive, such as FreeCAD's `.FCStd`, reads as its
|
||||
entries: point into an entry's view, and name array members by selector
|
||||
rather than position, as
|
||||
`/entries/[name=Document.xml]/view/root/children/[name=Object][@name=Hole]`,
|
||||
so the check survives an app version that writes them in another order. Give
|
||||
so the check survives an app version that writes them in another order. A
|
||||
gzip-compressed document, such as Gnumeric's `.gnumeric`, reads as the
|
||||
document inside: point into it as into the same document uncompressed. Give
|
||||
`value_equals` a `tolerance` to compare a number the app writes as text, such
|
||||
as `"5.0000000000000000"`, with a number. Check what the user wrote in a
|
||||
document with `text_equals` on its paragraph element, not `value_equals` on a
|
||||
|
||||
@@ -47,7 +47,7 @@ member comparison CLI still takes two assembly paths; process comparison takes
|
||||
two capture Evidence JSON paths. Check command help for the installed version.
|
||||
An input bundle grants no implicit file lookup: `evidence-file` and historical
|
||||
graph file selectors are accepted only by contracts advertising them. See the
|
||||
[CLI reuse guide](https://github.com/morluto/rea/blob/main/docs/cli.md#import-export-and-compare-evidence).
|
||||
[CLI reuse guide](https://github.com/morluto/rea/blob/main/docs/getting-started/cli.md#import-export-and-compare-evidence).
|
||||
|
||||
Completed `inspect_artifact` inventory also supports a summary and
|
||||
`view: {kind: "inventory", collection: "occurrences", logical_paths: ["package.json", "main.js"]}`.
|
||||
|
||||
@@ -6,7 +6,7 @@ For captured or bundled JavaScript that needs readable source recovery, use
|
||||
`additional_paths` when advertised, then analyze the returned `analysis_input`
|
||||
directory together. Each input retains its own snapshot, digest and byte-range
|
||||
provenance; inputs and recovered code are never executed. Recovery requires a
|
||||
caller-supplied Wakaru on Linux x64; see [the recovery guide](https://github.com/morluto/rea/blob/main/docs/javascript-recovery.md).
|
||||
caller-supplied Wakaru on Linux x64; see [the recovery guide](https://github.com/morluto/rea/blob/main/docs/guides/javascript/javascript-recovery.md).
|
||||
|
||||
Use `analyze_javascript_application` directly on the operator-supplied ASAR or
|
||||
extracted tree. When the question concerns known source paths and the connected
|
||||
|
||||
@@ -67,11 +67,18 @@ See [desktop installations](https://github.com/morluto/rea/blob/main/docs/deskto
|
||||
Use `inspect_go_binary` for an explicit local ELF, PE or Mach-O (universal
|
||||
files need `architecture`) when the
|
||||
question concerns the embedded compiler version, module/dependency versions,
|
||||
local replacements or build settings. No `open_binary`, Go installation or
|
||||
local replacements, build settings, or static Go string literals packed without
|
||||
NUL terminators. Pass `include_string_literals: true`
|
||||
(`--include-string-literals`, optional `max_string_literals` /
|
||||
`--max-string-literals`) to recover bounded inferred word-aligned `(ptr, len)`
|
||||
UTF-8 string slices from read-only data and page them through `go`
|
||||
`string_literals` views. No `open_binary`, Go installation or
|
||||
target execution is required. The CLI equivalent is `inspect-go-binary PATH`.
|
||||
Preserve artifact SHA-256, original file ranges, framed module bytes and every
|
||||
unparsed module-text line. A missing record is an unknown, not proof of a
|
||||
non-Go binary; observed metadata does not authenticate its claims. Function,
|
||||
non-Go binary; observed metadata does not authenticate its claims, and static
|
||||
`(ptr, len)` string recovery excludes compiler-inlined stack/immediate strings
|
||||
without proving runtime reachability. Function,
|
||||
source and type recovery remain a separate native-analysis question.
|
||||
|
||||
## Model files
|
||||
@@ -142,6 +149,20 @@ table or overlay. Bound snapshots, loaded IAT contents, and export-forward
|
||||
resolution remain unobserved. See
|
||||
[PE import and delay-load tables](https://github.com/morluto/rea/blob/main/docs/pe-imports.md).
|
||||
|
||||
## Windows Shell Link shortcuts
|
||||
|
||||
Use `inspect_windows_shortcut` for an explicit local `.lnk` file when the
|
||||
question concerns the recorded target path, arguments, working directory, icon
|
||||
location, volume serial, network share names, ExtraData blocks, or Tracker
|
||||
droid identifiers. No `open_binary`, Windows SDK, COM, or target execution is
|
||||
required. The CLI equivalent is `inspect-windows-shortcut PATH`. Preserve
|
||||
artifact SHA-256, FILETIME raw decimals, IDList type bytes, and ExtraData
|
||||
signatures. Unknown IDList items and ExtraData signatures remain raw with
|
||||
SHA-256; they are not guessed. Version-1 UUID MAC and timestamp values are
|
||||
labelled derived. A missing optional section is observed absence of that
|
||||
structure. See
|
||||
[Windows Shell Link shortcuts](https://github.com/morluto/rea/blob/main/docs/guides/native/windows-shortcut.md).
|
||||
|
||||
## PE TLS callbacks and load configuration
|
||||
|
||||
Use `inspect_pe_load_config` for an explicit local PE32/PE32+ image when the
|
||||
@@ -246,7 +267,7 @@ Choose `row_limit` when a finite sample is useful and keep truncation and
|
||||
unspecified row order explicit. Virtual tables, shadow tables and views are
|
||||
schema facts, not row-read targets. REA inspects private copies and leaves
|
||||
the source files untouched; obtain a coherent quiescent database/WAL snapshot
|
||||
before inspection. See [SQLite snapshots](https://github.com/morluto/rea/blob/main/docs/sqlite-databases.md).
|
||||
before inspection. See [SQLite snapshots](https://github.com/morluto/rea/blob/main/docs/guides/data/sqlite-databases.md).
|
||||
|
||||
## Recorded Linux crashes
|
||||
|
||||
@@ -261,7 +282,7 @@ The optional `include_debugger_context` facet adds mapping candidates through
|
||||
caller-supplied GDB/pwndbg in an owned core-only session. Display names do not
|
||||
establish current file identity; zero reported flags leave permissions unknown.
|
||||
Requested unavailable context fails with setup guidance. See
|
||||
[recorded crashes](https://github.com/morluto/rea/blob/main/docs/recorded-crashes.md)
|
||||
[recorded crashes](https://github.com/morluto/rea/blob/main/docs/guides/native/recorded-crashes.md)
|
||||
for exact upstream profiles, bounds and verification coverage.
|
||||
|
||||
## Offline ELF layout
|
||||
@@ -325,7 +346,8 @@ on the first MCP call. It retains the complete observation and returns the
|
||||
original selection, text availability and length without the body. Use
|
||||
`normalized_result.parent_evidence_id` with `inspect_analysis_view` and
|
||||
`view: {kind: "native", facet: "pseudocode", offset: 0, limit: 20000}`;
|
||||
follow `coverage.next_offset` for later pages. Offsets and limits count UTF-16
|
||||
follow `coverage.next_offset` for later pages. Choose a smaller limit if one
|
||||
page exceeds the client or transport budget. Offsets and limits count UTF-16
|
||||
code units, not lines or tokens. Pages reuse the same observation without
|
||||
repeating decompilation. Null and empty text remain distinct. Omitted or
|
||||
`complete` detail preserves full inline delivery. Summary delivery requires a
|
||||
@@ -393,7 +415,7 @@ In ephemeral mode, choose a private absolute directory and set
|
||||
`REA_GHIDRA_CHECKPOINT_DIR` in the environment starting REA. Restart the MCP server
|
||||
after changing that launch configuration; no current tool call or runtime
|
||||
analysis-setting update enables it. Stock ELF/PE/Mach-O imports on Linux/macOS
|
||||
are supported; see the [checkpoint setup and limitations](https://github.com/morluto/rea/blob/main/docs/installation.md#automatically-checkpoint-an-owned-ghidra-program).
|
||||
are supported; see the [checkpoint setup and limitations](https://github.com/morluto/rea/blob/main/docs/getting-started/installation.md#automatically-checkpoint-an-owned-ghidra-program).
|
||||
|
||||
With the setting enabled, normal opens restore compatible saved Programs
|
||||
automatically. Initial completed analysis is saved, and `close_binary` saves
|
||||
@@ -414,7 +436,7 @@ import overrides and repair scripts are unavailable in this mode. Treat original
|
||||
analysis completeness/settings as unknown and prior edits as caller-project state.
|
||||
The program's recorded import digest must match the target; changed project content
|
||||
requires reopening for a fresh profile. See the
|
||||
[setup and preparation guide](https://github.com/morluto/rea/blob/main/docs/installation.md#reuse-an-existing-ghidra-project).
|
||||
[setup and preparation guide](https://github.com/morluto/rea/blob/main/docs/getting-started/installation.md#reuse-an-existing-ghidra-project).
|
||||
|
||||
## Ghidra startup deadline recovery
|
||||
|
||||
@@ -448,7 +470,7 @@ and memory controls in place. Disable specific expensive analyzers only when
|
||||
their missing coverage is acceptable and retain the resulting limitations.
|
||||
Exported C and embedded resources remain useful independent evidence, but a
|
||||
timeout does not establish complete analysis or absence of code. See the
|
||||
[deadline and client guide](https://github.com/morluto/rea/blob/main/docs/mcp-contracts.md#ghidra-first-query-deadlines-and-recovery).
|
||||
[deadline and client guide](https://github.com/morluto/rea/blob/main/docs/reference/mcp-contracts.md#ghidra-first-query-deadlines-and-recovery).
|
||||
|
||||
## Bridge request ceiling
|
||||
|
||||
@@ -599,7 +621,7 @@ broader metadata recovery on Linux; it requires an explicitly configured
|
||||
NativeAOT JAR. These are separate routes. The built-in parser also runs on
|
||||
Windows Ghidra P0; read frozen literals from its report, because
|
||||
`search_strings` does not include them. See the
|
||||
[NativeAOT guide](https://github.com/morluto/rea/blob/main/docs/ghidra-nativeaot.md)
|
||||
[NativeAOT guide](https://github.com/morluto/rea/blob/main/docs/providers/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
|
||||
@@ -628,7 +650,7 @@ every executable in the bundle. It also lists missing or weak loads and earlier
|
||||
provides them.
|
||||
|
||||
Use `extract_artifact` when materialized files from a supported format are needed.
|
||||
It extracts the active target and accepts optional `integrity_policy`; see the [MCP contracts](https://github.com/morluto/rea/blob/main/docs/mcp-contracts.md).
|
||||
It extracts the active target and accepts optional `integrity_policy`; see the [MCP contracts](https://github.com/morluto/rea/blob/main/docs/reference/mcp-contracts.md).
|
||||
It materializes all regular files into a fresh temporary directory chosen by
|
||||
REA. Symlinks and encrypted entries are inventory facts, not extractable files.
|
||||
The result reports the materialized directory; callers do not choose the
|
||||
@@ -656,7 +678,7 @@ temporary, not a retained export of the image's contents.
|
||||
For headerless DOS COM, explicitly open with `format: "dos-com"` (CLI
|
||||
`--target-format dos-com`). Inspect the load image before trusting function
|
||||
analysis: the entry is `0x10100`, file offset zero, with imposed real-mode segment
|
||||
context. PSP/stack/device state remains unmodeled. See [DOS guide](https://github.com/morluto/rea/blob/main/docs/ghidra-dos.md).
|
||||
context. PSP/stack/device state remains unmodeled. See [DOS guide](https://github.com/morluto/rea/blob/main/docs/providers/ghidra-dos.md).
|
||||
|
||||
Use `inspect_byte_entropy` to triage high- and low-entropy ranges before extraction.
|
||||
|
||||
@@ -670,7 +692,7 @@ otherwise. Big-endian ARM, Thumb-only, and Cortex-M variants are unsupported.
|
||||
`0x0000..0xffff`. 65C02, 65816, cartridge containers, bank switching, and mapper
|
||||
semantics are unsupported. `m68k` requires an even entry and decodes the 68040
|
||||
superset of the 68000 family; Amiga/Atari containers and vector-table entry
|
||||
discovery are unsupported. Windows Ghidra P0 admits raw images only for `6502`. See [raw binary guide](https://github.com/morluto/rea/blob/main/docs/raw-binary.md).
|
||||
discovery are unsupported. Windows Ghidra P0 admits raw images only for `6502`. See [raw binary guide](https://github.com/morluto/rea/blob/main/docs/providers/raw-binary.md).
|
||||
|
||||
Intel HEX, S-record, UF2 and DfuSe files are containers, not raw images:
|
||||
`inspect_artifact` lists address regions (UF2 per familyID, DfuSe per element
|
||||
@@ -684,6 +706,11 @@ numbering gaps leave coverage unknown; a DfuSe suffix CRC mismatch follows
|
||||
Fresh-import sessions admit annotations; existing-project reuse is read-only.
|
||||
Use `annotate_native_function` for one function name and/or entry comments, with at least one explicit change. Review its annotation readback and refreshed dossier inline. Changes are atomic; empty comments clear them, omitted fields preserve them. Later MCP calls observe edits. Normal close saves them when owned Program checkpoint mode is enabled; ephemeral mode discards them. CLI `annotate-native-function` follows the same setting when closing after its updated result. Select the [checkpoint workflow](#continue-editable-ghidra-analysis-across-processes) before edits that must survive a later process. Original executable bytes are unchanged; edits invalidate immutable snapshots. Windows P0 does not admit database mutations. For naming only, `set_address_name` / `set_addresses_names` also work with Ghidra: they name function entries or data addresses (primary labels) and return compact per-address success booleans instead of a dossier. Ghidra rejects batch addresses that request the same name or a name another selected address holds; `raw_result.failures` gives each failure's reason.
|
||||
|
||||
A provider switch or different target can retire the active Ghidra database and discard
|
||||
its edits, even if the new provider fails on a later call. Same-target,
|
||||
same-profile reopen keeps the active database. Retained annotation Evidence
|
||||
records what happened; it does not restore the edits.
|
||||
|
||||
For `compare_functions`, obtain `analyze_function` Evidence before and after the
|
||||
edit while the MCP session is open; annotation Evidence is not a comparison
|
||||
input. Export the needed Evidence before close if comparison will happen later.
|
||||
@@ -704,7 +731,7 @@ code pages, payload hashes and static icon-group references. Same-language icon
|
||||
resolution is explicit; missing references and size mismatch remain visible.
|
||||
Other payloads are opaque, and this operation does not decode images or simulate
|
||||
Windows resource loading. Consult the budgets and supported tree profile in
|
||||
[offline binary diagnostics](https://github.com/morluto/rea/blob/main/docs/binary-diagnostics.md).
|
||||
[offline binary diagnostics](https://github.com/morluto/rea/blob/main/docs/guides/native/binary-diagnostics.md).
|
||||
|
||||
## Offline PE and ELF export tables
|
||||
|
||||
@@ -714,7 +741,7 @@ directory or ELF dynamic symbol table on any host without opening a native
|
||||
target. Ordinal-only, forwarded and hidden-version exports stay distinct;
|
||||
partial or unsupported coverage means the inventory is incomplete, not that
|
||||
exports are absent. Use `inspect_macho` for Mach-O. See
|
||||
[offline binary diagnostics](https://github.com/morluto/rea/blob/main/docs/binary-diagnostics.md).
|
||||
[offline binary diagnostics](https://github.com/morluto/rea/blob/main/docs/guides/native/binary-diagnostics.md).
|
||||
|
||||
For exact core-module import/export differences, use `compare_wasm_interfaces`
|
||||
with two complete inspection Evidence records (or current-session retained
|
||||
|
||||
@@ -41,10 +41,16 @@ behavior unknown. Record truncation, unmatched breakpoints, changed target
|
||||
identity and cleanup uncertainty as limitations, rather than treating no retained
|
||||
event as proof that the behavior never occurs.
|
||||
|
||||
Detailed contracts and prerequisites: [Frida](https://github.com/morluto/rea/blob/main/docs/frida-instrumentation.md),
|
||||
For same-session MCP comparisons, pass each capture inline or reuse it as
|
||||
`{"kind":"retained-evidence","evidence_id":"ev_..."}`. Default comparison
|
||||
keeps capture-local timing as provenance without treating scheduler or observer
|
||||
latency as a behavior change; use an exact `trace_spec` event when timing is part
|
||||
of the analyst question.
|
||||
|
||||
Detailed contracts and prerequisites: [Frida](https://github.com/morluto/rea/blob/main/docs/guides/runtime/frida-instrumentation.md),
|
||||
[GDB/Rizin/Cutter](https://github.com/morluto/rea/blob/main/docs/reverse-engineering-tools.md),
|
||||
[process capture](https://github.com/morluto/rea/blob/main/docs/process-capture.md),
|
||||
and [native calls/UI](https://github.com/morluto/rea/blob/main/docs/native-investigation.md#native-desktop-observation).
|
||||
[process capture](https://github.com/morluto/rea/blob/main/docs/guides/runtime/process-capture.md),
|
||||
and [native calls/UI](https://github.com/morluto/rea/blob/main/docs/guides/native/native-investigation.md#native-desktop-observation).
|
||||
|
||||
## Browser and Electron
|
||||
|
||||
@@ -130,5 +136,5 @@ Inspect native `.saz` snapshots with `inspect_web_network_capture` and
|
||||
traffic analysis, connect Everywhere's separate MCP server and use its
|
||||
advertised session tools with an explicit `sessionsSource` (`LiveTraffic` or
|
||||
`AgentCalls`). Preserve existing sessions and filters when inspecting a
|
||||
recorded run. See the [capture and MCP guide](https://github.com/morluto/rea/blob/main/docs/web-network-captures.md)
|
||||
recorded run. See the [capture and MCP guide](https://github.com/morluto/rea/blob/main/docs/guides/web/web-network-captures.md)
|
||||
for the workflow and Telerik's public setup and traffic-debugging skills.
|
||||
@@ -27,7 +27,7 @@ body:
|
||||
attributes:
|
||||
label: Documentation location
|
||||
description: Link the page, section, command, API, skill, or inline comment.
|
||||
placeholder: README.md#quick-start or docs/mcp-contracts.md
|
||||
placeholder: README.md#quick-start or docs/reference/mcp-contracts.md
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ source, link, or rendered-document checks. -->
|
||||
- User-visible CLI/MCP output (if applicable):
|
||||
- Remaining proof gaps:
|
||||
|
||||
For boundary fixes, identify the applicable [boundary regressions](https://github.com/morluto/rea/blob/main/docs/testing.md#boundary-regressions)
|
||||
and [lifecycle regressions](https://github.com/morluto/rea/blob/main/docs/testing.md#lifecycle-regressions)
|
||||
For boundary fixes, identify the applicable [boundary regressions](https://github.com/morluto/rea/blob/main/docs/development/testing.md#boundary-regressions)
|
||||
and [lifecycle regressions](https://github.com/morluto/rea/blob/main/docs/development/testing.md#lifecycle-regressions)
|
||||
covered by the evidence above, and explain relevant gaps.
|
||||
|
||||
For evidence-bearing changes:
|
||||
@@ -99,7 +99,7 @@ limits, security/privacy/containment implications, and meaningful proof gaps. --
|
||||
its new behavior and migration, and why compatibility/deprecation cannot
|
||||
preserve it. Every release increments minor, including breaking changes;
|
||||
keep breaking markers and migration notes so callers can assess compatibility.
|
||||
See docs/releasing.md. -->
|
||||
See docs/development/releasing.md. -->
|
||||
- Real Hopper/Ghidra, browser, or OS coverage:
|
||||
- Package or release metadata impact:
|
||||
- Security, privacy, process, or containment review:
|
||||
|
||||
@@ -924,6 +924,7 @@ jobs:
|
||||
tests/process-global/filesystemSnapshotFallbackCancellation.test.ts
|
||||
tests/boundary/filesystem/typescriptCompiler.test.ts
|
||||
tests/boundary/filesystem/releaseProposal.test.ts
|
||||
tests/acceptance/byteEntropyWindowsIdentity.test.ts
|
||||
tests/boundary/filesystem/binaryTarget.test.ts
|
||||
src/contracts/sessionPathInputs.test.ts
|
||||
tests/boundary/filesystem/directAnalysisSnapshotReplay.test.ts
|
||||
@@ -1016,8 +1017,8 @@ jobs:
|
||||
uses: ./.github/actions/npm-cache
|
||||
- run: npm ci
|
||||
- run: npm run docs:check
|
||||
- name: Render documentation and validate page links
|
||||
run: npm run docs:build
|
||||
- name: Verify published routes, source links and local anchors
|
||||
run: npm run verify:docs:routes
|
||||
- name: Generation leaves authored files unchanged
|
||||
run: git diff --exit-code
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
|
||||
@@ -95,3 +95,31 @@ jobs:
|
||||
decode cortex ARM:LE:32:Cortex mrs/4/msp bx/2/lr
|
||||
decode v8m ARM:LE:32:v8-m mrs/4/msplim bx/2/lr
|
||||
decode xtensa Xtensa:LE:32:default entry/3/a1 retw.n/2
|
||||
# A call through a writable slot keeps Ghidra's recorded target as an
|
||||
# observed callee while callee coverage stays partial; a direct call is
|
||||
# the complete control. The source-owned x86-64 bytes are never executed.
|
||||
- name: Keep computed-call targets non-exhaustive in callee coverage
|
||||
shell: bash
|
||||
run: |
|
||||
java_home_variable="JAVA_HOME_${GHIDRA_JAVA_MAJOR}_X64"
|
||||
export JAVA_HOME="${!java_home_variable}"
|
||||
probe_root="${RUNNER_TEMP}/rea-computed-call"
|
||||
mkdir -p "${probe_root}/project"
|
||||
{
|
||||
printf '\270\001\000\000\000\303\314\314' # 0x1000: mov eax, 1; ret
|
||||
printf '\270\002\000\000\000\303\314\314' # 0x1008: mov eax, 2; ret
|
||||
printf '\377\025\052\000\000\000\303\314' # 0x1010: call [rip + 0x2a]; ret
|
||||
printf '\377\320\303\314\314\314\314\314' # 0x1018: call rax; ret
|
||||
printf '\350\333\377\377\377\303\314\314' # 0x1020: call 0x1000; ret
|
||||
printf '\314%.0s' $(seq 24) # 0x1028: int3 padding
|
||||
printf '\000\020\000\000\000\000\000\000' # 0x1040: slot = 0x1000
|
||||
} > "${probe_root}/computed-call.bin"
|
||||
test "$(wc -c < "${probe_root}/computed-call.bin")" -eq 72
|
||||
timeout 180s "${GHIDRA_INSTALL_DIR}/support/analyzeHeadless" "${probe_root}/project" ComputedCall \
|
||||
-import "${probe_root}/computed-call.bin" -loader BinaryLoader -loader-baseAddr 0x1000 \
|
||||
-processor x86:LE:64:default -noanalysis -readOnly -deleteProject \
|
||||
-scriptPath "${GITHUB_WORKSPACE}/tests/conformance/ghidra;${GITHUB_WORKSPACE}/bridge/ghidra" \
|
||||
-postScript ReaComputedCallCoverageProbe.java "${GITHUB_WORKSPACE}/bridge/ghidra" \
|
||||
> "${probe_root}/output.log" 2>&1 || { cat "${probe_root}/output.log"; exit 1; }
|
||||
cat "${probe_root}/output.log"
|
||||
grep -F 'REA_COMPUTED_CALL_COVERAGE_OK slot=observed-complete-discovery-unknown register=partial direct=complete callers=discovery-unknown' "${probe_root}/output.log"
|
||||
@@ -27,4 +27,4 @@ jobs:
|
||||
id: npm-cache
|
||||
uses: ./.github/actions/npm-cache
|
||||
- run: npm ci
|
||||
- run: npm run docs:build
|
||||
- run: npm run verify:docs:routes
|
||||
@@ -14,13 +14,13 @@ Preserve caller-selected inputs and local evidence, including output, URLs, path
|
||||
|
||||
## Architecture and Cleanup
|
||||
|
||||
Dependencies flow inward: domain semantics and contracts, provider adapters, shared application workflows, then CLI/MCP adapters. Keep engine protocols and provider-specific code out of domain/application layers. See [docs/architecture.mermaid](docs/architecture.mermaid) when changing composition.
|
||||
Dependencies flow inward: domain semantics and contracts, provider adapters, shared application workflows, then CLI/MCP adapters. Keep engine protocols and provider-specific code out of domain/application layers. See [docs/architecture/architecture.mermaid](docs/architecture/architecture.mermaid) when changing composition.
|
||||
|
||||
Give each interpretation and resource a clear owner. Consumers must use that owner's parsed facts rather than reinterpret raw source. Preserve identity, omission, uncertainty, and source evidence across boundaries. Retain ownership of resources whose cleanup failed. Reuse `src/process/` supervision and identity primitives; a PID and executable path alone do not establish ownership after exit or reuse.
|
||||
|
||||
Keep proof of ownership separate from validity, editability, and readiness. Malformed owned data may still be safely removable. Unresolved identity or applicability must remain unknown rather than be treated as absent, foreign, or aligned.
|
||||
|
||||
For lifecycle changes, follow [ownership and completion invariants](docs/tool-design.md#own-the-lifecycle) and select the applicable [lifecycle regressions](docs/testing.md#lifecycle-regressions). Include late handshakes, cancellation during final cleanup, mixed child outcomes, and cleanup retry where those stages exist; active-execution cancellation alone does not cover finalization.
|
||||
For lifecycle changes, follow [ownership and completion invariants](docs/development/tool-design.md#own-the-lifecycle) and select the applicable [lifecycle regressions](docs/development/testing.md#lifecycle-regressions). Include late handshakes, cancellation during final cleanup, mixed child outcomes, and cleanup retry where those stages exist; active-execution cancellation alone does not cover finalization.
|
||||
|
||||
Before adding complexity for a speculative or vanishingly unlikely race or security edge case, explain the concrete failure mode, likelihood, and complexity cost to the user and get their buy-in. Do not silently expand scope for theoretical robustness.
|
||||
|
||||
@@ -68,6 +68,12 @@ do not establish fewer tokens or faster analysis.
|
||||
|
||||
## Development
|
||||
|
||||
Documentation ownership and authoring conventions live in
|
||||
[docs/development/documentation.md](docs/development/documentation.md). A feature
|
||||
uses `docs/specs/<domain>/<feature-slug>/spec.md`, one `plan.md` and `tasks.md`;
|
||||
individual architectural decisions use `docs/adr/<domain>/<decision-slug>.md`.
|
||||
Consult the [documentation directory](docs/README.md) before adding a guide.
|
||||
|
||||
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`. Prefix `PATH="/usr/local/bin:$PATH"` before `node` and `npm`.
|
||||
|
||||
- `npm ci`: install locked dependencies.
|
||||
@@ -80,15 +86,15 @@ Use [.nvmrc](.nvmrc) and `package.json#packageManager` for the pinned toolchain.
|
||||
Use relevant checks for the change. The complete local gate, `npm run check:pr`, is optional for broad changes or CI diagnosis. See [CONTRIBUTING.md](CONTRIBUTING.md) for development, generated-file ownership, and release conventions.
|
||||
|
||||
When changing installers or setup recovery, follow
|
||||
[Checking installers and publisher downloads](docs/testing.md#checking-installers-and-publisher-downloads).
|
||||
[Checking installers and publisher downloads](docs/development/testing.md#checking-installers-and-publisher-downloads).
|
||||
|
||||
Coordinate expensive checks across agents. If a test unexpectedly consumes heavy CPU, stop its owned process family and profile a bounded representative case before retrying. Inspect production work, fixture generation, subprocesses, and repeated setup; preserve regression coverage when optimizing. Follow the [test resource guidance](docs/testing.md#developer-commands).
|
||||
Coordinate expensive checks across agents. If a test unexpectedly consumes heavy CPU, stop its owned process family and profile a bounded representative case before retrying. Inspect production work, fixture generation, subprocesses, and repeated setup; preserve regression coverage when optimizing. Follow the [test resource guidance](docs/development/testing.md#developer-commands).
|
||||
|
||||
`docs/public/product-catalog.json`, `docs/verification/managed-conformance-*.json`, and `skills/` are ignored outputs. Edit source contracts and `.agents/skills/reverse-engineer-anything/`, then regenerate as needed. `.cache/mcp-tool-catalog.json` is test metadata; runtime builds and source checking do not consume it. Never commit binaries, provider project documents, credentials, `dist/`, `node_modules/`, or local planning artifacts.
|
||||
|
||||
## Tool and Test Changes
|
||||
|
||||
For tool design, follow [docs/tool-design.md](docs/tool-design.md): start from the analyst question, reuse existing contracts, preserve caller choices, and return useful evidence inline. Limits must follow real format, protocol, authority, or resource constraints. Account for representation expansion before allocation; derive completeness from examined coverage.
|
||||
For tool design, follow [docs/development/tool-design.md](docs/development/tool-design.md): start from the analyst question, reuse existing contracts, preserve caller choices, and return useful evidence inline. Limits must follow real format, protocol, authority, or resource constraints. Account for representation expansion before allocation; derive completeness from examined coverage.
|
||||
|
||||
For user- or agent-facing tool problems, prioritize fixing the owning behavior,
|
||||
contract, and actionable result or recovery at the point of use. Document the
|
||||
@@ -96,7 +102,7 @@ result in product docs when explanation is needed. Add skill guidance only for
|
||||
workflow judgment or context that the tool cannot reasonably convey; do not use
|
||||
a skill as the primary repair for a discoverability or contract defect.
|
||||
|
||||
For test changes or provider claims, use [docs/testing.md](docs/testing.md). Select applicable [boundary regressions](docs/testing.md#boundary-regressions) for parser, inventory, snapshot, and projection fixes. Prefer real public CLI/MCP workflows, then production-boundary integration, then producer goldens. Keep module tests for distinct semantics stronger workflows cannot reliably reproduce. Preserve malformed-input, cancellation, cleanup, permission, capacity, and target-identity coverage when pruning. Report unverified coverage explicitly; simulated providers do not establish real-provider behavior.
|
||||
For test changes or provider claims, use [docs/development/testing.md](docs/development/testing.md). Select applicable [boundary regressions](docs/development/testing.md#boundary-regressions) for parser, inventory, snapshot, and projection fixes. Prefer real public CLI/MCP workflows, then production-boundary integration, then producer goldens. Keep module tests for distinct semantics stronger workflows cannot reliably reproduce. Preserve malformed-input, cancellation, cleanup, permission, capacity, and target-identity coverage when pruning. Report unverified coverage explicitly; simulated providers do not establish real-provider behavior.
|
||||
|
||||
Use Conventional Commit subjects and PR titles. Mark breaking changes with `!` or a `BREAKING CHANGE:` footer. Describe behavior changes, relevant validation, and real-provider verification scope.
|
||||
|
||||
|
||||
+7
-7
@@ -132,8 +132,8 @@ Full contribution record: [4 commits and 1 merged PR](https://github.com/morluto
|
||||
- **Kuna analysis:** Use a caller-installed Kuna for procedure listings, pseudocode, assembly, call relationships, exact-address xrefs and cached string searches. Project exports retain source spans and digests; repeated requests reuse completed work. Recorded real-provider coverage uses Kuna 1.833 on Linux; Windows, PE and universal Mach-O are unsupported. See [the provider guide](docs/kuna-provider.md). ([#3832](https://github.com/morluto/rea/pull/3832), [#3854](https://github.com/morluto/rea/pull/3854), [#4071](https://github.com/morluto/rea/pull/4071), [#4095](https://github.com/morluto/rea/pull/4095)). Thanks @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **Retained JavaScript facts:** Query exact application paths, selected properties and filtered module references through `inspect_analysis_view`, with paging and complete row Evidence. These views reuse completed analysis and preserve source selection and unknown coverage. ([#4265](https://github.com/morluto/rea/pull/4265), [morluto/rea#4190](https://github.com/morluto/rea/issues/4190), [#4097](https://github.com/morluto/rea/pull/4097), [morluto/rea#4092](https://github.com/morluto/rea/issues/4092)). Thanks @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **APK locale tables:** Request several resource locales in one decode with repeatable CLI `--locales` or MCP `locales`. Each table reports its status and coverage; existing single-locale fields remain available. ([#4804](https://github.com/morluto/rea/pull/4804), [morluto/rea#4777](https://github.com/morluto/rea/issues/4777)). Thanks @abhay-2108, @N0zoM1z0.
|
||||
- **Windows ARM binaries:** Ghidra admits ARMNT/Thumb-2 and ARM64 PE applications and DLLs on the Windows x64 host lane. Recorded Ghidra 12.1.4 verification uses `WindowsResourceReference` disabled and raised startup budgets; default-analyzer completion, ARM64EC/ARM64X and Windows-on-Arm hosts remain unverified or unsupported. See [the exact scope](docs/windows-ghidra-p0.md#native-authority-and-target-identity). ([#3965](https://github.com/morluto/rea/pull/3965), [morluto/rea#2186](https://github.com/morluto/rea/issues/2186)). Thanks @N0zoM1z0, @WestLabsAI.
|
||||
- **Raw m68k images:** Analyze explicitly selected big-endian m68k raw binaries using Ghidra’s fixed 68000 profile and a caller-supplied aligned entry. Real CLI/MCP verification used Ghidra 12.1.4 on macOS arm64; Linux is unverified and Windows P0 does not admit m68k. See [mapping requirements](docs/raw-binary.md). ([#4018](https://github.com/morluto/rea/pull/4018)). Thanks @icedac.
|
||||
- **Windows ARM binaries:** Ghidra admits ARMNT/Thumb-2 and ARM64 PE applications and DLLs on the Windows x64 host lane. Recorded Ghidra 12.1.4 verification uses `WindowsResourceReference` disabled and raised startup budgets; default-analyzer completion, ARM64EC/ARM64X and Windows-on-Arm hosts remain unverified or unsupported. See [the exact scope](docs/providers/windows-ghidra-p0.md#native-authority-and-target-identity). ([#3965](https://github.com/morluto/rea/pull/3965), [morluto/rea#2186](https://github.com/morluto/rea/issues/2186)). Thanks @N0zoM1z0, @WestLabsAI.
|
||||
- **Raw m68k images:** Analyze explicitly selected big-endian m68k raw binaries using Ghidra’s fixed 68000 profile and a caller-supplied aligned entry. Real CLI/MCP verification used Ghidra 12.1.4 on macOS arm64; Linux is unverified and Windows P0 does not admit m68k. See [mapping requirements](docs/providers/raw-binary.md). ([#4018](https://github.com/morluto/rea/pull/4018)). Thanks @icedac.
|
||||
- **JADX deadlines:** Set `REA_JADX_OPERATION_TIMEOUT_MS` to extend APK loading and upstream operation deadlines together. Doctor reports the effective value and setup forwards an explicit selection. ([#4466](https://github.com/morluto/rea/pull/4466), [morluto/rea#3918](https://github.com/morluto/rea/issues/3918)). Thanks @jaychou813, @SandstromPL.
|
||||
- **Electron window options:** Resolve stable local constant `BrowserWindow` options while retaining source provenance. Relevant writes and escapes keep the result unknown. ([#4400](https://github.com/morluto/rea/pull/4400), [morluto/rea#4366](https://github.com/morluto/rea/issues/4366)). Thanks @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **Language editions:** Add the Greek website edition and Malayalam documentation, with Korean typography and translation corrections across the site. ([#3520](https://github.com/morluto/rea/pull/3520), [#4792](https://github.com/morluto/rea/pull/4792), [#3821](https://github.com/morluto/rea/pull/3821), [morluto/rea#3820](https://github.com/morluto/rea/issues/3820), [#3799](https://github.com/morluto/rea/pull/3799), [morluto/rea#3798](https://github.com/morluto/rea/issues/3798), [#4344](https://github.com/morluto/rea/pull/4344), [#3856](https://github.com/morluto/rea/pull/3856), [#4166](https://github.com/morluto/rea/pull/4166)). Thanks @gensokyo-dev, @hi2242, @kalayciburak, @kaoru0822-kitauji, @kraken-503, @kukinghan, @N0zoM1z0, @yeseong0412.
|
||||
@@ -192,7 +192,7 @@ Full contribution record: [571 commits and 236 merged PRs](https://github.com/mo
|
||||
|
||||
## [6.5.0](https://github.com/morluto/rea/compare/rea-agents-6.4.0...rea-agents-6.5.0) (2026-10-13)
|
||||
|
||||
Provider prerequisites and recorded verification scope are listed in [the testing guide](docs/testing.md).
|
||||
Provider prerequisites and recorded verification scope are listed in [the testing guide](docs/development/testing.md).
|
||||
|
||||
### Highlights
|
||||
|
||||
@@ -220,7 +220,7 @@ Provider prerequisites and recorded verification scope are listed in [the testin
|
||||
- **HarmonyOS packages:** inventory HAP/HSP/App Pack structures without executing code. The recorded real workflow covers one pinned HAP through repository-built CLI/MCP; installed-package and real HSP/App Pack coverage remain unverified. ([#1447](https://github.com/morluto/rea/pull/1447)). Thanks @BaaRai.
|
||||
- **Ghidra raw inputs and references:** compatible Linux/macOS Ghidra profiles accept caller-selected raw architecture/entry information and expose typed incoming references at exact addresses. Windows Ghidra P0 admits the raw NMOS 6502 profile described below; other raw targets and the incoming-reference facet remain outside Windows P0. ([#1868](https://github.com/morluto/rea/pull/1868), [issue morluto/rea#1836](https://github.com/morluto/rea/issues/1836), [#1715](https://github.com/morluto/rea/pull/1715), [issue morluto/rea#1245](https://github.com/morluto/rea/issues/1245)). Thanks @bugstan, @casesolved-co-uk, @mvanhorn, @N0zoM1z0.
|
||||
- **Ghidra MIPS:** Add bounded MIPS32r2/o32 relocatable objects, soft-float integer-register storage, admitted MIPS16 shared ELF, and a narrowly admitted recordless legacy MIPS32 executable profile. The latter pins an endian-matched 32-bit language and records inferred o32 as an analysis assumption. Admission follows each documented ABI/flag/relocation boundary. ([#1949](https://github.com/morluto/rea/pull/1949), [issue morluto/rea#1937](https://github.com/morluto/rea/issues/1937), [#1950](https://github.com/morluto/rea/pull/1950), [issue morluto/rea#1938](https://github.com/morluto/rea/issues/1938), [#1991](https://github.com/morluto/rea/pull/1991), [issue morluto/rea#1851](https://github.com/morluto/rea/issues/1851), [#1898](https://github.com/morluto/rea/pull/1898), [issue morluto/rea#1620](https://github.com/morluto/rea/issues/1620)). Thanks @AurelioB, @BaaRai, @bqw371, @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **Ghidra RISC-V:** admit little-endian RV32/RV64 `ET_EXEC` ELF declaring the supported double-float ABI. Relocatable/shared, big-endian and other ABI profiles remain refused; see [the profile and recorded lane](docs/ghidra-riscv.md). ([#2151](https://github.com/morluto/rea/pull/2151)). Thanks @NIU-123370.
|
||||
- **Ghidra RISC-V:** admit little-endian RV32/RV64 `ET_EXEC` ELF declaring the supported double-float ABI. Relocatable/shared, big-endian and other ABI profiles remain refused; see [the profile and recorded lane](docs/providers/ghidra-riscv.md). ([#2151](https://github.com/morluto/rea/pull/2151)). Thanks @NIU-123370.
|
||||
- **PSP static ELF profile:** the Ghidra profile is Linux x64, bounded little-endian ELF32 `ET_EXEC` with the documented PSP/ABI declarations and a compatible caller-installed Allegrex extension. PRX, shared/relocatable images, PBP/ISO/CSO and runtime emulation are outside scope. Historical extension experiments are separate from public-provider verification; real public Ghidra PSP coverage remains unverified. ([#1599](https://github.com/morluto/rea/pull/1599)). Thanks @jaelliot.
|
||||
- **Ghidra analysis settings:** apply validated analyzer overrides before analysis while retaining the selected analysis profile. ([#1913](https://github.com/morluto/rea/pull/1913)). Thanks @akushonkamen, @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **Attached native IDA MCP:** add an optional native bridge alongside existing legacy/headless profiles. Recorded native runs use Linux IDA Free 9.4 with a navigation correction and Windows IDA Pro 9.3 with a loopback-listener change; stock native switching, native macOS and Windows IDA Free remain unverified. Attached databases remain read-only and are never saved or closed. ([#1544](https://github.com/morluto/rea/pull/1544)). Thanks @imissapixel, @N0zoM1z0.
|
||||
@@ -292,7 +292,7 @@ Provider prerequisites and recorded verification scope are listed in [the testin
|
||||
- **Source maps:** original-source and mapping rows preserve a null source name when unavailable. Handle null explicitly instead of expecting an invented unknown-source string; new index fields remain optional when reading older Evidence. ([ee50ed1](https://github.com/morluto/rea/commit/ee50ed121e38cc6e1a2ff0dc8b789f15f71c5402)).
|
||||
- **Streamed filtered JSON:** `--filter-output` now emits JSON `null` instead of `{}` when the selected value is null; consumers must distinguish a present null from a missing selection. Use `--full-output` when an object envelope is required. ([#2333](https://github.com/morluto/rea/pull/2333)). Thanks @Jackmeson1.
|
||||
- **Call graphs:** `get_call_graph.normalized_result` is now `{ graph, limitations }`; read traversal-depth groups under `graph` and retain relationship-specific caveats. Contract/fixture validation does not establish new Ghidra or IDA engine coverage. ([5dfb9d0](https://github.com/morluto/rea/commit/5dfb9d050c2cc44a61b183dae765bef4d22a53b7)).
|
||||
- **MCP discovery:** `binary_session` no longer repeats `server_identity.catalog.tools`. Use the connected server tool list, grouped `tool_availability` and provider capabilities; see [MCP contracts](docs/mcp-contracts.md). Origin: [6395e8d](https://github.com/morluto/rea/commit/6395e8d3007d5ee453477460e7ee1c51cff76be0). ([#1988](https://github.com/morluto/rea/pull/1988)). Thanks @kaoru0822-kitauji, @N0zoM1z0.
|
||||
- **MCP discovery:** `binary_session` no longer repeats `server_identity.catalog.tools`. Use the connected server tool list, grouped `tool_availability` and provider capabilities; see [MCP contracts](docs/reference/mcp-contracts.md). Origin: [6395e8d](https://github.com/morluto/rea/commit/6395e8d3007d5ee453477460e7ee1c51cff76be0). ([#1988](https://github.com/morluto/rea/pull/1988)). Thanks @kaoru0822-kitauji, @N0zoM1z0.
|
||||
|
||||
- **Provider admission:** MIPS targets with unresolved GNU ABI attributes are refused. Supply supported ABI declarations. Saved Hopper databases on macOS are unavailable because the launcher cannot run the analysis bridge when opening a database; select an executable target instead. Database support requires a script-capable database launch route. ([d4bd65c](https://github.com/morluto/rea/commit/d4bd65c53c0254d0195cc7ab8da163dcadfd3b9b)).
|
||||
- **Segment extents:** `binary_overview` segment length may be null when Hopper coordinates cannot establish a finite extent in one address space. Preserve unknown rather than converting it to zero or a saturated value. ([36db19c](https://github.com/morluto/rea/commit/36db19c59)).
|
||||
@@ -372,7 +372,7 @@ Full contribution record: [336 commits and 163 merged PRs](https://github.com/mo
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **captures:** Historical captures without current producer accounting or transaction identity, and web diffs missing accessibility or storage dimensions, are rejected. Preserve original captures and recapture with the current producer; update comparison consumers to include every dimension rather than synthesizing missing observations. See the [process capture guide](docs/process-capture.md) and [browser scenario contract](docs/browser-scenario-contract.md). ([3283a45](https://github.com/morluto/rea/commit/3283a45d09457c79e3adadb50a48620926d4bc5b))
|
||||
* **captures:** Historical captures without current producer accounting or transaction identity, and web diffs missing accessibility or storage dimensions, are rejected. Preserve original captures and recapture with the current producer; update comparison consumers to include every dimension rather than synthesizing missing observations. See the [process capture guide](docs/guides/runtime/process-capture.md) and [browser scenario contract](docs/guides/web/browser-scenario-contract.md). ([3283a45](https://github.com/morluto/rea/commit/3283a45d09457c79e3adadb50a48620926d4bc5b))
|
||||
* **browser:** JSON shape paths now contain typed property and array-element segments. WebMCP input_schema_shape is replaced by input_schema and input_schema_sha256, retaining declared examples and defaults.
|
||||
* **process:** Filesystem digest omission entries now require system_code; budget and changed-file omissions use null, and unavailable-file omissions preserve the operating-system error code.
|
||||
* **contracts:** Provider analysis outputs must explicitly supply metadata previously repaired with defaults; unsupported nullable facets must be reported as null.
|
||||
@@ -540,7 +540,7 @@ Full contribution record: [336 commits and 163 merged PRs](https://github.com/mo
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
Read the [6.1 to 6.2 migration guide](docs/migration-6.2.md) before upgrading. REA's `always-bump-minor` policy includes breaking changes; 6.2 is not a backward-compatibility promise. Preserve original saved files and regenerate missing observations rather than fabricating identities or facts.
|
||||
Read the [6.1 to 6.2 migration guide](docs/migrations/migration-6.2.md) before upgrading. REA's `always-bump-minor` policy includes breaking changes; 6.2 is not a backward-compatibility promise. Preserve original saved files and regenerate missing observations rather than fabricating identities or facts.
|
||||
|
||||
* **MCP / Evidence / snapshots / artifacts:** Success results are direct canonical Evidence; read `normalized_result` rather than the old `result`/`evidence` wrapper. Evidence requires nullable `analysis_profile`, session provider aliases are removed, snapshots require complete profile-bound query records, and artifact roles/permissions belong to occurrences. Recreate incompatible saved data; adding fields without recomputing their semantic identity is invalid. ([63bf914](https://github.com/morluto/rea/commit/63bf91405cf97b114a84f337fb1272d98a267999))
|
||||
* **Process captures:** Legacy v3 conversion is removed. Explicit executable identity and `event_journal` are required; retain old captures and recapture when current comparisons are needed instead of inventing launch identity or event order. ([2a77469](https://github.com/morluto/rea/commit/2a7746998d47446c4db6d4f524e0f183d6803f3f))
|
||||
|
||||
+14
-10
@@ -11,7 +11,7 @@ incorrect user instructions warrant standalone corrections. Collect other
|
||||
cosmetic-only suggestions in an issue rather than separate PRs.
|
||||
|
||||
For selected architectural owners and dependency paths, use the
|
||||
[architecture map](docs/architecture.mermaid). It is not a complete directory or
|
||||
[architecture map](docs/architecture/architecture.mermaid). It is not a complete directory or
|
||||
import inventory. For current provider wiring, start with
|
||||
[`src/composition/binary.ts`](src/composition/binary.ts) for deep candidates and
|
||||
the other `src/composition/` factories for tool services, including
|
||||
@@ -32,7 +32,7 @@ removing it. Preserve validation, lazy loading, caller policy, and resource
|
||||
acquisition and cleanup supplied by the old boundary. Published APIs, persisted
|
||||
formats, and independently versioned bridges require an explicit compatibility
|
||||
decision; an internal representation alone does not establish that obligation.
|
||||
See [interpreting boundary facts once](docs/tool-design.md#interpret-boundary-facts-once)
|
||||
See [interpreting boundary facts once](docs/development/tool-design.md#interpret-boundary-facts-once)
|
||||
for admission ownership and the distinction between repeated validation and
|
||||
independent checks.
|
||||
|
||||
@@ -44,7 +44,7 @@ Use the [analysis optimization skill](.agents/skills/rea-analysis-optimization/S
|
||||
to locate provider and shared-workflow bottlenecks, preserve Evidence, and
|
||||
compare equivalent real tasks before claiming an improvement.
|
||||
|
||||
When adding or changing an MCP tool, follow the [tool design guide](docs/tool-design.md) and preserve the canonical contracts and generated catalog.
|
||||
When adding or changing an MCP tool, follow the [tool design guide](docs/development/tool-design.md) and preserve the canonical contracts and generated catalog.
|
||||
When adding or changing an admission ceiling, budget, or deadline, follow
|
||||
[analysis settings, limits, and recovery](docs/design/limits-and-recovery.md)
|
||||
for ownership, operation snapshots, provider integration, and the steps for
|
||||
@@ -234,7 +234,7 @@ guarantee.
|
||||
Use the development toolchain pinned in `.nvmrc` and
|
||||
`package.json#packageManager`. Run `nvm use` before installing dependencies;
|
||||
installed-package runtime support is documented in
|
||||
[installation](docs/installation.md#start-setup).
|
||||
[installation](docs/getting-started/installation.md#start-setup).
|
||||
Use Node.js and npm for source builds and verifier scripts; the installed
|
||||
package's Bun runtime support does not extend to those development scripts.
|
||||
|
||||
@@ -289,16 +289,20 @@ base revision, or run the suite on Linux or WSL, before attributing them to a
|
||||
change. The embedded-artifact parent-swap tests exercise the selected-path
|
||||
replacement when the rename succeeds; if Windows refuses it while the admitted
|
||||
file is open, they instead verify the refusal and cleanup. See
|
||||
[testing](docs/testing.md#developer-commands) for command scopes
|
||||
[testing](docs/development/testing.md#developer-commands) for command scopes
|
||||
and lane selection.
|
||||
|
||||
`git submodule update --init --recursive` fails at the pinned Unblob submodule
|
||||
on Windows and can leave later submodules unchecked out. Apply the
|
||||
[Unblob checkout workaround](docs/firmware-analysis.md#windows-submodule-checkout),
|
||||
[Unblob checkout workaround](docs/guides/firmware/firmware-analysis.md#windows-submodule-checkout),
|
||||
then rerun the command.
|
||||
|
||||
## Documentation website
|
||||
|
||||
Use the [documentation directory](docs/README.md) and
|
||||
[authoring guide](docs/development/documentation.md) for document ownership,
|
||||
domain-based feature specifications and architectural decision records.
|
||||
|
||||
The VitePress site uses the Markdown files in `docs/`. Run `npm run docs:dev`
|
||||
for live editing, `npm run docs:build` to check the production build and
|
||||
links, and `npm run docs:preview` to preview that build at `/rea/`.
|
||||
@@ -352,7 +356,7 @@ npm run check:fast
|
||||
`test:local` runs source tests without building. `check:changed` combines cached
|
||||
static checks with source tests affected since the merge base with `origin/main`.
|
||||
Import-graph selection can miss runtime registration, bridges, and generated data;
|
||||
select relevant boundary tests explicitly. See [testing](docs/testing.md#developer-commands)
|
||||
select relevant boundary tests explicitly. See [testing](docs/development/testing.md#developer-commands)
|
||||
for commands, test placement, pruning, and real-provider prerequisites.
|
||||
|
||||
Before requesting review, run relevant tests and `npm run check`; add
|
||||
@@ -427,8 +431,8 @@ Run `npm run verify:hopper` on a supported macOS host or
|
||||
`npm run verify:hopper:linux` on the supported Linux demo runner. These build
|
||||
native fixtures and verify the installed engine through CLI/MCP; package or
|
||||
simulated-provider checks do not establish engine behavior. See
|
||||
[real-toolchain verification](docs/testing.md#end-to-end-integration-and-golden-evidence)
|
||||
for prerequisites and scope, and [Hopper setup](docs/installation.md#hopper)
|
||||
[real-toolchain verification](docs/development/testing.md#end-to-end-integration-and-golden-evidence)
|
||||
for prerequisites and scope, and [Hopper setup](docs/getting-started/installation.md#hopper)
|
||||
for supported hosts and unattended startup.
|
||||
|
||||
Use the default `build/conformance/manifest.json` unless explicitly verifying
|
||||
@@ -437,7 +441,7 @@ Generated fixtures and manifests remain ignored.
|
||||
|
||||
## Maintainer release checklist
|
||||
|
||||
Use the [release guide](docs/releasing.md). Main pushes automatically refresh a
|
||||
Use the [release guide](docs/development/releasing.md). Main pushes automatically refresh a
|
||||
Release Please PR with the next version and changelog. Review its migration
|
||||
notes, wait for the current CI checks to pass, and merge it into main to publish.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
**See a feature you like. Understand how it works, down to the binary level.**
|
||||
|
||||
[](https://www.npmjs.com/package/rea-agents)
|
||||
[](docs/mcp-contracts.md#generated-catalog)
|
||||
[](docs/reference/mcp-contracts.md#generated-catalog)
|
||||
[](#what-you-can-analyze)
|
||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||
[](LICENSE)
|
||||
@@ -72,7 +72,7 @@ Setup registers REA with your agent and installs matching workflow instructions.
|
||||
|
||||
On Linux, Ghidra, JADX, firmware tool launches and static JavaScript/Electron
|
||||
analysis require a procps-compatible `ps` on REA's `PATH` for process ownership
|
||||
checks. Recovery steps are in `docs/installation.md` under
|
||||
checks. Recovery steps are in `docs/getting-started/installation.md` under
|
||||
"Linux owned-process prerequisite".
|
||||
|
||||
### Set up your agent
|
||||
@@ -91,8 +91,8 @@ available. Run package acquisition from a trusted directory outside the target
|
||||
project. Installation and recovery details are in the setup guide below.
|
||||
|
||||
Setup supports Claude Code, Codex, Cursor, Gemini CLI, Grok Build and
|
||||
[other agents](docs/installation.md#supported-agents). See
|
||||
[installation and setup](docs/installation.md) for provider configuration and
|
||||
[other agents](docs/getting-started/installation.md#supported-agents). See
|
||||
[installation and setup](docs/getting-started/installation.md) for provider configuration and
|
||||
manual MCP registration and Claude Code/Codex plugin installation.
|
||||
|
||||
MCP uses compact input schemas by default to reduce context overhead. Set
|
||||
@@ -135,7 +135,7 @@ rea --help
|
||||
```
|
||||
|
||||
For native analysis, configure a provider first. See the
|
||||
[CLI and Evidence guide](docs/cli.md) for native commands, provider selection,
|
||||
[CLI and Evidence guide](docs/getting-started/cli.md) for native commands, provider selection,
|
||||
snapshots and scripting.
|
||||
|
||||
### Update REA
|
||||
@@ -191,45 +191,46 @@ CLI commands use the same workflows.
|
||||
REA requires Node.js 22.x (>=22.23.4), 24.x (>=24.22.1), or 26.12.1+, plus npm.
|
||||
Additional tools and host support depend on the target:
|
||||
|
||||
| Target | What REA returns | Requirements and guide |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Desktop installations | Runtime candidates, supporting files, component markers and next probes | Built-in bounded directory/header inspection; [desktop applications](docs/desktop-applications.md) |
|
||||
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra, IDA or Kuna; [native analysis](docs/native-investigation.md) |
|
||||
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
|
||||
| Go binaries | Embedded compiler version, modules, replacements and build settings | Built-in static ELF/PE/thin Mach-O inspection; no Go installation required |
|
||||
| GPU code objects | CUDA/HIP targets, selected kernel parameters and resources, retained PTX text | Built-in static ELF/PE/fatbin/CUBIN/PTX inspection; [GPU code objects](docs/gpu-code-objects.md) |
|
||||
| Model artifacts | GGUF / safetensors metadata, tensor declarations and derived totals | Built-in header inspection; optional full-file hash; [model files](docs/model-artifacts.md) |
|
||||
| IL2CPP metadata | Unity global-metadata.dat assembly images, type and method names and index ranges | Built-in static decoding of versions 24, 27, 29, 31 and 39; no Unity required |
|
||||
| Godot PCK | Archive inventory and extraction, original header/directory facts and selected content identities | Built-in static formats 2, 3 and 4; no Godot required |
|
||||
| Rust binaries | Embedded cargo-auditable crate names, versions, sources and dependency edges | Built-in static ELF/PE/thin Mach-O inspection; [Rust binaries](docs/rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](docs/pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](docs/pe-imports.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](docs/elf-notes.md) |
|
||||
| Binary hardening | PIE, NX, RELRO, CFG and related header flags for ELF, PE and Mach-O | Built-in static header inspection; [binary hardening](docs/binary-hardening.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and documented crash classes | Built-in static JSON inspection; [Apple IPS](docs/apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](docs/kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, imports, lambdas and the Code header | Built-in static BEAM inspection; [Erlang BEAM](docs/erlang-beam.md) |
|
||||
| WASM artifact | Validation, sections, exact import/export WAT forms and decoded WAT | Caller-supplied WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
|
||||
| SQLite databases | Tables, columns, indexes, views, triggers and selected ordinary-table rows | Local database/WAL snapshot; Node.js 24.x >=24.15 or 26+ with native SQLite limits |
|
||||
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
|
||||
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; Linux: procps-compatible `ps`; [application analysis](docs/javascript-application-workflows.md) |
|
||||
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](docs/browser-observation.md) |
|
||||
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR or Fiddler Everywhere SAZ; mitmdump on Linux for native mitmproxy; [capture guide](docs/web-network-captures.md) |
|
||||
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | None (static only); [managed-code guide](docs/managed-code-analysis.md) |
|
||||
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
|
||||
| APK signatures | v1/v2/v3/v3.1 signers, certificate fingerprints, key rotation and digest self-consistency | None (static only); `inspect_apk_signature` |
|
||||
| Android devices | Devices, packages, processes, logs, dumps, screen captures, and APK/file transfers | Caller-supplied adb (emulator or hardware); [ADB guide](docs/adb-device-analysis.md) |
|
||||
| JEB projects | Engine-backed project units, artifact digests and type/method pseudo-code | A caller-started JEB client serving MCP, selected with REA_JEB_MCP_URL; [JEB guide](docs/jeb-analysis.md) |
|
||||
| Android resources | Decoded manifest, string tables, locales and version facts | Caller-supplied Apktool launcher; [resource guide](docs/apktool-resource-analysis.md) |
|
||||
| Flutter apps | Dart snapshot hash, per-ABI library digests and engine build provenance | None (static APK parsing); [Flutter guide](docs/flutter-analysis.md) |
|
||||
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
|
||||
| Recorded packets | Selected fields, repeated values, filters and decode-as rules | Linux: TShark 4.x + prlimit; [capture guide](docs/packet-captures.md) |
|
||||
| Packet summaries | Endpoints, DNS, TLS SNI, protocol distribution and HTTP requests | Caller-supplied tshark and capinfos (Linux-verified); [pcap guide](docs/pcap-analysis.md) |
|
||||
| Recorded logic signals | Decoder annotations, sample ranges and diagnostics | Linux: sigrok-cli 0.7.2 + prlimit; [signal recordings](docs/signal-recordings.md) |
|
||||
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
|
||||
| Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
|
||||
| PyInstaller executables | CArchive members, Python version, entry scripts and extracted bytecode | None (static only); [Python packaged applications](docs/python-packaged-applications.md) |
|
||||
| Target | What REA returns | Requirements and guide |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Desktop installations | Runtime candidates, supporting files, component markers and next probes | Built-in bounded directory/header inspection; [desktop applications](docs/desktop-applications.md) |
|
||||
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra, IDA or Kuna; [native analysis](docs/guides/native/native-investigation.md) |
|
||||
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/guides/native/binary-diagnostics.md) |
|
||||
| Go binaries | Embedded compiler version, modules, replacements and build settings | Built-in static ELF/PE/thin Mach-O inspection; no Go installation required |
|
||||
| GPU code objects | CUDA/HIP targets, selected kernel parameters and resources, retained PTX text | Built-in static ELF/PE/fatbin/CUBIN/PTX inspection; [GPU code objects](docs/gpu-code-objects.md) |
|
||||
| Model artifacts | GGUF / safetensors metadata, tensor declarations and derived totals | Built-in header inspection; optional full-file hash; [model files](docs/model-artifacts.md) |
|
||||
| IL2CPP metadata | Unity global-metadata.dat assembly images, type and method names and index ranges | Built-in static decoding of versions 24, 27, 29, 31 and 39; no Unity required |
|
||||
| Godot PCK | Archive inventory and extraction, original header/directory facts and selected content identities | Built-in static formats 2, 3 and 4; no Godot required |
|
||||
| Rust binaries | Embedded cargo-auditable crate names, versions, sources and dependency edges | Built-in static ELF/PE/thin Mach-O inspection; [Rust binaries](docs/rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](docs/pe-certificates.md) |
|
||||
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](docs/pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](docs/guides/native/windows-shortcut.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](docs/elf-notes.md) |
|
||||
| Binary hardening | PIE, NX, RELRO, CFG and related header flags for ELF, PE and Mach-O | Built-in static header inspection; [binary hardening](docs/binary-hardening.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and documented crash classes | Built-in static JSON inspection; [Apple IPS](docs/apple-ips.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](docs/kernel-modules.md) |
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, imports, lambdas and the Code header | Built-in static BEAM inspection; [Erlang BEAM](docs/erlang-beam.md) |
|
||||
| WASM artifact | Validation, sections, exact import/export WAT forms and decoded WAT | Caller-supplied WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/guides/evm/evm-bytecode.md) |
|
||||
| SQLite databases | Tables, columns, indexes, views, triggers and selected ordinary-table rows | Local database/WAL snapshot; Node.js 24.x >=24.15 or 26+ with native SQLite limits |
|
||||
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/guides/native/recorded-crashes.md) |
|
||||
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; Linux: procps-compatible `ps`; [application analysis](docs/guides/javascript/javascript-application-workflows.md) |
|
||||
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](docs/guides/web/browser-observation.md) |
|
||||
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR or Fiddler Everywhere SAZ; mitmdump on Linux for native mitmproxy; [capture guide](docs/guides/web/web-network-captures.md) |
|
||||
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | None (static only); [managed-code guide](docs/guides/managed/managed-code-analysis.md) |
|
||||
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/guides/android/android-analysis.md) |
|
||||
| APK signatures | v1/v2/v3/v3.1 signers, certificate fingerprints, key rotation and digest self-consistency | None (static only); `inspect_apk_signature` |
|
||||
| Android devices | Devices, packages, processes, logs, dumps, screen captures, and APK/file transfers | Caller-supplied adb (emulator or hardware); [ADB guide](docs/guides/android/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/providers/jeb-analysis.md) |
|
||||
| Android resources | Decoded manifest, string tables, locales and version facts | Caller-supplied Apktool launcher; [resource guide](docs/guides/android/apktool-resource-analysis.md) |
|
||||
| Flutter apps | Dart snapshot hash, per-ABI library digests and engine build provenance | None (static APK parsing); [Flutter guide](docs/guides/android/flutter-analysis.md) |
|
||||
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/guides/firmware/firmware-analysis.md) |
|
||||
| Recorded packets | Selected fields, repeated values, filters and decode-as rules | Linux: TShark 4.x + prlimit; [capture guide](docs/guides/data/packet-captures.md) |
|
||||
| Packet summaries | Endpoints, DNS, TLS SNI, protocol distribution and HTTP requests | Caller-supplied tshark and capinfos (Linux-verified); [pcap guide](docs/guides/data/pcap-analysis.md) |
|
||||
| Recorded logic signals | Decoder annotations, sample ranges and diagnostics | Linux: sigrok-cli 0.7.2 + prlimit; [signal recordings](docs/guides/signals/signal-recordings.md) |
|
||||
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/guides/javascript/javascript-artifact-reconstruction.md), [Apple applications](docs/guides/apple/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/guides/runtime/process-capture.md) |
|
||||
| PyInstaller executables | CArchive members, Python version, entry scripts and extracted bytecode | None (static only); [Python packaged applications](docs/python-packaged-applications.md) |
|
||||
|
||||
Static JavaScript and .NET inspection read the supplied files without running
|
||||
the application. Runtime capture runs or interacts with the selected target
|
||||
@@ -243,15 +244,15 @@ or update either provider.
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Native formats and host support vary by provider. See
|
||||
[Hopper and Ghidra setup](docs/installation.md#hopper), the
|
||||
[IDA guide](docs/ida-provider.md) (including an optional native MCP bridge), the
|
||||
[Hopper and Ghidra setup](docs/getting-started/installation.md#hopper), the
|
||||
[IDA guide](docs/providers/ida-provider.md) (including an optional native MCP bridge), the
|
||||
[Kuna decompiler guide](docs/kuna-provider.md), and
|
||||
[experimental Windows Ghidra support](docs/windows-ghidra-p0.md).
|
||||
Ghidra also supports [16-bit DOS analysis](docs/ghidra-dos.md).
|
||||
[experimental Windows Ghidra support](docs/providers/windows-ghidra-p0.md).
|
||||
Ghidra also supports [16-bit DOS analysis](docs/providers/ghidra-dos.md).
|
||||
For large binaries, raise the provider's startup deadline with
|
||||
`REA_GHIDRA_STARTUP_TIMEOUT_MS` or `REA_HOPPER_STARTUP_TIMEOUT_MS`.
|
||||
For provider selection, see the [CLI guide](docs/cli.md#choose-a-provider).
|
||||
Check [release availability](docs/installation.md#released-package-and-main)
|
||||
For provider selection, see the [CLI guide](docs/getting-started/cli.md#choose-a-provider).
|
||||
Check [release availability](docs/getting-started/installation.md#released-package-and-main)
|
||||
for features added since the latest npm release.
|
||||
|
||||
## Showcases
|
||||
@@ -341,8 +342,8 @@ REA exports a runnable environment with a basic test to check that it starts and
|
||||
<summary><strong>Which agents can use REA?</strong></summary>
|
||||
|
||||
Any agent that supports local MCP servers. Setup configures the
|
||||
[supported agents](docs/installation.md#supported-agents); other clients can use
|
||||
[manual MCP registration](docs/installation.md#mcp-registry).
|
||||
[supported agents](docs/getting-started/installation.md#supported-agents); other clients can use
|
||||
[manual MCP registration](docs/getting-started/installation.md#mcp-registry).
|
||||
|
||||
</details>
|
||||
|
||||
@@ -352,7 +353,7 @@ Any agent that supports local MCP servers. Setup configures the
|
||||
Deep native analysis uses Hopper, Ghidra, IDA or Kuna, depending on the target
|
||||
and operation. Static JavaScript and .NET inspection work without a native
|
||||
analysis engine. Setup can install Hopper after approval; Ghidra, IDA and Kuna
|
||||
use your existing installations. See [provider setup](docs/installation.md#hopper)
|
||||
use your existing installations. See [provider setup](docs/getting-started/installation.md#hopper)
|
||||
for the options and their supported targets.
|
||||
|
||||
</details>
|
||||
@@ -364,7 +365,7 @@ REA starts Hopper when an operation needs it. On macOS, a first-run dialog may
|
||||
ask you to choose demo mode or activate your license. Complete that prompt in the
|
||||
same user session before your first CLI/MCP operation or unattended job. Open
|
||||
Hopper manually if needed. See
|
||||
[Hopper startup and troubleshooting](docs/installation.md#launcher-paths-and-troubleshooting).
|
||||
[Hopper startup and troubleshooting](docs/getting-started/installation.md#launcher-paths-and-troubleshooting).
|
||||
|
||||
</details>
|
||||
|
||||
@@ -373,7 +374,7 @@ Hopper manually if needed. See
|
||||
|
||||
The skill supplies investigation instructions for your agent. Use `npx rea-agents setup`
|
||||
to register REA's MCP server and install the matching instructions, then restart
|
||||
your agent. See [skill-only installation](docs/installation.md#skill-only-installation).
|
||||
your agent. See [skill-only installation](docs/getting-started/installation.md#skill-only-installation).
|
||||
|
||||
</details>
|
||||
|
||||
@@ -422,12 +423,12 @@ with your REA version, target type, steps to reproduce and error output.
|
||||
Start with the website's [worked guides](https://rea.tools/guides/).
|
||||
For exact options, prerequisites and result contracts:
|
||||
|
||||
- [Installation and setup](docs/installation.md): agent registration, provider configuration, updates and uninstall.
|
||||
- [Readiness and troubleshooting](docs/installation.md#check-readiness-for-your-task): diagnose one agent or analysis engine.
|
||||
- [CLI and Evidence](docs/cli.md): commands, provider selection, snapshots, import/export and exit statuses.
|
||||
- [MCP contracts](docs/mcp-contracts.md) and [agent prompts](docs/mcp-prompts.md): tool results, sessions and guided investigations.
|
||||
- [Tool catalog](docs/mcp-contracts.md#generated-catalog): generated inventory of tools, providers and CLI commands.
|
||||
- [Roadmap](docs/roadmap.md): planned work and capability trackers.
|
||||
- [Installation and setup](docs/getting-started/installation.md): agent registration, provider configuration, updates and uninstall.
|
||||
- [Readiness and troubleshooting](docs/getting-started/installation.md#check-readiness-for-your-task): diagnose one agent or analysis engine.
|
||||
- [CLI and Evidence](docs/getting-started/cli.md): commands, provider selection, snapshots, import/export and exit statuses.
|
||||
- [MCP contracts](docs/reference/mcp-contracts.md) and [agent prompts](docs/getting-started/mcp-prompts.md): tool results, sessions and guided investigations.
|
||||
- [Tool catalog](docs/reference/mcp-contracts.md#generated-catalog): generated inventory of tools, providers and CLI commands.
|
||||
- [Roadmap](docs/development/roadmap.md): planned work and capability trackers.
|
||||
|
||||
Report vulnerabilities through [SECURITY.md](SECURITY.md).
|
||||
|
||||
@@ -462,8 +463,8 @@ report a bug or suggest a feature, or [send a pull request](https://github.com/m
|
||||
to improve the code or docs.
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
|
||||
[testing](docs/testing.md) for verification lanes, and the
|
||||
[architecture map](docs/architecture.mermaid) for selected layers and dependency paths.
|
||||
[testing](docs/development/testing.md) for verification lanes, and the
|
||||
[architecture map](docs/architecture/architecture.mermaid) for selected layers and dependency paths.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+111
-27
@@ -4,6 +4,117 @@
|
||||
|
||||
Security fixes are provided for the latest published version of REA. Upgrade to the latest release before reporting a problem that may already have been resolved.
|
||||
|
||||
## Security boundary
|
||||
|
||||
REA is a local reverse-engineering and automation tool. CLI and MCP use the
|
||||
same application workflows and run with the host process's permissions.
|
||||
REA is not a general-purpose sandbox or a multi-tenant authorization service.
|
||||
|
||||
### Threat model
|
||||
|
||||
- **Trusted authority:** the operating-system account running REA, the caller
|
||||
or agent host that selects operations, and configured analysis providers,
|
||||
their executables and extensions, and service endpoints. An MCP client can
|
||||
invoke the operations exposed to it; its host must enforce the user's tool
|
||||
permissions and approvals.
|
||||
- **Untrusted data:** target binaries, archives, source files, project contents,
|
||||
captures, web pages and returned target content can be malicious. Selecting
|
||||
an input for static inspection does not authorize commands embedded in that
|
||||
input. Agents must treat target text and Evidence as data rather
|
||||
than instructions granting additional authority.
|
||||
- **Operation-specific effects:** static inspection parses target data and may
|
||||
launch an analysis engine. Runtime, debugger, instrumentation, browser,
|
||||
desktop and environment workflows can deliberately execute code, attach to
|
||||
processes, make network requests, write files or interact with applications
|
||||
and devices. Review the selected operation's effects and limitations; static
|
||||
inspection does not authorize launching or interacting with the target
|
||||
application. See
|
||||
[runtime and network responsibilities](DISCLAIMER.md#runtime-network-and-device-operations).
|
||||
|
||||
Standard client registrations use a dedicated stdio process. Opt-in
|
||||
[HTTP MCP](docs/reference/mcp-contracts.md#transports) uses plain HTTP without
|
||||
TLS or client authentication and shares provider/active-target state across
|
||||
protocol sessions. Its session ID is not a user-authentication or isolation
|
||||
boundary. Keep this endpoint within a trusted local or isolated environment.
|
||||
|
||||
### Intended security properties
|
||||
|
||||
Static JavaScript and .NET inspection do not run the target application.
|
||||
Unexpected execution of input code through a data-only analysis path is a
|
||||
security concern. Analysis engines themselves are executable software trusted
|
||||
with the host account's permissions; parsing an input in an external engine
|
||||
does not isolate that engine from the host.
|
||||
|
||||
REA authenticates its managed Hopper and Ghidra bridges with per-session random
|
||||
capability tokens transferred through private session files, rather than
|
||||
process arguments or environment variables. POSIX uses current-user Unix
|
||||
sockets. Windows Ghidra uses authenticated loopback TCP and a private NTFS
|
||||
runtime whose DACL admits only the current user and SYSTEM. These controls
|
||||
protect the managed session boundary, not every external provider or debugger
|
||||
endpoint. See [Windows Ghidra transport and lifecycle](docs/providers/windows-ghidra-p0.md#private-runtime-transport-and-lifecycle).
|
||||
|
||||
Provider ownership and mutation rules remain specific to each workflow:
|
||||
|
||||
- Ghidra's working projects are temporary and owned by REA. Opt-in
|
||||
[checkpoints](docs/getting-started/installation.md#automatically-checkpoint-an-owned-ghidra-program)
|
||||
retain REA-owned Program state. A
|
||||
[caller-selected existing project](docs/getting-started/installation.md#reuse-an-existing-ghidra-project)
|
||||
is fingerprinted and copied into an owned runtime for read-only processing;
|
||||
Ghidra does not open or save the original database through that workflow.
|
||||
- [IDA analysis](docs/providers/ida-provider.md) is read-only. An attached GUI
|
||||
database is never saved or closed by REA; owned headless sessions have a
|
||||
separate lifecycle.
|
||||
- Cleanup must stay within resources REA owns. Failed or unverified cleanup
|
||||
can retain a workspace or session for retry; closing a session
|
||||
does not imply that every investigation artifact has been erased.
|
||||
|
||||
`rea setup` shows planned configuration and installation changes and requires
|
||||
approval before applying them. Ghidra, Java and IDA are user-managed. Approved
|
||||
Linux Hopper installation authenticates the package's detached PGP signature
|
||||
against the pinned publisher identity and checks the signed launcher against
|
||||
the selected release's digest. The release feed's display version is separate
|
||||
from that authenticated identity. See [installation and publisher verification](docs/getting-started/installation.md#hopper).
|
||||
|
||||
### Limits and caller responsibilities
|
||||
|
||||
- **Host isolation:** private runtimes and capability tokens do not protect
|
||||
against malicious software already running as the same operating-system
|
||||
user, or a compromised trusted client or provider. Use an appropriately
|
||||
isolated account, VM or restricted environment when handling hostile targets.
|
||||
- **Resource bounds:** timeouts, cancellation, streaming and size limits are
|
||||
operation-specific. They are not a universal CPU, memory, disk or wall-time
|
||||
limit on every target and third-party tool. Enforce hard host resource limits
|
||||
externally when needed. Failures of a documented boundary or cancellation
|
||||
control still warrant investigation.
|
||||
- **Data and network exposure:** Evidence, caches, checkpoints, exports and
|
||||
captures can retain private target data, paths, URLs and memory contents.
|
||||
Local execution does not make these outputs safe to publish. Requested
|
||||
network operations, agent hosts and provider features such as
|
||||
[IDA Free's cloud decompiler](docs/providers/ida-provider.md) can communicate
|
||||
outside the host. Review their data handling and secure any exposed endpoint.
|
||||
- **Interpretation:** analysis, reconstruction and generated environments can
|
||||
be incomplete or incorrect. Identity checks, signatures and successful
|
||||
analysis do not establish that a target, provider or generated program is
|
||||
safe to execute. Review the Evidence and proposed actions before relying on
|
||||
them.
|
||||
|
||||
### Vulnerability scope
|
||||
|
||||
Please report suspected violations of these boundaries privately. Examples
|
||||
include unintended code execution during data-only inspection, escaping a
|
||||
documented extraction/output boundary, bypassing bridge authentication or
|
||||
target/session identity checks, unauthorized effects on an unrelated resource,
|
||||
and disclosure of transport credentials or explicitly marked sensitive values.
|
||||
An attacker-triggered bypass of a documented resource or cancellation control
|
||||
can also be security-relevant without code execution.
|
||||
|
||||
Incorrect analysis, unsupported formats, crashes, hangs and high resource use
|
||||
without a security-boundary impact are generally ordinary bug reports. Effects
|
||||
explicitly requested through an execution or interaction workflow are not by
|
||||
themselves a vulnerability. A dependency advisory needs its actual REA exposure
|
||||
assessed; a complete exploit or diagnosis is not required to report a concern.
|
||||
If you are unsure whether a boundary is affected, use the private channel below.
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
Do not disclose vulnerabilities, proof-of-concept exploits, credentials,
|
||||
@@ -21,30 +132,3 @@ unrelated local paths from logs or examples.
|
||||
The maintainer will acknowledge the report, assess its scope, and coordinate
|
||||
remediation and disclosure timing with the reporter. Please allow time for
|
||||
provider-dependent behavior to be reproduced safely.
|
||||
|
||||
## Security boundary
|
||||
|
||||
REA authenticates its Hopper and Ghidra bridges with per-session random
|
||||
capability tokens. POSIX uses current-user Unix sockets; Windows Ghidra uses
|
||||
authenticated loopback TCP with a private NTFS runtime whose DACL admits only
|
||||
the current user and SYSTEM. See [Windows Ghidra P0](docs/windows-ghidra-p0.md#private-runtime-transport-and-lifecycle).
|
||||
Tokens are transferred through private session descriptors rather than process
|
||||
arguments or environment variables.
|
||||
This is not a sandbox and does not protect against malicious processes already
|
||||
running as the same operating-system user. Opening an untrusted binary
|
||||
delegates parsing and analysis to the selected local provider with that user's
|
||||
permissions.
|
||||
|
||||
Ghidra sessions use a packaged Java `HeadlessScript`, an isolated temporary
|
||||
project, and private home, cache, and runtime directories. REA imports only the
|
||||
requested target, bounds startup and protocol messages, requests bounded CPU
|
||||
and heap settings, and deletes the temporary project when the session closes.
|
||||
These controls limit accidental persistence and resource use; they do not make
|
||||
Ghidra a sandbox. REA does not open or modify user-owned Ghidra projects.
|
||||
|
||||
`GHIDRA_INSTALL_DIR` and optional `JAVA_HOME` identify user-managed
|
||||
installations. Setup can add those values to detected client configuration only
|
||||
after showing its plan and receiving approval. REA does not download, install,
|
||||
upgrade, or modify Ghidra or Java.
|
||||
|
||||
On Linux, REA accepts release metadata only from Hopper's HTTPS endpoint, restricts package URLs to Hopper's public download origin, bounds the package size, and compares the downloaded bytes with Hopper's published checksum before requesting installation. The published SHA-1 value is a corruption check, not a modern package signature; HTTPS origin validation remains part of the trust boundary. Dependency installation is delegated without shell evaluation to `apt-get`, `dnf`, or `pacman`, directly as root or through `pkexec`. REA never invokes `sudo`.
|
||||
+21
-21
@@ -54,27 +54,27 @@ 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; see [supported versions](docs/installation.md#ghidra). Copies of the 12.1.4 [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. |
|
||||
| Kuna | [Apache-2.0](https://github.com/Noelo-Lab/kuna/blob/v1.990/LICENSE), with its [NOTICE](https://github.com/Noelo-Lab/kuna/blob/v1.990/NOTICE) | Bring your own `kuna`; REA verified 1.990 and never downloads, installs or bundles it. REA invokes it as a separate process. |
|
||||
| Apktool | [Apache-2.0](https://github.com/iBotPeaches/Apktool/blob/master/LICENSE.md) | User-supplied Android resource decoder. |
|
||||
| Binwalk | [MIT](https://github.com/ReFirmLabs/binwalk/blob/4fdab3d464d97b68e0af9088df3f9e2e1545b21c/LICENSE) | v3.1.0; pinned submodule and user-supplied firmware engine. |
|
||||
| Unblob | [MIT](https://github.com/onekey-sec/unblob/blob/1fcc7a0a584a70a96c31f5a276c20944d199a089/LICENSE) | 26.6.4; pinned submodule and user-supplied firmware engine. |
|
||||
| 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. |
|
||||
| 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; see [supported versions](docs/getting-started/installation.md#ghidra). Copies of the 12.1.4 [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. |
|
||||
| Kuna | [Apache-2.0](https://github.com/Noelo-Lab/kuna/blob/v1.990/LICENSE), with its [NOTICE](https://github.com/Noelo-Lab/kuna/blob/v1.990/NOTICE) | Bring your own `kuna`; REA verified 1.990 and never downloads, installs or bundles it. REA invokes it as a separate process. |
|
||||
| Apktool | [Apache-2.0](https://github.com/iBotPeaches/Apktool/blob/master/LICENSE.md) | User-supplied Android resource decoder. |
|
||||
| Binwalk | [MIT](https://github.com/ReFirmLabs/binwalk/blob/4fdab3d464d97b68e0af9088df3f9e2e1545b21c/LICENSE) | v3.1.0; pinned submodule and user-supplied firmware engine. |
|
||||
| Unblob | [MIT](https://github.com/onekey-sec/unblob/blob/1fcc7a0a584a70a96c31f5a276c20944d199a089/LICENSE) | 26.6.4; pinned submodule and user-supplied firmware engine. |
|
||||
| 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
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
"""Run REA inside an agentenv build computer for REA on the host: capture the app, draft its task and export it.
|
||||
|
||||
REA sends this file's source through the computer's ``computer-exec/v1`` route as
|
||||
``python3 -I -c <source> <command> <JSON arguments>``; each command prints one JSON line and exits. ``start``
|
||||
``python3 -I -c <source> <command> <JSON arguments>``. JSON that would exceed the bytes Linux
|
||||
passes as one string travels as several arguments, which this file joins before parsing. Each command prints
|
||||
one JSON line and exits. ``start``
|
||||
leaves the capture running on its own: its stdin is a FIFO it holds open for reading and writing, so it never
|
||||
sees the end of its input, and ``mark`` and ``stop`` write their requests there and wait for the capture's own
|
||||
acknowledgement on its progress log. A small shell around the capture writes its exit status to a file, the
|
||||
@@ -91,6 +93,13 @@ def _exit_code(capture: str):
|
||||
return None
|
||||
|
||||
|
||||
def _ended(capture: str, code: int) -> dict:
|
||||
"""A capture that has exited: its status, the end of its progress log and its output's size, which REA reads
|
||||
whole for the Evidence or failure it ended with, whichever step was waiting on it."""
|
||||
return {"exited": code, "progress": _tail(os.path.join(capture, "progress.log")),
|
||||
"output_bytes": os.path.getsize(os.path.join(capture, "capture.out"))}
|
||||
|
||||
|
||||
def _event_line(path: str, offset: int, kinds: set, name):
|
||||
"""The first progress line after ``offset`` whose event is of one of ``kinds``, for ``name`` when given."""
|
||||
try:
|
||||
@@ -119,17 +128,49 @@ def _wait(capture: str, offset: int, kinds: set, name, timeout: float) -> dict:
|
||||
return {"line": line}
|
||||
code = _exit_code(capture)
|
||||
if code is not None:
|
||||
return {"exited": code, "progress": _tail(log), "output": _tail(os.path.join(capture, "capture.out"))}
|
||||
return _ended(capture, code)
|
||||
if time.monotonic() > deadline:
|
||||
return {"timed_out": True, "progress": _tail(log)}
|
||||
time.sleep(POLL_S)
|
||||
|
||||
|
||||
def _within(path: str, folder: str) -> bool:
|
||||
return path == folder or path.startswith(folder + os.sep)
|
||||
|
||||
|
||||
def _state_paths(values: list, work: str):
|
||||
"""Each state path as an absolute path strictly under the home and outside REA's work folder, both as named
|
||||
and with its links resolved, or the refusal of the first that is not. The capture resolves the links again
|
||||
and retains what they lead to, so a link out of the home is refused here. Each passes on as named, so the
|
||||
capture keeps what its spelling means, such as a hidden settings folder."""
|
||||
home = os.path.normpath(os.path.expanduser("~"))
|
||||
real_home, real_work = os.path.realpath(home), os.path.realpath(work)
|
||||
spellings = {home, real_home}
|
||||
paths = []
|
||||
for value in values:
|
||||
relative = value[2:] if value.startswith("~/") else value
|
||||
path = os.path.normpath(os.path.join(home, relative))
|
||||
if ".." in relative.split("/") or not any(path.startswith(spelling + os.sep) for spelling in spellings):
|
||||
return None, f"The state path {value} is not under the computer's home, {home}."
|
||||
# Every link on the way is followed, a dangling one too; a path that does not exist yet resolves
|
||||
# through its nearest existing folder.
|
||||
resolved = os.path.realpath(path)
|
||||
if not resolved.startswith(real_home + os.sep):
|
||||
return None, f"The state path {value} leads through a link to {resolved}, which is not under the computer's home, {home}."
|
||||
if _within(path, work) or _within(resolved, real_work):
|
||||
return None, f"The state path {value} is in REA's work folder {work}, which every capture leaves out."
|
||||
paths.append(path)
|
||||
return paths, None
|
||||
|
||||
|
||||
def start(arguments: dict) -> int:
|
||||
work, capture = os.path.abspath(arguments["work"]), os.path.abspath(arguments["capture"])
|
||||
rea = shutil.which("rea")
|
||||
if rea is None:
|
||||
return _say({"error": "REA is not installed in this computer; start the computer from a request, which installs it."})
|
||||
state_paths, refusal = _state_paths(arguments.get("state_paths", []), work)
|
||||
if refusal is not None:
|
||||
return _say({"refused": refusal})
|
||||
if os.path.exists(capture):
|
||||
return _say({"error": f"the capture folder {capture} is already used"})
|
||||
apt = _apt(work, arguments.get("apt_timeout_s", 600))
|
||||
@@ -143,6 +184,8 @@ def start(arguments: dict) -> int:
|
||||
"--output", os.path.join(capture, "capture"), "--exclude", work, "--json"]
|
||||
for value in arguments.get("arguments", []):
|
||||
argv += ["--argument", value]
|
||||
for path in state_paths:
|
||||
argv += ["--state-path", path]
|
||||
if arguments.get("package_file"):
|
||||
argv += ["--package-file", arguments["package_file"]]
|
||||
# Reading and writing, so the capture never reads the end of its input between requests.
|
||||
@@ -175,11 +218,13 @@ def _request(capture: str, line: str) -> bool:
|
||||
|
||||
|
||||
def mark(arguments: dict) -> int:
|
||||
"""Request a checkpoint and answer with the capture's acknowledgement line as it wrote it: the checkpoint's
|
||||
counts and up to ten of the files that changed, home-relative, with a count of the rest."""
|
||||
capture, name = os.path.abspath(arguments["capture"]), arguments["name"]
|
||||
code = _exit_code(capture)
|
||||
log = os.path.join(capture, "progress.log")
|
||||
if code is not None:
|
||||
return _say({"exited": code, "progress": _tail(log)})
|
||||
return _say(_ended(capture, code))
|
||||
# A checkpoint already taken, whose answer was lost, is answered from the capture's own log.
|
||||
taken = _event_line(log, 0, {"checkpoint"}, name)
|
||||
if taken is not None:
|
||||
@@ -213,6 +258,7 @@ def run(arguments: dict) -> int:
|
||||
rea = shutil.which("rea")
|
||||
if rea is None:
|
||||
return _say({"error": "REA is not installed in this computer"})
|
||||
os.makedirs(os.path.dirname(arguments["stdout"]), exist_ok=True)
|
||||
for path, text in arguments.get("files", {}).items():
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "w", encoding="utf-8") as handle:
|
||||
@@ -236,8 +282,18 @@ def listing(arguments: dict) -> int:
|
||||
"""
|
||||
home = os.path.expanduser("~")
|
||||
files, skipped = [], []
|
||||
for directory, folders, names in os.walk(os.path.abspath(arguments["root"])):
|
||||
|
||||
def fail_walk(error: OSError) -> None:
|
||||
raise error
|
||||
|
||||
for directory, folders, names in os.walk(os.path.abspath(arguments["root"]), onerror=fail_walk):
|
||||
folders.sort()
|
||||
# os.walk does not follow directory symlinks; disclose them to the consumer.
|
||||
for name in folders[:]:
|
||||
path = os.path.join(directory, name)
|
||||
if os.path.islink(path):
|
||||
skipped.append(os.path.relpath(path, home))
|
||||
folders.remove(name)
|
||||
for name in sorted(names):
|
||||
path = os.path.join(directory, name)
|
||||
relative = os.path.relpath(path, home)
|
||||
@@ -259,4 +315,4 @@ def listing(arguments: dict) -> int:
|
||||
COMMANDS = {"start": start, "mark": mark, "stop": stop, "run": run, "list": listing}
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(COMMANDS[sys.argv[1]](json.loads(sys.argv[2])))
|
||||
sys.exit(COMMANDS[sys.argv[1]](json.loads("".join(sys.argv[2:]))))
|
||||
@@ -0,0 +1,64 @@
|
||||
"""Exercise the capture controller's filesystem inventory boundary."""
|
||||
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
|
||||
CONTROLLER = Path(__file__).with_name("capture.py")
|
||||
|
||||
|
||||
class CaptureListingTest(unittest.TestCase):
|
||||
def run_listing(self, root, output):
|
||||
return subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(CONTROLLER),
|
||||
"list",
|
||||
json.dumps({"root": str(root), "output": str(output)}),
|
||||
],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=False,
|
||||
)
|
||||
|
||||
def test_directory_symlink_is_disclosed_without_following_it(self):
|
||||
with tempfile.TemporaryDirectory() as parent:
|
||||
parent = Path(parent)
|
||||
root = parent / "root"
|
||||
target = parent / "target"
|
||||
output = parent / "listing.json"
|
||||
root.mkdir()
|
||||
target.mkdir()
|
||||
(root / "present.txt").write_text("present")
|
||||
(target / "outside.txt").write_text("outside")
|
||||
try:
|
||||
(root / "linked").symlink_to(target, target_is_directory=True)
|
||||
except OSError as error:
|
||||
self.skipTest(f"directory symlinks unavailable: {error}")
|
||||
result = self.run_listing(root, output)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
listing = json.loads(output.read_text())
|
||||
self.assertEqual(
|
||||
[item["path"] for item in listing["files"]],
|
||||
[os.path.relpath(root / "present.txt", Path.home())],
|
||||
)
|
||||
self.assertEqual(
|
||||
listing["skipped"], [os.path.relpath(root / "linked", Path.home())]
|
||||
)
|
||||
|
||||
def test_missing_root_does_not_produce_an_empty_successful_inventory(self):
|
||||
with tempfile.TemporaryDirectory() as parent:
|
||||
parent = Path(parent)
|
||||
output = parent / "listing.json"
|
||||
result = self.run_listing(parent / "missing", output)
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertFalse(output.exists())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -179,6 +179,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
private List<FunctionEntry> procedureInventory;
|
||||
private List<InventoryItem> stringInventory;
|
||||
private DecompInterface decompiler;
|
||||
private boolean existingProject;
|
||||
// A refused Program may only report its admission failure to the client.
|
||||
private String identityAdmissionFailure;
|
||||
/** Per-function native decompiler limit from the session; 0 leaves it unbounded. */
|
||||
@@ -199,6 +200,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
Path descriptorPath = Path.of(arguments[0]);
|
||||
checkpointDirectory = descriptorPath.toAbsolutePath().normalize().getParent();
|
||||
SessionDescriptor descriptor = readDescriptor(descriptorPath);
|
||||
existingProject = descriptor.existingProject;
|
||||
decompileTimeoutSeconds = descriptor.decompileTimeoutSeconds();
|
||||
// Windows retains a native immutable bearer descriptor lease until
|
||||
// runtime_close; POSIX removes it after this read. Normal cleanup removes
|
||||
@@ -876,6 +878,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
JsonArray blocks = new JsonArray();
|
||||
JsonArray skipped = new JsonArray();
|
||||
JsonArray notLoaded = new JsonArray();
|
||||
JsonArray overlays = new JsonArray();
|
||||
List<ByteSearchBlock> eligible = new ArrayList<>();
|
||||
for (MemoryBlock block : ordered) {
|
||||
monitor.checkCancelled();
|
||||
@@ -883,10 +886,16 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
Address high = block.getEnd();
|
||||
Address bound = start == null ? end : start;
|
||||
if (bound != null && !bound.getAddressSpace().equals(low.getAddressSpace())) continue;
|
||||
if (bound == null && (!block.isLoaded() || block.isOverlay())) {
|
||||
// Without bounds, search loaded non-overlay memory. Unloaded file
|
||||
// parts and loaded overlays stay reachable through explicit bounds.
|
||||
if (bound == null && !block.isLoaded()) {
|
||||
notLoaded.add(byteSearchCoverage(block, low, high));
|
||||
continue;
|
||||
}
|
||||
if (bound == null && block.isOverlay()) {
|
||||
overlays.add(byteSearchCoverage(block, low, high));
|
||||
continue;
|
||||
}
|
||||
if (start != null && low.compareTo(start) < 0) low = start;
|
||||
if (end != null && high.compareTo(end) > 0) high = end;
|
||||
if (low.compareTo(high) > 0) continue;
|
||||
@@ -960,6 +969,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
searched.addProperty("bytes", covered);
|
||||
searched.add("skipped_uninitialized", skipped);
|
||||
searched.add("skipped_not_loaded", notLoaded);
|
||||
searched.add("skipped_overlays", overlays);
|
||||
JsonObject result = new JsonObject();
|
||||
result.add("matches", matches);
|
||||
result.add("searched", searched);
|
||||
@@ -1414,8 +1424,29 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
flow.addProperty("conditional", false);
|
||||
flow.addProperty("computed", false);
|
||||
if (instruction == null) {
|
||||
result.addProperty("status", !currentProgram.getMemory().contains(address) ? "outside-memory" : currentProgram.getListing().getInstructionContaining(address) != null
|
||||
? "not-instruction-boundary" : currentProgram.getListing().getDefinedDataContaining(address) != null ? "data" : "not-in-listing");
|
||||
Instruction containing = currentProgram.getListing().getInstructionContaining(address);
|
||||
boolean inMemory = currentProgram.getMemory().contains(address);
|
||||
Data containingData = inMemory && containing == null
|
||||
? currentProgram.getListing().getDefinedDataContaining(address) : null;
|
||||
result.addProperty("status", !inMemory ? "outside-memory" : containing != null
|
||||
? "not-instruction-boundary" : containingData != null ? "data" : "not-in-listing");
|
||||
if (inMemory && containing == null && containingData != null) {
|
||||
JsonObject parentData = new JsonObject();
|
||||
parentData.addProperty("address", canonicalAddress(containingData.getAddress()));
|
||||
parentData.addProperty("length", containingData.getLength());
|
||||
parentData.addProperty("type_id", containingData.getDataType().getPathName());
|
||||
parentData.addProperty("provenance", "ghidra-listing");
|
||||
result.add("containing_data", parentData);
|
||||
}
|
||||
if (containing != null && currentProgram.getMemory().contains(address)) {
|
||||
JsonObject containingInstruction = new JsonObject();
|
||||
containingInstruction.addProperty("address", canonicalAddress(containing.getAddress()));
|
||||
containingInstruction.addProperty("length", containing.getLength());
|
||||
containingInstruction.addProperty("mnemonic", containing.getMnemonicString());
|
||||
containingInstruction.addProperty("raw_disassembly", containing.toString());
|
||||
containingInstruction.addProperty("provenance", "ghidra-listing");
|
||||
result.add("containing_instruction", containingInstruction);
|
||||
}
|
||||
for (String key : List.of("bytes", "length", "mnemonic", "raw_disassembly")) result.add(key, JsonNull.INSTANCE);
|
||||
} else {
|
||||
result.addProperty("status", "decoded");
|
||||
@@ -1930,6 +1961,9 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
limitations.add(
|
||||
"Def-use links do not cross function boundaries and may omit memory aliasing, call side effects, or unresolved indirect flow."
|
||||
);
|
||||
limitations.add(
|
||||
"Memory read/write effects cover high-p-code LOAD and STORE operations only; direct memory address varnodes in other operations are not included. An empty effect list does not establish that no memory is accessed. Recorded instruction references may provide complementary evidence."
|
||||
);
|
||||
limitations.add(
|
||||
"Memory read/write effects include stack and temporary memory operations; they do not identify persistent state or business meaning."
|
||||
);
|
||||
@@ -2376,7 +2410,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
if (!match.matched()) {
|
||||
continue;
|
||||
}
|
||||
JsonObject item = resultItem(entry.item, null);
|
||||
JsonObject item = resultItem(entry.item, "procedure");
|
||||
if (!match.aliases().isEmpty()) {
|
||||
JsonArray aliases = new JsonArray();
|
||||
for (String alias : match.aliases()) aliases.add(alias);
|
||||
@@ -2391,7 +2425,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
if (!matcher.matches(item.value)) {
|
||||
continue;
|
||||
}
|
||||
items.add(resultItem(item, null));
|
||||
items.add(resultItem(item, procedureSearch ? "procedure" : "string"));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
@@ -3716,9 +3750,23 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static JsonObject callRelationshipCoverage(
|
||||
private JsonObject callRelationshipCoverage(
|
||||
CallBoundaryObservation calls, Integer missingCallers) {
|
||||
JsonObject coverage = completeResolvedCallCoverage();
|
||||
JsonObject discovery = new JsonObject();
|
||||
if (missingCallers != null) {
|
||||
JsonObject callers = new JsonObject();
|
||||
callers.addProperty("status", "unknown");
|
||||
callers.addProperty("reason", "Recorded incoming references do not establish additional computed callers elsewhere in the program.");
|
||||
discovery.add("callers", callers);
|
||||
}
|
||||
if (calls != null && !calls.computedCallSites().isEmpty()) {
|
||||
JsonObject callees = new JsonObject();
|
||||
callees.addProperty("status", "unknown");
|
||||
callees.addProperty("reason", computedCallTargetLimitation(calls.computedCallSites()));
|
||||
discovery.add("callees", callees);
|
||||
}
|
||||
if (!discovery.isEmpty()) coverage.add("discovery", discovery);
|
||||
Integer omitted = calls == null ? null : calls.unrepresentedCalleeCalls();
|
||||
JsonArray directions = new JsonArray();
|
||||
if (missingCallers != null && missingCallers > 0) directions.add("callers");
|
||||
@@ -3733,20 +3781,49 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
if (calls == null && missingCallers == null) directions.add("callers");
|
||||
directions.add("callees");
|
||||
coverage.add("limited_directions", directions);
|
||||
return coverage;
|
||||
return qualifyProjectCallCoverage(coverage, calls, missingCallers);
|
||||
}
|
||||
JsonArray limitations = new JsonArray();
|
||||
if (callerLimitation != null) limitations.add(callerLimitation);
|
||||
if (omitted != null && omitted > 0) directions.add("callees");
|
||||
if (omitted != null && omitted > 0) {
|
||||
limitations.add("Ghidra's callee inventory omits targets of " + omitted +
|
||||
" call reference(s) or decoded call(s) without destinations.");
|
||||
directions.add("callees");
|
||||
}
|
||||
if (!limitations.isEmpty()) {
|
||||
coverage.addProperty("status", "partial");
|
||||
coverage.add("limitations", limitations);
|
||||
coverage.add("limited_directions", directions);
|
||||
}
|
||||
return qualifyProjectCallCoverage(coverage, calls, missingCallers);
|
||||
}
|
||||
|
||||
private JsonObject qualifyProjectCallCoverage(
|
||||
JsonObject coverage, CallBoundaryObservation calls, Integer missingCallers) {
|
||||
if (!existingProject) return coverage;
|
||||
String reason = "The selected project's prior analysis completeness is unknown; " +
|
||||
"the recorded call relationships may omit undiscovered callers or callees.";
|
||||
String status = coverage.get("status").getAsString();
|
||||
// A single-direction read with known omissions is still partial; an
|
||||
// unknown project history adds a limitation rather than erasing them.
|
||||
if (status.equals("partial") && (calls == null || missingCallers == null)) {
|
||||
coverage.getAsJsonArray("limitations").add(reason);
|
||||
return coverage;
|
||||
}
|
||||
if (status.equals("unknown")) reason += " " + coverage.get("reason").getAsString();
|
||||
if (status.equals("partial")) {
|
||||
for (JsonElement limitation : coverage.getAsJsonArray("limitations"))
|
||||
reason += " " + limitation.getAsString();
|
||||
}
|
||||
JsonArray directions = new JsonArray();
|
||||
if (missingCallers != null || (calls == null && missingCallers == null))
|
||||
directions.add("callers");
|
||||
if (calls != null || (calls == null && missingCallers == null))
|
||||
directions.add("callees");
|
||||
coverage.addProperty("status", "unknown");
|
||||
coverage.addProperty("reason", reason);
|
||||
coverage.remove("limitations");
|
||||
coverage.add("limited_directions", directions);
|
||||
return coverage;
|
||||
}
|
||||
|
||||
@@ -3761,6 +3838,24 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
return coverage;
|
||||
}
|
||||
|
||||
/** Name a few sites inline; reference reads and call-target queries recover the rest. */
|
||||
private static final int NAMED_COMPUTED_CALL_SITES = 4;
|
||||
|
||||
/**
|
||||
* A computed call's ReferenceManager targets are static candidates: Ghidra
|
||||
* records no proof that other values cannot reach the call, so the callee
|
||||
* set stays incomplete while the recorded candidates remain observed.
|
||||
*/
|
||||
private static String computedCallTargetLimitation(List<String> sites) {
|
||||
if (sites.isEmpty()) return null;
|
||||
int named = Math.min(sites.size(), NAMED_COMPUTED_CALL_SITES);
|
||||
String listed = String.join(", ", sites.subList(0, named)) +
|
||||
(sites.size() > named ? " and " + (sites.size() - named) + " more" : "");
|
||||
return "Ghidra records call reference targets at " + sites.size() +
|
||||
" computed call site(s) (" + listed + "); these static references do not establish" +
|
||||
" every possible target, so additional callees remain unknown.";
|
||||
}
|
||||
|
||||
private boolean unrepresentedCaller(Reference reference, Set<Function> callers) {
|
||||
if (!reference.getReferenceType().isCall()) return false;
|
||||
Function caller = functionAtOrContaining(reference.getFromAddress());
|
||||
@@ -3795,9 +3890,11 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
monitor.checkCancelled();
|
||||
calls.observe(reference);
|
||||
}
|
||||
List<String> computedCallSites = new ArrayList<>();
|
||||
for (Instruction instruction : instructions) {
|
||||
boundary.observe(instruction);
|
||||
if (!instruction.getFlowType().isCall()) continue;
|
||||
FlowType flow = instruction.getFlowType();
|
||||
if (!flow.isCall()) continue;
|
||||
boolean destination = false;
|
||||
for (Reference reference : instruction.getReferencesFrom()) {
|
||||
if (!reference.getReferenceType().isCall()) continue;
|
||||
@@ -3809,9 +3906,13 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
calls.unresolved(instruction.getAddress(),
|
||||
"Instruction decoder identifies a call but ReferenceManager supplies no call destination");
|
||||
}
|
||||
// The same decoded flow classifies resolve_native_call_targets'
|
||||
// mechanism; its recorded targets are candidates, not a closed set.
|
||||
else if (flow.isComputed()) computedCallSites.add(canonicalAddress(instruction.getAddress()));
|
||||
}
|
||||
return new CallBoundaryObservation(boundary.values(),
|
||||
returnedCallees == null ? null : calls.unrepresented, calls.unresolvedCalls());
|
||||
returnedCallees == null ? null : calls.unrepresented, calls.unresolvedCalls(),
|
||||
List.copyOf(computedCallSites));
|
||||
}
|
||||
|
||||
private final class FunctionBoundaryLimitations {
|
||||
@@ -5257,7 +5358,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
}
|
||||
}
|
||||
private record FunctionAnalysisObservation(JsonObject dossier, List<String> limitations, JsonObject relationshipCoverage, boolean decompilerFailed) {}
|
||||
private record CallBoundaryObservation(List<String> limitations, Integer unrepresentedCalleeCalls, JsonArray unresolvedCalls) {}
|
||||
private record CallBoundaryObservation(List<String> limitations, Integer unrepresentedCalleeCalls, JsonArray unresolvedCalls, List<String> computedCallSites) {}
|
||||
private record SwiftStringLiteralDecode(JsonArray literals, JsonArray omissions) {}
|
||||
private record SwiftLiteralLayout(
|
||||
String representation,
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.xml.sax.InputSource;
|
||||
/**
|
||||
* Apply the committed RISC-V calling-convention policy after analysis. Ghidra's generic RV32
|
||||
* compiler specification models ilp32d. Each policy derives a program-specific prototype from the
|
||||
* program's own default prototype, as its {@link Policy} row and docs/ghidra-riscv.md state. The
|
||||
* program's own default prototype, as its {@link Policy} row and docs/providers/ghidra-riscv.md state. The
|
||||
* script installs the prototype as a specification extension and assigns it, with dynamic
|
||||
* storage, to every non-thunk function, external function and function definition.
|
||||
*/
|
||||
|
||||
@@ -1399,7 +1399,8 @@ def _serve_connection(connection):
|
||||
break
|
||||
except (ConnectionError, OSError):
|
||||
# A lost client cannot confirm document closure or revoke this run.
|
||||
pass
|
||||
# Keep the listener available for the owner to confirm cleanup.
|
||||
should_stop = False
|
||||
finally:
|
||||
try:
|
||||
file.close()
|
||||
|
||||
@@ -24,3 +24,16 @@ func captureAccessibilityValue(_ source: Any?) -> AccessibilityValue {
|
||||
}
|
||||
return AccessibilityValue(value: NSNull(), gap: "AXValue type \(type(of: source)) is not a supported JSON scalar")
|
||||
}
|
||||
|
||||
/** Keep an unavailable action list distinct from a successful empty list. */
|
||||
func captureActionNames(status: Int32, success: Int32, names: [String]?) -> (names: [String], error: Int32?) {
|
||||
guard status == success else { return ([], status) }
|
||||
return (names ?? [], nil)
|
||||
}
|
||||
|
||||
/** AX absence is distinct from a failed attribute read. */
|
||||
func captureAttributeValue<Value>(status: Int32, success: Int32, absent: [Int32], value: Value?) -> (value: Value?, error: Int32?) {
|
||||
if status == success { return (value, nil) }
|
||||
if absent.contains(status) { return (nil, nil) }
|
||||
return (nil, status)
|
||||
}
|
||||
@@ -18,9 +18,10 @@ struct Request: Decodable {
|
||||
struct Action: Decodable { var kind: String; var path: [Int]?; var direction: String?; var text: String? }
|
||||
struct BoundaryFailure: Error { var code: String; var message: String }
|
||||
func fail(_ code: String, _ message: String) throws -> Never { throw BoundaryFailure(code: code, message: message) }
|
||||
func attribute(_ element: AXUIElement, _ key: String) -> CFTypeRef? {
|
||||
func attribute(_ element: AXUIElement, _ key: String) -> (value: CFTypeRef?, error: Int32?) {
|
||||
var value: CFTypeRef?
|
||||
return AXUIElementCopyAttributeValue(element, key as CFString, &value) == .success ? value : nil
|
||||
let status = AXUIElementCopyAttributeValue(element, key as CFString, &value)
|
||||
return captureAttributeValue(status: status.rawValue, success: AXError.success.rawValue, absent: [AXError.noValue.rawValue, AXError.attributeUnsupported.rawValue], value: value)
|
||||
}
|
||||
func childCount(_ element: AXUIElement) -> ChildCount {
|
||||
var count = 0
|
||||
@@ -34,13 +35,15 @@ func children(_ element: AXUIElement, count: Int) -> ChildBatch<AXUIElement> {
|
||||
return value as? [AXUIElement]
|
||||
}
|
||||
}
|
||||
func text(_ element: AXUIElement, _ key: String) -> Any { (attribute(element, key) as? String) ?? NSNull() as Any }
|
||||
func windowBounds(_ element: AXUIElement) -> CGRect? {
|
||||
guard let p = attribute(element, kAXPositionAttribute), let s = attribute(element, kAXSizeAttribute),
|
||||
CFGetTypeID(p) == AXValueGetTypeID(), CFGetTypeID(s) == AXValueGetTypeID() else { return nil }
|
||||
var point = CGPoint.zero; var size = CGSize.zero
|
||||
guard AXValueGetValue(p as! AXValue, .cgPoint, &point), AXValueGetValue(s as! AXValue, .cgSize, &size) else { return nil }
|
||||
return CGRect(origin: point, size: size)
|
||||
func windowBounds(_ element: AXUIElement) -> (bounds: CGRect?, error: Int32?) {
|
||||
let position = attribute(element, kAXPositionAttribute)
|
||||
let size = attribute(element, kAXSizeAttribute)
|
||||
if let error = position.error ?? size.error { return (nil, error) }
|
||||
guard let p = position.value, let s = size.value,
|
||||
CFGetTypeID(p) == AXValueGetTypeID(), CFGetTypeID(s) == AXValueGetTypeID() else { return (nil, nil) }
|
||||
var point = CGPoint.zero; var dimensions = CGSize.zero
|
||||
guard AXValueGetValue(p as! AXValue, .cgPoint, &point), AXValueGetValue(s as! AXValue, .cgSize, &dimensions) else { return (nil, nil) }
|
||||
return (CGRect(origin: point, size: dimensions), nil)
|
||||
}
|
||||
func observe(_ request: Request) async throws -> [String: Any] {
|
||||
guard let app = NSRunningApplication(processIdentifier: request.pid) else {
|
||||
@@ -84,11 +87,22 @@ func observe(_ request: Request) async throws -> [String: Any] {
|
||||
guard AXIsProcessTrusted() else { try fail("accessibility-denied", "Grant Accessibility to the REA host in System Settings > Privacy & Security, then retry") }
|
||||
let application = AXUIElementCreateApplication(request.pid)
|
||||
AXUIElementSetMessagingTimeout(application, 2)
|
||||
guard let axWindows = attribute(application, kAXWindowsAttribute) as? [AXUIElement] else {
|
||||
try fail("accessibility-unavailable", "Selected application does not expose accessibility windows")
|
||||
let windowsAttribute = attribute(application, kAXWindowsAttribute)
|
||||
if let error = windowsAttribute.error {
|
||||
try fail("accessibility-unavailable", "Cannot read accessibility windows: AXError \(error)")
|
||||
}
|
||||
let matches = axWindows.filter { windowBounds($0) == bounds }
|
||||
guard matches.count == 1 else { try fail("ambiguous-window", "Accessibility window geometry does not identify exactly one selected window; selected CG bounds \(bounds), AX candidates \(axWindows.map { String(describing: windowBounds($0)) })") }
|
||||
guard let axWindows = windowsAttribute.value as? [AXUIElement] else {
|
||||
try fail("accessibility-unavailable", "Accessibility windows are unavailable for the selected application")
|
||||
}
|
||||
let candidates = axWindows.map { (element: $0, observation: windowBounds($0)) }
|
||||
if let error = candidates.compactMap({ $0.observation.error }).first {
|
||||
try fail("accessibility-unavailable", "Cannot read accessibility window geometry: AXError \(error)")
|
||||
}
|
||||
guard candidates.allSatisfy({ $0.observation.bounds != nil }) else {
|
||||
try fail("accessibility-unavailable", "Accessibility window geometry is unavailable; the selected window cannot be identified")
|
||||
}
|
||||
let matches = candidates.filter { $0.observation.bounds == bounds }.map { $0.element }
|
||||
guard matches.count == 1 else { try fail("ambiguous-window", "Accessibility window geometry does not identify exactly one selected window; selected CG bounds \(bounds), AX candidates \(candidates.map { String(describing: $0.observation.bounds) })") }
|
||||
selected = matches[0]
|
||||
}
|
||||
if let action = request.action, let root = selected {
|
||||
@@ -99,13 +113,16 @@ func observe(_ request: Request) async throws -> [String: Any] {
|
||||
guard let available = count.value else {
|
||||
try fail("element-count-unavailable", "Cannot validate selected accessibility path because child count failed with AXError \(count.error ?? -1)")
|
||||
}
|
||||
guard index >= 0 && index < available,
|
||||
AXUIElementCopyAttributeValues(element, kAXChildrenAttribute as CFString, index, 1, &selectedChild) == .success,
|
||||
let item = (selectedChild as? [AXUIElement])?.first else { try fail("element-missing", "Selected accessibility path no longer exists") }
|
||||
guard index >= 0 && index < available else { try fail("element-missing", "Selected accessibility path no longer exists") }
|
||||
let childStatus = AXUIElementCopyAttributeValues(element, kAXChildrenAttribute as CFString, index, 1, &selectedChild)
|
||||
guard childStatus == .success else { try fail("accessibility-unavailable", "Cannot read selected accessibility child: AXError \(childStatus.rawValue)") }
|
||||
guard let item = (selectedChild as? [AXUIElement])?.first else { try fail("accessibility-unavailable", "Selected accessibility child was not returned") }
|
||||
element = item
|
||||
}
|
||||
var owner: pid_t = 0
|
||||
guard AXUIElementGetPid(element, &owner) == .success && owner == request.pid else { try fail("element-owner-mismatch", "Selected element belongs to another process") }
|
||||
let ownerStatus = AXUIElementGetPid(element, &owner)
|
||||
guard ownerStatus == .success else { try fail("accessibility-unavailable", "Cannot identify accessibility element owner: AXError \(ownerStatus.rawValue)") }
|
||||
guard owner == request.pid else { try fail("element-owner-mismatch", "Selected element belongs to another process") }
|
||||
let outcome: AXError
|
||||
switch action.kind {
|
||||
case "click": outcome = AXUIElementPerformAction(element, kAXPressAction as CFString)
|
||||
@@ -122,10 +139,18 @@ func observe(_ request: Request) async throws -> [String: Any] {
|
||||
if nodes.count >= request.max_nodes { truncated = true; break }
|
||||
let childCountResult = childCount(element)
|
||||
var actions: CFArray?
|
||||
AXUIElementCopyActionNames(element, &actions)
|
||||
let observedValue = captureAccessibilityValue(attribute(element, kAXValueAttribute))
|
||||
let actionStatus = AXUIElementCopyActionNames(element, &actions)
|
||||
let observedActions = captureActionNames(status: actionStatus.rawValue, success: AXError.success.rawValue, names: actions as? [String])
|
||||
if let error = observedActions.error { gaps.append("AX actions unavailable at path \(path): AXError \(error)"); truncated = true }
|
||||
let role = attribute(element, kAXRoleAttribute)
|
||||
let title = attribute(element, kAXTitleAttribute)
|
||||
let value = attribute(element, kAXValueAttribute)
|
||||
for (name, error) in [("role", role.error), ("title", title.error), ("value", value.error)] {
|
||||
if let error { gaps.append("AX \(name) unavailable at path \(path): AXError \(error)"); truncated = true }
|
||||
}
|
||||
let observedValue = captureAccessibilityValue(value.value)
|
||||
if let gap = observedValue.gap { gaps.append("\(gap) at path \(path)"); truncated = true }
|
||||
nodes.append(["path": path, "role": text(element, kAXRoleAttribute), "title": text(element, kAXTitleAttribute), "value": observedValue.value, "actions": actions as? [String] ?? [], "children_count": childCountResult.value.map { $0 as Any } ?? NSNull()])
|
||||
nodes.append(["path": path, "role": (role.value as? String) ?? NSNull() as Any, "title": (title.value as? String) ?? NSNull() as Any, "value": observedValue.value, "actions": observedActions.names, "children_count": childCountResult.value.map { $0 as Any } ?? NSNull()])
|
||||
guard let totalChildren = childCountResult.value else {
|
||||
truncated = true
|
||||
gaps.append("AX child count unavailable at path \(path): AXError \(childCountResult.error ?? -1)")
|
||||
|
||||
@@ -243,6 +243,20 @@ def _hex(value):
|
||||
return "0x%x" % value
|
||||
|
||||
|
||||
def _source_location(address):
|
||||
"""Preserve available line-entry facets without acquiring source files."""
|
||||
entry = address.GetLineEntry()
|
||||
if not entry.IsValid():
|
||||
return None
|
||||
file_spec = entry.GetFileSpec()
|
||||
file_path = str(file_spec) if file_spec.IsValid() else None
|
||||
line = entry.GetLine() or None
|
||||
column = entry.GetColumn() or None
|
||||
if not file_path and line is None and column is None:
|
||||
return None
|
||||
return {"file_path": file_path or None, "line": line, "column": column}
|
||||
|
||||
|
||||
def _location(address, target):
|
||||
"""Load and file address, module and symbol of one code address."""
|
||||
module = address.GetModule()
|
||||
@@ -256,6 +270,7 @@ def _location(address, target):
|
||||
"module": module.GetFileSpec().GetFilename() if module.IsValid() else None,
|
||||
"module_path": str(module.GetFileSpec()) if module.IsValid() else None,
|
||||
"symbol": symbol.GetName() if symbol.IsValid() else None,
|
||||
"source_location": _source_location(address),
|
||||
}
|
||||
return location
|
||||
|
||||
|
||||
@@ -25,6 +25,45 @@ spec.loader.exec_module(tracer)
|
||||
|
||||
|
||||
class NativeTraceBudgetTests(unittest.TestCase):
|
||||
def test_source_coordinates_preserve_partial_metadata_without_reading_source(self):
|
||||
def address(valid=True, file_valid=True, line=23, column=7):
|
||||
class SourceFileSpec:
|
||||
def IsValid(self):
|
||||
return file_valid
|
||||
|
||||
def __str__(self):
|
||||
return "/missing/é space/fixture.pas"
|
||||
|
||||
file_spec = SourceFileSpec()
|
||||
entry = types.SimpleNamespace(
|
||||
IsValid=lambda: valid,
|
||||
GetFileSpec=lambda: file_spec,
|
||||
GetLine=lambda: line,
|
||||
GetColumn=lambda: column,
|
||||
)
|
||||
return types.SimpleNamespace(GetLineEntry=lambda: entry)
|
||||
|
||||
self.assertEqual(
|
||||
tracer._source_location(address()),
|
||||
{"file_path": "/missing/é space/fixture.pas", "line": 23, "column": 7},
|
||||
)
|
||||
self.assertEqual(
|
||||
tracer._source_location(address(column=0)),
|
||||
{"file_path": "/missing/é space/fixture.pas", "line": 23, "column": None},
|
||||
)
|
||||
self.assertEqual(
|
||||
tracer._source_location(address(file_valid=False)),
|
||||
{"file_path": None, "line": 23, "column": 7},
|
||||
)
|
||||
self.assertEqual(
|
||||
tracer._source_location(address(line=0)),
|
||||
{"file_path": "/missing/é space/fixture.pas", "line": None, "column": 7},
|
||||
)
|
||||
self.assertIsNone(tracer._source_location(address(valid=False)))
|
||||
self.assertIsNone(
|
||||
tracer._source_location(address(file_valid=False, line=0, column=0))
|
||||
)
|
||||
|
||||
def test_invalid_launch_process_reports_explicit_no_creation(self):
|
||||
class InvalidProcess:
|
||||
def IsValid(self):
|
||||
@@ -390,6 +429,9 @@ class NativeTraceBudgetTests(unittest.TestCase):
|
||||
return FileSpec()
|
||||
|
||||
class Address:
|
||||
def GetLineEntry(self):
|
||||
return types.SimpleNamespace(IsValid=lambda: False)
|
||||
|
||||
def GetModule(self):
|
||||
return Module()
|
||||
|
||||
@@ -491,7 +533,24 @@ class NativeTraceBudgetTests(unittest.TestCase):
|
||||
def GetFileSpec(self):
|
||||
return FileSpec()
|
||||
|
||||
class SourceFileSpec:
|
||||
def IsValid(self):
|
||||
return True
|
||||
|
||||
def __str__(self):
|
||||
return source_path
|
||||
|
||||
class Address:
|
||||
def GetLineEntry(self):
|
||||
if source_path is None:
|
||||
return types.SimpleNamespace(IsValid=lambda: False)
|
||||
return types.SimpleNamespace(
|
||||
IsValid=lambda: True,
|
||||
GetFileSpec=SourceFileSpec,
|
||||
GetLine=lambda: 15,
|
||||
GetColumn=lambda: 3,
|
||||
)
|
||||
|
||||
def GetModule(self):
|
||||
return Module()
|
||||
|
||||
@@ -518,19 +577,35 @@ class NativeTraceBudgetTests(unittest.TestCase):
|
||||
breakpoint_count = 1000
|
||||
created = [[Breakpoint()] for _ in range(breakpoint_count)]
|
||||
config = {"breakpoints": [{"kind": "objc-method"}] * breakpoint_count}
|
||||
report, locations_truncated = tracer._breakpoint_report(
|
||||
object(), created, config
|
||||
)
|
||||
retained_bytes = sum(
|
||||
len(json.dumps(location).encode("utf-8"))
|
||||
+ (1 if index > 0 else 0)
|
||||
for row in report
|
||||
for index, location in enumerate(row["locations"])
|
||||
)
|
||||
self.assertTrue(locations_truncated)
|
||||
self.assertEqual(sum(row["location_count"] for row in report), 64_000)
|
||||
self.assertLess(sum(len(row["locations"]) for row in report), 64_000)
|
||||
self.assertLessEqual(retained_bytes, tracer.MAX_BREAKPOINT_LOCATION_BYTES)
|
||||
for source_path in (None, "/tmp/" + "源🚀" * 3000 + "/calls.pas"):
|
||||
with self.subTest(source_path_present=source_path is not None):
|
||||
report, locations_truncated = tracer._breakpoint_report(
|
||||
object(), created, config
|
||||
)
|
||||
retained_bytes = sum(
|
||||
len(json.dumps(location).encode("utf-8"))
|
||||
+ (1 if index > 0 else 0)
|
||||
for row in report
|
||||
for index, location in enumerate(row["locations"])
|
||||
)
|
||||
self.assertTrue(locations_truncated)
|
||||
self.assertEqual(
|
||||
sum(row["location_count"] for row in report), 64_000
|
||||
)
|
||||
self.assertLess(
|
||||
sum(len(row["locations"]) for row in report), 64_000
|
||||
)
|
||||
self.assertLessEqual(
|
||||
retained_bytes, tracer.MAX_BREAKPOINT_LOCATION_BYTES
|
||||
)
|
||||
if source_path is not None:
|
||||
self.assertTrue(
|
||||
any(
|
||||
location["source_location"]["file_path"] == source_path
|
||||
for row in report
|
||||
for location in row["locations"]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -78,14 +78,9 @@ public final class NativeAotExtension {
|
||||
new FrozenObjectAnnotator(program, manager).analyze(located.directory(), scan.getPointerLocations(), monitor, log);
|
||||
}
|
||||
monitor.checkCancelled();
|
||||
report.addProperty("method_tables", manager.getMethodTableCount());
|
||||
JsonObject coverage = auditFrozenObjects(program, scan.getPointerLocations(), monitor);
|
||||
report.add("coverage", coverage);
|
||||
if (coverage.get("frozen_objects_annotated").getAsInt() != coverage.get("frozen_object_candidates").getAsInt())
|
||||
diagnostics.add("Some frozen-object candidates lack committed instance annotations; inspect coverage counts and Ghidra diagnostics.");
|
||||
report.addProperty("status", diagnostics.isEmpty() ? "complete" : "partial");
|
||||
report.add("reason", JsonNull.INSTANCE);
|
||||
report.add("derived_memory", derivedRange.deepCopy());
|
||||
JsonArray tables = new JsonArray();
|
||||
for (var mt : manager.getMethodTables()) {
|
||||
monitor.checkCancelled();
|
||||
@@ -94,6 +89,13 @@ public final class NativeAotExtension {
|
||||
identity.addProperty("type", mt.getMTType().getPathName());
|
||||
tables.add(identity);
|
||||
}
|
||||
// Publish recovery facts only after every fallible recovery and audit step.
|
||||
// A failed transaction is rolled back, so it cannot report committed metadata.
|
||||
report.addProperty("method_tables", manager.getMethodTableCount());
|
||||
report.add("coverage", coverage);
|
||||
report.addProperty("status", diagnostics.isEmpty() ? "complete" : "partial");
|
||||
report.add("reason", JsonNull.INSTANCE);
|
||||
report.add("derived_memory", derivedRange.deepCopy());
|
||||
report.add("types", tables);
|
||||
commit = true;
|
||||
return finish(log);
|
||||
|
||||
@@ -109,7 +109,7 @@ class CoreContextTests(unittest.TestCase):
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertEqual(result["reason"], "output-limit")
|
||||
self.assertNotIn("exceeds64", result["message"])
|
||||
self.assertEqual(result["message"], "Complete debugger context exceeds the 64 MiB reply budget.")
|
||||
self.assertIn("64 MiB", result["message"])
|
||||
self.assertEqual(reads, [])
|
||||
self.assertEqual(queries, ["maps"])
|
||||
|
||||
|
||||
+88
-117
@@ -1,4 +1,18 @@
|
||||
import { defineConfig } from "vitepress";
|
||||
import { dirname, relative, resolve, sep } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import {
|
||||
documentationRewrites,
|
||||
documentationSections,
|
||||
} from "./documentation.js";
|
||||
|
||||
const documentationRoot = fileURLToPath(new URL("..", import.meta.url));
|
||||
const rewrites: Record<string, string> = {
|
||||
...documentationRewrites,
|
||||
"README.md": "documentation.md",
|
||||
"specs/README.md": "specs/index.md",
|
||||
"adr/README.md": "adr/index.md",
|
||||
};
|
||||
|
||||
export default defineConfig({
|
||||
title: "REA",
|
||||
@@ -6,135 +20,92 @@ export default defineConfig({
|
||||
"Reverse engineer binaries, applications, and runtime behavior with one CLI and MCP server.",
|
||||
lang: "en-US",
|
||||
base: "/rea/",
|
||||
rewrites,
|
||||
markdown: {
|
||||
config(md) {
|
||||
// Repository links resolve from their physical source. Render them from
|
||||
// the stable public route instead, including links across categories.
|
||||
md.core.ruler.after("inline", "documentation-source-links", (state) => {
|
||||
const physicalPath =
|
||||
state.env.realPath ??
|
||||
(state.env.relativePath
|
||||
? resolve(documentationRoot, state.env.relativePath)
|
||||
: null);
|
||||
if (physicalPath === null) return;
|
||||
const renderedPath =
|
||||
state.env.path ??
|
||||
resolve(
|
||||
documentationRoot,
|
||||
rewrites[state.env.relativePath] ?? state.env.relativePath,
|
||||
);
|
||||
for (const block of state.tokens) {
|
||||
for (const token of block.children ?? []) {
|
||||
const attribute =
|
||||
token.type === "link_open"
|
||||
? "href"
|
||||
: token.type === "image"
|
||||
? "src"
|
||||
: null;
|
||||
if (attribute === null) continue;
|
||||
const destination = token.attrGet(attribute);
|
||||
if (
|
||||
!destination ||
|
||||
/^(?:[a-z][a-z\d+.-]*:|[/#])/iu.test(destination)
|
||||
)
|
||||
continue;
|
||||
const separator = destination.search(/[?#]/u);
|
||||
const path =
|
||||
separator === -1 ? destination : destination.slice(0, separator);
|
||||
const suffix = separator === -1 ? "" : destination.slice(separator);
|
||||
const source = relative(
|
||||
documentationRoot,
|
||||
resolve(dirname(physicalPath), path),
|
||||
)
|
||||
.split(sep)
|
||||
.join("/");
|
||||
const rendered = relative(
|
||||
dirname(renderedPath),
|
||||
resolve(
|
||||
documentationRoot,
|
||||
source.startsWith("public/")
|
||||
? source.slice("public/".length)
|
||||
: (rewrites[source] ?? source),
|
||||
),
|
||||
)
|
||||
.split(sep)
|
||||
.join("/");
|
||||
token.attrSet(attribute, rendered + suffix);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
srcExclude: ["readme/**"],
|
||||
themeConfig: {
|
||||
nav: [
|
||||
{ text: "Get started", link: "/installation" },
|
||||
{ text: "Documentation", link: "/documentation" },
|
||||
{ text: "Reference", link: "/mcp-contracts" },
|
||||
{ text: "Roadmap", link: "/roadmap" },
|
||||
],
|
||||
sidebar: [
|
||||
{
|
||||
text: "Getting started",
|
||||
text: "Documentation directory",
|
||||
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" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Investigation guides",
|
||||
items: [
|
||||
{ text: "Native binaries", link: "/native-investigation" },
|
||||
{ text: "Go build metadata", link: "/go-binaries" },
|
||||
{ text: "IL2CPP metadata", link: "/il2cpp-metadata" },
|
||||
{ text: "Model artifacts", link: "/model-artifacts" },
|
||||
{ text: "Rust dependencies", link: "/rust-binaries" },
|
||||
{ text: "PE certificates", link: "/pe-certificates" },
|
||||
{ text: "PE imports", link: "/pe-imports" },
|
||||
{ text: "PE TLS/load config", link: "/pe-load-config" },
|
||||
{ text: "ELF notes", link: "/elf-notes" },
|
||||
{ text: "Binary hardening", link: "/binary-hardening" },
|
||||
{ text: "Apple IPS crash reports", link: "/apple-ips" },
|
||||
{ text: "Linux kernel modules", link: "/kernel-modules" },
|
||||
{ text: "CPython pyc files", link: "/python-pyc" },
|
||||
{ text: "Erlang BEAM", link: "/erlang-beam" },
|
||||
{
|
||||
text: "JavaScript and Electron",
|
||||
link: "/javascript-artifact-reconstruction",
|
||||
},
|
||||
{
|
||||
text: "JavaScript workflows",
|
||||
link: "/javascript-application-workflows",
|
||||
},
|
||||
{ text: "Browser observation", link: "/browser-observation" },
|
||||
{
|
||||
text: "Web network captures",
|
||||
link: "/web-network-captures",
|
||||
},
|
||||
{
|
||||
text: "Build RL environments",
|
||||
link: "/agent-environments-quickstart",
|
||||
},
|
||||
{ text: "Environment reference", link: "/agent-environments" },
|
||||
{ text: "Electron observation", link: "/electron-observation" },
|
||||
{ text: "Electron fuses", link: "/electron-fuses" },
|
||||
{ text: "Process capture", link: "/process-capture" },
|
||||
{
|
||||
text: "Desktop application capture",
|
||||
link: "/desktop-application-capture",
|
||||
},
|
||||
{
|
||||
text: "Desktop application state",
|
||||
link: "/desktop-application-state",
|
||||
},
|
||||
{
|
||||
text: "Desktop application export",
|
||||
link: "/desktop-application-export",
|
||||
},
|
||||
{
|
||||
text: "Desktop application tasks",
|
||||
link: "/desktop-application-tasks",
|
||||
},
|
||||
{
|
||||
text: "Desktop build computer",
|
||||
link: "/desktop-build-computer",
|
||||
},
|
||||
{
|
||||
text: "Building and witnessing",
|
||||
link: "/desktop-build-witness",
|
||||
},
|
||||
{ text: ".NET assemblies", link: "/managed-code-analysis" },
|
||||
{
|
||||
text: "Python packaged applications",
|
||||
link: "/python-packaged-applications",
|
||||
},
|
||||
{ text: "Android applications", link: "/android-analysis" },
|
||||
{ text: "Apple applications", link: "/apple-application-analysis" },
|
||||
{ text: "Desktop installations", link: "/desktop-applications" },
|
||||
{ text: "Firmware", link: "/firmware-analysis" },
|
||||
{ text: "iNES containers", link: "/ines-containers" },
|
||||
{ text: "SQLite databases", link: "/sqlite-databases" },
|
||||
{ text: "Packet captures", link: "/packet-captures" },
|
||||
{ text: "Signal recordings", link: "/signal-recordings" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Provider guides",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "IDA", link: "/ida-provider" },
|
||||
{ text: "Kuna", link: "/kuna-provider" },
|
||||
{ text: "Ghidra on Windows", link: "/windows-ghidra-p0" },
|
||||
{ text: "Ghidra DOS analysis", link: "/ghidra-dos" },
|
||||
{ text: "Ghidra raw binary", link: "/raw-binary" },
|
||||
{ text: "Ghidra NativeAOT", link: "/ghidra-nativeaot" },
|
||||
{ text: "Ghidra PowerPC", link: "/ghidra-ppc" },
|
||||
{ text: "Ghidra GameCube DOL", link: "/ghidra-dol" },
|
||||
{ text: "Ghidra semantics", link: "/ghidra-provider" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Reference and development",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "MCP contracts", link: "/mcp-contracts" },
|
||||
{ text: "Tool design", link: "/tool-design" },
|
||||
{
|
||||
text: "Admission limits and recovery",
|
||||
link: "/design/limits-and-recovery",
|
||||
},
|
||||
{ text: "Testing", link: "/testing" },
|
||||
{ text: "Client verification", link: "/client-verification" },
|
||||
{
|
||||
text: "Reconstruction readiness",
|
||||
link: "/reconstruction-readiness",
|
||||
},
|
||||
{ text: "Releasing", link: "/releasing" },
|
||||
{ text: "All guides", link: "/documentation" },
|
||||
{ text: "Authoring conventions", link: "/development/documentation" },
|
||||
{ text: "Feature specifications", link: "/specs/" },
|
||||
{ text: "Architecture decisions", link: "/adr/" },
|
||||
],
|
||||
},
|
||||
...documentationSections.map((section) => ({
|
||||
text: section.text,
|
||||
collapsed: section.text !== "Getting started",
|
||||
items: section.items.map((item) => ({
|
||||
text: item.text,
|
||||
link: item.route,
|
||||
})),
|
||||
})),
|
||||
],
|
||||
search: { provider: "local" },
|
||||
socialLinks: [
|
||||
|
||||
@@ -0,0 +1,664 @@
|
||||
// Authored guide ownership: physical sources and stable public routes.
|
||||
export const documentationSections = [
|
||||
{
|
||||
text: "Getting started",
|
||||
items: [
|
||||
{
|
||||
text: "Installation and setup",
|
||||
source: "getting-started/installation.md",
|
||||
route: "/installation",
|
||||
},
|
||||
{
|
||||
text: "Client configuration and troubleshooting",
|
||||
source: "getting-started/client-configuration.md",
|
||||
route: "/client-configuration",
|
||||
},
|
||||
{
|
||||
text: "CLI and Evidence",
|
||||
source: "getting-started/cli.md",
|
||||
route: "/cli",
|
||||
},
|
||||
{
|
||||
text: "Guided MCP prompts and completion",
|
||||
source: "getting-started/mcp-prompts.md",
|
||||
route: "/mcp-prompts",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Native binaries",
|
||||
items: [
|
||||
{
|
||||
text: "Native binary investigation",
|
||||
source: "guides/native/native-investigation.md",
|
||||
route: "/native-investigation",
|
||||
},
|
||||
{
|
||||
text: "Go binary build metadata",
|
||||
source: "guides/native/go-binaries.md",
|
||||
route: "/go-binaries",
|
||||
},
|
||||
{
|
||||
text: "Offline binary diagnostics",
|
||||
source: "guides/native/binary-diagnostics.md",
|
||||
route: "/binary-diagnostics",
|
||||
},
|
||||
{
|
||||
text: "Recorded crash evidence",
|
||||
source: "guides/native/recorded-crashes.md",
|
||||
route: "/recorded-crashes",
|
||||
},
|
||||
{
|
||||
text: "Windows Shell Link shortcuts",
|
||||
source: "guides/native/windows-shortcut.md",
|
||||
route: "/windows-shortcut",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "JavaScript and Electron",
|
||||
items: [
|
||||
{
|
||||
text: "JavaScript Application Graph",
|
||||
source: "guides/javascript/javascript-application-graph.md",
|
||||
route: "/javascript-application-graph",
|
||||
},
|
||||
{
|
||||
text: "Cross-layer JavaScript application workflows",
|
||||
source: "guides/javascript/javascript-application-workflows.md",
|
||||
route: "/javascript-application-workflows",
|
||||
},
|
||||
{
|
||||
text: "JavaScript artifact reconstruction",
|
||||
source: "guides/javascript/javascript-artifact-reconstruction.md",
|
||||
route: "/javascript-artifact-reconstruction",
|
||||
},
|
||||
{
|
||||
text: "JavaScript source recovery",
|
||||
source: "guides/javascript/javascript-recovery.md",
|
||||
route: "/javascript-recovery",
|
||||
},
|
||||
{
|
||||
text: "Passive Node and Electron runtime observation",
|
||||
source: "guides/javascript/javascript-runtime-observation.md",
|
||||
route: "/javascript-runtime-observation",
|
||||
},
|
||||
{
|
||||
text: "JavaScript static/runtime reconciliation",
|
||||
source: "guides/javascript/javascript-runtime-reconciliation.md",
|
||||
route: "/javascript-runtime-reconciliation",
|
||||
},
|
||||
{
|
||||
text: "Electron file-page observation",
|
||||
source: "guides/javascript/electron-observation.md",
|
||||
route: "/electron-observation",
|
||||
},
|
||||
{
|
||||
text: "V8 code cache inspection",
|
||||
source: "guides/javascript/v8-code-cache.md",
|
||||
route: "/v8-code-cache",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Browser and captured websites",
|
||||
items: [
|
||||
{
|
||||
text: "Website observation with CDP",
|
||||
source: "guides/web/browser-observation.md",
|
||||
route: "/browser-observation",
|
||||
},
|
||||
{
|
||||
text: "Browser scenario contract",
|
||||
source: "guides/web/browser-scenario-contract.md",
|
||||
route: "/browser-scenario-contract",
|
||||
},
|
||||
{
|
||||
text: "Website runtime source attribution",
|
||||
source: "guides/web/web-runtime.md",
|
||||
route: "/web-runtime",
|
||||
},
|
||||
{
|
||||
text: "Historical web network captures",
|
||||
source: "guides/web/web-network-captures.md",
|
||||
route: "/web-network-captures",
|
||||
},
|
||||
{
|
||||
text: "HTTP/3 capture lab",
|
||||
source: "http3-capture-lab.md",
|
||||
route: "/http3-capture-lab",
|
||||
},
|
||||
{
|
||||
text: "Captured website source locations",
|
||||
source: "guides/web/web-source-location.md",
|
||||
route: "/web-source-location",
|
||||
},
|
||||
{
|
||||
text: "Captured website module relationships",
|
||||
source: "guides/web/website-module-trace.md",
|
||||
route: "/website-module-trace",
|
||||
},
|
||||
{
|
||||
text: "Captured website scripts and static JavaScript analysis",
|
||||
source: "guides/web/website-script-export.md",
|
||||
route: "/website-script-export",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Android applications",
|
||||
items: [
|
||||
{
|
||||
text: "Static Android APK analysis",
|
||||
source: "guides/android/android-analysis.md",
|
||||
route: "/android-analysis",
|
||||
},
|
||||
{
|
||||
text: "Apktool resource decoding",
|
||||
source: "guides/android/apktool-resource-analysis.md",
|
||||
route: "/apktool-resource-analysis",
|
||||
},
|
||||
{
|
||||
text: "ADB device inspection and acquisition",
|
||||
source: "guides/android/adb-device-analysis.md",
|
||||
route: "/adb-device-analysis",
|
||||
},
|
||||
{
|
||||
text: "Flutter build identification",
|
||||
source: "guides/android/flutter-analysis.md",
|
||||
route: "/flutter-analysis",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Apple applications",
|
||||
items: [
|
||||
{
|
||||
text: "Apple Application Inventory Projection",
|
||||
source: "guides/apple/apple-application-analysis.md",
|
||||
route: "/apple-application-analysis",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: ".NET assemblies",
|
||||
items: [
|
||||
{
|
||||
text: "Managed-code analysis",
|
||||
source: "guides/managed/managed-code-analysis.md",
|
||||
route: "/managed-code-analysis",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Firmware",
|
||||
items: [
|
||||
{
|
||||
text: "Firmware analysis",
|
||||
source: "guides/firmware/firmware-analysis.md",
|
||||
route: "/firmware-analysis",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "HarmonyOS packages",
|
||||
items: [
|
||||
{
|
||||
text: "Static HarmonyOS package inventory",
|
||||
source: "guides/harmony/harmony-analysis.md",
|
||||
route: "/harmony-analysis",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "WebAssembly",
|
||||
items: [
|
||||
{
|
||||
text: "Offline WebAssembly artifacts",
|
||||
source: "guides/wasm/wasm-artifacts.md",
|
||||
route: "/wasm-artifacts",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "EVM contracts",
|
||||
items: [
|
||||
{
|
||||
text: "Offline EVM bytecode",
|
||||
source: "guides/evm/evm-bytecode.md",
|
||||
route: "/evm-bytecode",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Databases and recorded packets",
|
||||
items: [
|
||||
{
|
||||
text: "SQLite database snapshots",
|
||||
source: "guides/data/sqlite-databases.md",
|
||||
route: "/sqlite-databases",
|
||||
},
|
||||
{
|
||||
text: "Recorded packet capture inspection",
|
||||
source: "guides/data/packet-captures.md",
|
||||
route: "/packet-captures",
|
||||
},
|
||||
{
|
||||
text: "Packet capture summaries",
|
||||
source: "guides/data/pcap-analysis.md",
|
||||
route: "/pcap-analysis",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Process capture and instrumentation",
|
||||
items: [
|
||||
{
|
||||
text: "Process capture",
|
||||
source: "guides/runtime/process-capture.md",
|
||||
route: "/process-capture",
|
||||
},
|
||||
{
|
||||
text: "Frida instrumentation",
|
||||
source: "guides/runtime/frida-instrumentation.md",
|
||||
route: "/frida-instrumentation",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Provider setup and formats",
|
||||
items: [
|
||||
{
|
||||
text: "Ghidra provider semantics",
|
||||
source: "providers/ghidra-provider.md",
|
||||
route: "/ghidra-provider",
|
||||
},
|
||||
{
|
||||
text: "DOS MZ and COM analysis with Ghidra",
|
||||
source: "providers/ghidra-dos.md",
|
||||
route: "/ghidra-dos",
|
||||
},
|
||||
{
|
||||
text: "Optional NativeAOT metadata recovery",
|
||||
source: "providers/ghidra-nativeaot.md",
|
||||
route: "/ghidra-nativeaot",
|
||||
},
|
||||
{
|
||||
text: "MIPS ELF analysis through Ghidra",
|
||||
source: "providers/ghidra-mips.md",
|
||||
route: "/ghidra-mips",
|
||||
},
|
||||
{
|
||||
text: "PSP static ELF analysis through Ghidra",
|
||||
source: "providers/ghidra-psp.md",
|
||||
route: "/ghidra-psp",
|
||||
},
|
||||
{
|
||||
text: "RISC-V ELF analysis through Ghidra",
|
||||
source: "providers/ghidra-riscv.md",
|
||||
route: "/ghidra-riscv",
|
||||
},
|
||||
{
|
||||
text: "Windows Ghidra P0",
|
||||
source: "providers/windows-ghidra-p0.md",
|
||||
route: "/windows-ghidra-p0",
|
||||
},
|
||||
{
|
||||
text: "Headerless raw-binary analysis with Ghidra",
|
||||
source: "providers/raw-binary.md",
|
||||
route: "/raw-binary",
|
||||
},
|
||||
{
|
||||
text: "IDA provider",
|
||||
source: "providers/ida-provider.md",
|
||||
route: "/ida-provider",
|
||||
},
|
||||
{
|
||||
text: "JEB instrumentation and analysis",
|
||||
source: "providers/jeb-analysis.md",
|
||||
route: "/jeb-analysis",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Contracts and evidence",
|
||||
items: [
|
||||
{
|
||||
text: "MCP runtime contracts",
|
||||
source: "reference/mcp-contracts.md",
|
||||
route: "/mcp-contracts",
|
||||
},
|
||||
{
|
||||
text: "Reconstruction obligation ledgers",
|
||||
source: "reference/reconstruction-obligation-ledgers.md",
|
||||
route: "/reconstruction-obligation-ledgers",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Development and verification",
|
||||
items: [
|
||||
{
|
||||
text: "Settings and recovery",
|
||||
source: "design/limits-and-recovery.md",
|
||||
route: "/design/limits-and-recovery",
|
||||
},
|
||||
{
|
||||
text: "MCP tool design",
|
||||
source: "development/tool-design.md",
|
||||
route: "/tool-design",
|
||||
},
|
||||
{
|
||||
text: "Testing REA",
|
||||
source: "development/testing.md",
|
||||
route: "/testing",
|
||||
},
|
||||
{
|
||||
text: "Client and agent verification",
|
||||
source: "development/client-verification.md",
|
||||
route: "/client-verification",
|
||||
},
|
||||
{
|
||||
text: "Reconstruction readiness conformance",
|
||||
source: "development/reconstruction-readiness.md",
|
||||
route: "/reconstruction-readiness",
|
||||
},
|
||||
{
|
||||
text: "Releasing REA",
|
||||
source: "development/releasing.md",
|
||||
route: "/releasing",
|
||||
},
|
||||
{
|
||||
text: "REA roadmap",
|
||||
source: "development/roadmap.md",
|
||||
route: "/roadmap",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Release migrations",
|
||||
items: [
|
||||
{
|
||||
text: "Upgrading from REA 6.1 to 6.2",
|
||||
source: "migrations/migration-6.2.md",
|
||||
route: "/migration-6.2",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Signal recordings",
|
||||
items: [
|
||||
{
|
||||
text: "Recorded signal inspection",
|
||||
source: "guides/signals/signal-recordings.md",
|
||||
route: "/signal-recordings",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Additional guides",
|
||||
items: [
|
||||
{
|
||||
text: "Offline API contract inventory",
|
||||
source: "api-contracts.md",
|
||||
route: "/api-contracts",
|
||||
},
|
||||
{
|
||||
text: "Bun standalone executables",
|
||||
source: "bun-standalone.md",
|
||||
route: "/bun-standalone",
|
||||
},
|
||||
{
|
||||
text: "Capability composition and ownership",
|
||||
source: "capability-composition.md",
|
||||
route: "/capability-composition",
|
||||
},
|
||||
{
|
||||
text: ".NET single-file bundles",
|
||||
source: "dotnet-bundles.md",
|
||||
route: "/dotnet-bundles",
|
||||
},
|
||||
{
|
||||
text: "ESP flash images",
|
||||
source: "esp-flash-image.md",
|
||||
route: "/esp-flash-image",
|
||||
},
|
||||
{
|
||||
text: "U-Boot FIT images",
|
||||
source: "fit-images.md",
|
||||
route: "/fit-images",
|
||||
},
|
||||
{
|
||||
text: "Measure MCP catalog costs in Codex",
|
||||
source: "mcp-catalog-evaluation.md",
|
||||
route: "/mcp-catalog-evaluation",
|
||||
},
|
||||
{
|
||||
text: "Offline Playwright traces",
|
||||
source: "playwright-traces.md",
|
||||
route: "/playwright-traces",
|
||||
},
|
||||
{
|
||||
text: "Testing lanes and provider verification",
|
||||
source: "testing-lanes.md",
|
||||
route: "/testing-lanes",
|
||||
},
|
||||
{
|
||||
text: "UF2 and DfuSe images",
|
||||
source: "uf2-dfuse.md",
|
||||
route: "/uf2-dfuse",
|
||||
},
|
||||
{
|
||||
text: "WeChat mini-program wxapkg archives",
|
||||
source: "wxapkg.md",
|
||||
route: "/wxapkg",
|
||||
},
|
||||
{
|
||||
text: "Binary hardening",
|
||||
source: "binary-hardening.md",
|
||||
route: "/binary-hardening",
|
||||
},
|
||||
{
|
||||
text: "Desktop application capture",
|
||||
source: "desktop-application-capture.md",
|
||||
route: "/desktop-application-capture",
|
||||
},
|
||||
{
|
||||
text: "Desktop application export",
|
||||
source: "desktop-application-export.md",
|
||||
route: "/desktop-application-export",
|
||||
},
|
||||
{
|
||||
text: "Desktop application state",
|
||||
source: "desktop-application-state.md",
|
||||
route: "/desktop-application-state",
|
||||
},
|
||||
{
|
||||
text: "Desktop application tasks",
|
||||
source: "desktop-application-tasks.md",
|
||||
route: "/desktop-application-tasks",
|
||||
},
|
||||
{
|
||||
text: "Desktop build computer",
|
||||
source: "desktop-build-computer.md",
|
||||
route: "/desktop-build-computer",
|
||||
},
|
||||
{
|
||||
text: "Desktop build witness",
|
||||
source: "desktop-build-witness.md",
|
||||
route: "/desktop-build-witness",
|
||||
},
|
||||
{
|
||||
text: "iNES containers",
|
||||
source: "ines-containers.md",
|
||||
route: "/ines-containers",
|
||||
},
|
||||
{
|
||||
text: "Build RL environments with REA",
|
||||
source: "agent-environments-quickstart.md",
|
||||
route: "/agent-environments-quickstart",
|
||||
},
|
||||
{
|
||||
text: "Agent environments from recorded captures",
|
||||
source: "agent-environments.md",
|
||||
route: "/agent-environments",
|
||||
},
|
||||
{
|
||||
text: "APK signature schemes",
|
||||
source: "apk-signature.md",
|
||||
route: "/apk-signature",
|
||||
},
|
||||
{
|
||||
text: "Apple IPS crash reports",
|
||||
source: "apple-ips.md",
|
||||
route: "/apple-ips",
|
||||
},
|
||||
{
|
||||
text: "Static analysis in GitHub Actions",
|
||||
source: "ci-analysis.md",
|
||||
route: "/ci-analysis",
|
||||
},
|
||||
{
|
||||
text: "Desktop installation directories",
|
||||
source: "desktop-applications.md",
|
||||
route: "/desktop-applications",
|
||||
},
|
||||
{
|
||||
text: "Flattened devicetree inspection",
|
||||
source: "devicetree.md",
|
||||
route: "/devicetree",
|
||||
},
|
||||
{
|
||||
text: "Electron fuse state",
|
||||
source: "electron-fuses.md",
|
||||
route: "/electron-fuses",
|
||||
},
|
||||
{ text: "ELF note tables", source: "elf-notes.md", route: "/elf-notes" },
|
||||
{
|
||||
text: "Erlang BEAM files",
|
||||
source: "erlang-beam.md",
|
||||
route: "/erlang-beam",
|
||||
},
|
||||
{ text: "ESP images", source: "esp-image.md", route: "/esp-image" },
|
||||
{
|
||||
text: "GameCube DOL analysis through Ghidra",
|
||||
source: "ghidra-dol.md",
|
||||
route: "/ghidra-dol",
|
||||
},
|
||||
{
|
||||
text: "PowerPC ELF analysis through Ghidra",
|
||||
source: "ghidra-ppc.md",
|
||||
route: "/ghidra-ppc",
|
||||
},
|
||||
{
|
||||
text: "Godot PCK archives",
|
||||
source: "godot-pck.md",
|
||||
route: "/godot-pck",
|
||||
},
|
||||
{
|
||||
text: "Static CUDA and HIP code objects",
|
||||
source: "gpu-code-objects.md",
|
||||
route: "/gpu-code-objects",
|
||||
},
|
||||
{
|
||||
text: "Intel HEX and S-record images",
|
||||
source: "hex-records.md",
|
||||
route: "/hex-records",
|
||||
},
|
||||
{
|
||||
text: "IL2CPP metadata",
|
||||
source: "il2cpp-metadata.md",
|
||||
route: "/il2cpp-metadata",
|
||||
},
|
||||
{
|
||||
text: "Static JavaScript route inventory",
|
||||
source: "javascript-route-inventory.md",
|
||||
route: "/javascript-route-inventory",
|
||||
},
|
||||
{
|
||||
text: "Linux kernel modules",
|
||||
source: "kernel-modules.md",
|
||||
route: "/kernel-modules",
|
||||
},
|
||||
{
|
||||
text: "Kuna provider",
|
||||
source: "kuna-provider.md",
|
||||
route: "/kuna-provider",
|
||||
},
|
||||
{
|
||||
text: "Model file declarations",
|
||||
source: "model-artifacts.md",
|
||||
route: "/model-artifacts",
|
||||
},
|
||||
{
|
||||
text: "Match native functions across builds",
|
||||
source: "native-function-matching.md",
|
||||
route: "/native-function-matching",
|
||||
},
|
||||
{
|
||||
text: "Node.js single executable applications",
|
||||
source: "node-sea.md",
|
||||
route: "/node-sea",
|
||||
},
|
||||
{
|
||||
text: "PE Authenticode certificate tables",
|
||||
source: "pe-certificates.md",
|
||||
route: "/pe-certificates",
|
||||
},
|
||||
{
|
||||
text: "PE import and delay-load tables",
|
||||
source: "pe-imports.md",
|
||||
route: "/pe-imports",
|
||||
},
|
||||
{
|
||||
text: "PE TLS callbacks and load configuration",
|
||||
source: "pe-load-config.md",
|
||||
route: "/pe-load-config",
|
||||
},
|
||||
{
|
||||
text: "Python packaged applications",
|
||||
source: "python-packaged-applications.md",
|
||||
route: "/python-packaged-applications",
|
||||
},
|
||||
{
|
||||
text: "CPython pyc inspection",
|
||||
source: "python-pyc.md",
|
||||
route: "/python-pyc",
|
||||
},
|
||||
{
|
||||
text: "Reconstruction coverage",
|
||||
source: "reconstruction-coverage.md",
|
||||
route: "/reconstruction-coverage",
|
||||
},
|
||||
{
|
||||
text: "Reverse-engineering tool integrations",
|
||||
source: "reverse-engineering-tools.md",
|
||||
route: "/reverse-engineering-tools",
|
||||
},
|
||||
{
|
||||
text: "Rust binary dependency metadata",
|
||||
source: "rust-binaries.md",
|
||||
route: "/rust-binaries",
|
||||
},
|
||||
{
|
||||
text: "U-Boot legacy uImage containers",
|
||||
source: "uimage.md",
|
||||
route: "/uimage",
|
||||
},
|
||||
{
|
||||
text: "UnityFS AssetBundle archives",
|
||||
source: "unityfs.md",
|
||||
route: "/unityfs",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const documentationRewrites = Object.fromEntries(
|
||||
documentationSections.flatMap((section) =>
|
||||
section.items.flatMap((item) => {
|
||||
const target = `${item.route.slice(1)}.md`;
|
||||
return item.source === target ? [] : [[item.source, target]];
|
||||
}),
|
||||
),
|
||||
);
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
# Documentation directory
|
||||
|
||||
REA documentation is organized by reader task and document owner. This directory
|
||||
links every authored guide; the [site](https://rea.tools/) also serves separate
|
||||
product pages. The VitePress documentation source is this `docs/` tree.
|
||||
|
||||
## Getting started
|
||||
|
||||
- [Installation and setup](getting-started/installation.md)
|
||||
- [Client configuration and troubleshooting](getting-started/client-configuration.md)
|
||||
- [CLI and Evidence](getting-started/cli.md)
|
||||
- [Guided MCP prompts and completion](getting-started/mcp-prompts.md)
|
||||
|
||||
## Native binaries
|
||||
|
||||
- [Native binary investigation](guides/native/native-investigation.md)
|
||||
- [Go binary build metadata](guides/native/go-binaries.md)
|
||||
- [Offline binary diagnostics](guides/native/binary-diagnostics.md)
|
||||
- [Recorded crash evidence](guides/native/recorded-crashes.md)
|
||||
- [Windows Shell Link shortcuts](guides/native/windows-shortcut.md)
|
||||
|
||||
## JavaScript and Electron
|
||||
|
||||
- [JavaScript Application Graph](guides/javascript/javascript-application-graph.md)
|
||||
- [Cross-layer JavaScript application workflows](guides/javascript/javascript-application-workflows.md)
|
||||
- [JavaScript artifact reconstruction](guides/javascript/javascript-artifact-reconstruction.md)
|
||||
- [JavaScript source recovery](guides/javascript/javascript-recovery.md)
|
||||
- [Passive Node and Electron runtime observation](guides/javascript/javascript-runtime-observation.md)
|
||||
- [JavaScript static/runtime reconciliation](guides/javascript/javascript-runtime-reconciliation.md)
|
||||
- [Electron file-page observation](guides/javascript/electron-observation.md)
|
||||
- [V8 code cache inspection](guides/javascript/v8-code-cache.md)
|
||||
|
||||
## Browser and captured websites
|
||||
|
||||
- [Website observation with CDP](guides/web/browser-observation.md)
|
||||
- [Browser scenario contract](guides/web/browser-scenario-contract.md)
|
||||
- [Website runtime source attribution](guides/web/web-runtime.md)
|
||||
- [Historical web network captures](guides/web/web-network-captures.md)
|
||||
- [HTTP/3 capture lab](http3-capture-lab.md)
|
||||
- [Captured website source locations](guides/web/web-source-location.md)
|
||||
- [Captured website module relationships](guides/web/website-module-trace.md)
|
||||
- [Captured website scripts and static JavaScript analysis](guides/web/website-script-export.md)
|
||||
|
||||
## Android applications
|
||||
|
||||
- [Static Android APK analysis](guides/android/android-analysis.md)
|
||||
- [Apktool resource decoding](guides/android/apktool-resource-analysis.md)
|
||||
- [ADB device inspection and acquisition](guides/android/adb-device-analysis.md)
|
||||
- [Flutter build identification](guides/android/flutter-analysis.md)
|
||||
|
||||
## Apple applications
|
||||
|
||||
- [Apple Application Inventory Projection](guides/apple/apple-application-analysis.md)
|
||||
|
||||
## .NET assemblies
|
||||
|
||||
- [Managed-code analysis](guides/managed/managed-code-analysis.md)
|
||||
|
||||
## Firmware
|
||||
|
||||
- [Firmware analysis](guides/firmware/firmware-analysis.md)
|
||||
|
||||
## HarmonyOS packages
|
||||
|
||||
- [Static HarmonyOS package inventory](guides/harmony/harmony-analysis.md)
|
||||
|
||||
## WebAssembly
|
||||
|
||||
- [Offline WebAssembly artifacts](guides/wasm/wasm-artifacts.md)
|
||||
|
||||
## EVM contracts
|
||||
|
||||
- [Offline EVM bytecode](guides/evm/evm-bytecode.md)
|
||||
|
||||
## Databases and recorded packets
|
||||
|
||||
- [SQLite database snapshots](guides/data/sqlite-databases.md)
|
||||
- [Recorded packet capture inspection](guides/data/packet-captures.md)
|
||||
- [Packet capture summaries](guides/data/pcap-analysis.md)
|
||||
|
||||
## Process capture and instrumentation
|
||||
|
||||
- [Process capture](guides/runtime/process-capture.md)
|
||||
- [Frida instrumentation](guides/runtime/frida-instrumentation.md)
|
||||
|
||||
## Signal recordings
|
||||
|
||||
- [Recorded signal inspection](guides/signals/signal-recordings.md)
|
||||
|
||||
## Provider setup and formats
|
||||
|
||||
- [Ghidra provider semantics](providers/ghidra-provider.md)
|
||||
- [DOS MZ and COM analysis with Ghidra](providers/ghidra-dos.md)
|
||||
- [Optional NativeAOT metadata recovery](providers/ghidra-nativeaot.md)
|
||||
- [MIPS ELF analysis through Ghidra](providers/ghidra-mips.md)
|
||||
- [PSP static ELF analysis through Ghidra](providers/ghidra-psp.md)
|
||||
- [RISC-V ELF analysis through Ghidra](providers/ghidra-riscv.md)
|
||||
- [Windows Ghidra P0](providers/windows-ghidra-p0.md)
|
||||
- [Headerless raw-binary analysis with Ghidra](providers/raw-binary.md)
|
||||
- [IDA provider](providers/ida-provider.md)
|
||||
- [JEB instrumentation and analysis](providers/jeb-analysis.md)
|
||||
|
||||
## Contracts and evidence
|
||||
|
||||
- [MCP runtime contracts](reference/mcp-contracts.md)
|
||||
- [Reconstruction obligation ledgers](reference/reconstruction-obligation-ledgers.md)
|
||||
|
||||
## Development and verification
|
||||
|
||||
- [Settings and recovery](design/limits-and-recovery.md)
|
||||
- [MCP tool design](development/tool-design.md)
|
||||
- [Testing REA](development/testing.md)
|
||||
- [Client and agent verification](development/client-verification.md)
|
||||
- [Reconstruction readiness conformance](development/reconstruction-readiness.md)
|
||||
- [Releasing REA](development/releasing.md)
|
||||
- [REA roadmap](development/roadmap.md)
|
||||
|
||||
## Release migrations
|
||||
|
||||
- [Upgrading from REA 6.1 to 6.2](migrations/migration-6.2.md)
|
||||
|
||||
## Architecture and authoring
|
||||
|
||||
- [Architecture map](https://github.com/morluto/rea/blob/main/docs/architecture/architecture.mermaid)
|
||||
- [Documentation ownership and contribution model](development/documentation.md)
|
||||
- [Feature specifications](specs/README.md)
|
||||
- [Architectural decision records](adr/README.md)
|
||||
|
||||
## Machine-owned documentation
|
||||
|
||||
| Path | Owner and update command |
|
||||
| ----------------------------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| `public/product-catalog.json` | Ignored contract projection; `npm run docs:generate` |
|
||||
| `verification/managed-conformance-*.json` | Ignored managed conformance projections; `npm run evidence:generate` |
|
||||
| `error-contract.schema.json` | Tracked schema from contracts; `npm run docs:error-schema` |
|
||||
| `user-visible-errors.csv` | Authored error classification inventory; preserve its schema |
|
||||
| `releases/<version>.contributions.json` | Durable release contribution record; follow the [release guide](development/releasing.md) |
|
||||
| `assets/` | Shared authored images referenced by guides |
|
||||
|
||||
Do not edit generated catalogs or evidence to change product facts. Change their
|
||||
canonical contracts or producer and regenerate. Historical release records retain
|
||||
the exact commit messages and references from the release they describe.
|
||||
|
||||
## Additional guides
|
||||
|
||||
- [Offline API contract inventory](api-contracts.md)
|
||||
- [Bun standalone executables](bun-standalone.md)
|
||||
- [Capability composition and ownership](capability-composition.md)
|
||||
- [.NET single-file bundles](dotnet-bundles.md)
|
||||
- [ESP flash images](esp-flash-image.md)
|
||||
- [U-Boot FIT images](fit-images.md)
|
||||
- [Measure MCP catalog costs in Codex](mcp-catalog-evaluation.md)
|
||||
- [Offline Playwright traces](playwright-traces.md)
|
||||
- [Testing lanes and provider verification](testing-lanes.md)
|
||||
- [UF2 and DfuSe images](uf2-dfuse.md)
|
||||
- [WeChat mini-program wxapkg archives](wxapkg.md)
|
||||
- [Binary hardening](binary-hardening.md)
|
||||
- [Desktop application capture](desktop-application-capture.md)
|
||||
- [Desktop application export](desktop-application-export.md)
|
||||
- [Desktop application state](desktop-application-state.md)
|
||||
- [Desktop application tasks](desktop-application-tasks.md)
|
||||
- [Desktop build computer](desktop-build-computer.md)
|
||||
- [Desktop build witness](desktop-build-witness.md)
|
||||
- [iNES containers](ines-containers.md)
|
||||
- [Build RL environments with REA](agent-environments-quickstart.md)
|
||||
- [Agent environments from recorded captures](agent-environments.md)
|
||||
- [APK signature schemes](apk-signature.md)
|
||||
- [Apple IPS crash reports](apple-ips.md)
|
||||
- [Static analysis in GitHub Actions](ci-analysis.md)
|
||||
- [Desktop installation directories](desktop-applications.md)
|
||||
- [Flattened devicetree inspection](devicetree.md)
|
||||
- [Electron fuse state](electron-fuses.md)
|
||||
- [ELF note tables](elf-notes.md)
|
||||
- [Erlang BEAM files](erlang-beam.md)
|
||||
- [ESP images](esp-image.md)
|
||||
- [GameCube DOL analysis through Ghidra](ghidra-dol.md)
|
||||
- [PowerPC ELF analysis through Ghidra](ghidra-ppc.md)
|
||||
- [Godot PCK archives](godot-pck.md)
|
||||
- [Static CUDA and HIP code objects](gpu-code-objects.md)
|
||||
- [Intel HEX and S-record images](hex-records.md)
|
||||
- [IL2CPP metadata](il2cpp-metadata.md)
|
||||
- [Static JavaScript route inventory](javascript-route-inventory.md)
|
||||
- [Linux kernel modules](kernel-modules.md)
|
||||
- [Kuna provider](kuna-provider.md)
|
||||
- [Model file declarations](model-artifacts.md)
|
||||
- [Match native functions across builds](native-function-matching.md)
|
||||
- [Node.js single executable applications](node-sea.md)
|
||||
- [PE Authenticode certificate tables](pe-certificates.md)
|
||||
- [PE import and delay-load tables](pe-imports.md)
|
||||
- [PE TLS callbacks and load configuration](pe-load-config.md)
|
||||
- [Python packaged applications](python-packaged-applications.md)
|
||||
- [CPython pyc inspection](python-pyc.md)
|
||||
- [Reconstruction coverage](reconstruction-coverage.md)
|
||||
- [Reverse-engineering tool integrations](reverse-engineering-tools.md)
|
||||
- [Rust binary dependency metadata](rust-binaries.md)
|
||||
- [U-Boot legacy uImage containers](uimage.md)
|
||||
- [UnityFS AssetBundle archives](unityfs.md)
|
||||
@@ -0,0 +1,9 @@
|
||||
# Architectural decision records
|
||||
|
||||
Store one actual decision per `docs/adr/<domain>/<decision-slug>.md`, without a
|
||||
global sequence number. Use meaningful names and the Michael Nygard sections:
|
||||
Status, Context, Decision and Consequences. Link each decision from its owning
|
||||
feature specification.
|
||||
|
||||
See [the authoring guide](../development/documentation.md#feature-lifecycle) for
|
||||
the distinction between specifications, roadmaps and isolated decisions.
|
||||
@@ -11,14 +11,14 @@ with your RL framework to set task goals, check rewards, and run training.
|
||||
|
||||
## Before you start
|
||||
|
||||
Install [REA and its agent integration](installation.md). To record an app,
|
||||
Install [REA and its agent integration](getting-started/installation.md). To record an app,
|
||||
you also need a running test instance and a Chrome-family browser. Choose an
|
||||
instance where the agent is allowed to create, edit, and delete data. REA
|
||||
records the app you provide; you start it and prepare its test data.
|
||||
|
||||
To run the exported environment, install the
|
||||
[AgentEnv framework](https://github.com/scaleapi/agentenv-framework#install)
|
||||
and start Docker. REA's [compatibility check](testing.md#exported-environment-bundles)
|
||||
and start Docker. REA's [compatibility check](development/testing.md#exported-environment-bundles)
|
||||
uses AgentEnv version `0.9.1431` with Python 3.12.
|
||||
|
||||
There are two ways to build an environment: ask your agent to record the app,
|
||||
@@ -52,7 +52,7 @@ work and which need more evidence. The app is used during recording; the
|
||||
exported environment runs from the saved data.
|
||||
|
||||
After your agent exports the folder, skip to
|
||||
[run the environment](#3-run-the-environment). The next section is an
|
||||
[run the environment](#run-the-environment). The next section is an
|
||||
alternative for an existing recording.
|
||||
|
||||
## 2. Or build from a saved recording
|
||||
@@ -91,6 +91,8 @@ A successful build means the folder was created. Check the report to confirm
|
||||
it supports the operations your tasks need. `coverage: null` means the build
|
||||
could not prepare state for this environment and it will use replay.
|
||||
|
||||
<a id="run-the-environment"></a>
|
||||
|
||||
## 3. Run the environment
|
||||
|
||||
Whether your agent exported the folder or you built it from a HAR, run it
|
||||
|
||||
+11
-11
@@ -30,7 +30,7 @@ rea environment-serve manifest.json --evidence capture.json --port 8765
|
||||
```
|
||||
|
||||
The first command inspects the capture; the second projects the
|
||||
[environment manifest](web-network-captures.md#environment-manifest) view from
|
||||
[environment manifest](guides/web/web-network-captures.md#environment-manifest) view from
|
||||
it, where `view.json` wraps the capture Evidence as the inline source:
|
||||
|
||||
```json
|
||||
@@ -163,7 +163,7 @@ at info level; the report is the only output on stdout:
|
||||
|
||||
`coverage` is the state's read views and write plans summarized, and `null`
|
||||
when the state is unavailable and the bundle serves replay. The
|
||||
[environment coverage](web-network-captures.md#environment-coverage) view
|
||||
[environment coverage](guides/web/web-network-captures.md#environment-coverage) view
|
||||
reports the same summary for any capture without building, so an agent can
|
||||
check it after each recording. The view summarizes the state as derived; it
|
||||
does not apply the serve-time admission checks, so for an environment whose
|
||||
@@ -235,7 +235,7 @@ name `export_environment_bundle`; the others name their stage as
|
||||
## From a browser scenario
|
||||
|
||||
The capture can also come from REA itself: a
|
||||
[browser scenario](browser-scenario-contract.md) records a scripted session
|
||||
[browser scenario](guides/web/browser-scenario-contract.md) records a scripted session
|
||||
in a browser REA launches, and its Evidence is a manifest parent like a HAR
|
||||
inspection. Select the `network` event family and response bodies. A replayed
|
||||
reply carries up to 256 KiB of a recorded body, but the scenario keeps at most
|
||||
@@ -321,7 +321,7 @@ declared secret replaced by its redaction marker (a body that redaction had to
|
||||
empty replays no body).
|
||||
|
||||
To record writes, sign in through the UI and then send the application's API
|
||||
calls with [request steps](browser-scenario-contract.md#request-steps): each
|
||||
calls with [request steps](guides/web/browser-scenario-contract.md#request-steps): each
|
||||
sends one request to the start origin through the page's own `fetch`, with the
|
||||
session's cookies, and a header can carry the CSRF cookie or stored token the
|
||||
application's own requests send. A write is served only when the capture shows
|
||||
@@ -481,7 +481,7 @@ captured text without changing the tool names or schema fields clients use.
|
||||
|
||||
Replay answers each call from one recording, so the answers reflect whichever
|
||||
moment of the capture recorded them. The
|
||||
[environment state](web-network-captures.md#environment-state) view extracts
|
||||
[environment state](guides/web/web-network-captures.md#environment-state) view extracts
|
||||
instead the data the capture's reads observed before the first related write:
|
||||
entity types with an identity field, entities with their recorded values,
|
||||
documents for reads that are not entities, and a render plan per read tool,
|
||||
@@ -503,14 +503,14 @@ see [Serve from the state](#serve-from-the-state).
|
||||
|
||||
`--host` and `--port` default to `MCP_HOST` and `MCP_PORT` from the
|
||||
environment, then to `127.0.0.1` and an ephemeral port, exactly as
|
||||
[`rea mcp --http`](cli.md#serve-mcp-over-streamable-http) resolves them. The
|
||||
[`rea mcp --http`](getting-started/cli.md#serve-mcp-over-streamable-http) resolves them. The
|
||||
bound MCP URL is written to stderr as one JSON log line
|
||||
(`"msg":"MCP transport listening"` with `url`); `REA_LOG_LEVEL` overrides that
|
||||
log level. `ENVIRONMENT_NAME` renames the served environment; otherwise the
|
||||
manifest's `name` is used, and a set but blank value is refused as
|
||||
`configuration_invalid` before binding rather than silently falling back. The
|
||||
listener serves one MCP client at a time with the same session, `Host` header
|
||||
and shutdown contract as [transports](mcp-contracts.md#transports) describes.
|
||||
and shutdown contract as [transports](reference/mcp-contracts.md#transports) describes.
|
||||
It runs until SIGINT or SIGTERM, then closes the listener, prints one
|
||||
`{"status":"stopped", …}` document whose `state` member says whether it served
|
||||
from the state, and exits `130` or `143`.
|
||||
@@ -585,7 +585,7 @@ names the method and path template, then what the tool returns, one level deep:
|
||||
`returns a JSON object with fields …`, `returns a JSON array of objects with
|
||||
fields …` or `returns a JSON object whose <member> lists objects with fields …`,
|
||||
where a list is an array of objects found by the
|
||||
[environment state](web-network-captures.md#environment-state)'s list rule (the
|
||||
[environment state](guides/web/web-network-captures.md#environment-state)'s list rule (the
|
||||
root array, or the one array of objects an envelope carries). Field and member
|
||||
names are written as JSON strings, so a captured name cannot read as more of
|
||||
the description; a member name too long to show whole is a quoted prefix marked
|
||||
@@ -641,7 +641,7 @@ rea environment-serve manifest.json --evidence capture.json
|
||||
```
|
||||
|
||||
Before it binds, the server derives the
|
||||
[environment state](web-network-captures.md#environment-state) the capture
|
||||
[environment state](guides/web/web-network-captures.md#environment-state) the capture
|
||||
observed: it runs the `environment-state` view on the capture in-process with
|
||||
the manifest's `template_rules` in the same order, exactly as
|
||||
`inspect-analysis-view` projects it from the same capture, so the state
|
||||
@@ -733,7 +733,7 @@ query model may describe supported paging; an empty later page cannot start
|
||||
returning earlier entities merely because it was empty in the capture.
|
||||
|
||||
`POST`, `PUT`, `PATCH` and `DELETE` tools are served only when the state's
|
||||
[write plan](web-network-captures.md#environment-state) for them is served:
|
||||
[write plan](guides/web/web-network-captures.md#environment-state) for them is served:
|
||||
the capture's later reads confirmed the effect the plan models. Other write
|
||||
tools are not served, so no call claims a change it does not make; each one's
|
||||
plan states why in its `reason`. A served write changes the live state, which
|
||||
@@ -1187,7 +1187,7 @@ read, not that the write had no other effect.
|
||||
## Compatibility verification
|
||||
|
||||
`npm run verify:agentenv:environment` is the hosted `real-agentenv` lane
|
||||
described in [testing](testing.md#exported-environment-bundles). It projects
|
||||
described in [testing](development/testing.md#exported-environment-bundles). It projects
|
||||
the Grafana-shaped source-owned capture through the built CLI, packs the
|
||||
checkout, exports a bundle with `--package-tarball`, runs it with the pinned
|
||||
`agentenv-framework` release on the runner's Docker and requires the smoke task
|
||||
|
||||
+67
-4
@@ -85,9 +85,49 @@ canonical hexadecimal form), `EXC_GUARD` subtypes,
|
||||
pointer-authentication suffixes, and dyld missing-library strings. A report
|
||||
that matches none of those rules is `unclassified`.
|
||||
|
||||
Opened Mach-O and dSYM UUID joins remain unobserved. Symbol names printed
|
||||
inside the report are recorded claims and are not verified. Linux ELF cores
|
||||
use the separate [recorded crash](recorded-crashes.md) workflow.
|
||||
## Joining frames to the crashed Mach-O or dSYM
|
||||
|
||||
Pass `join_path` (`--join-path` in the CLI) to select one local Mach-O
|
||||
executable or dSYM. UUID bytes in the report and the artifact's `LC_UUID` load
|
||||
commands are compared in hexadecimal, so an uppercase `dwarfdump --uuid` value
|
||||
and a lowercase report `uuid` match.
|
||||
|
||||
```bash
|
||||
rea inspect-apple-ips /absolute/path/to/report.ips \
|
||||
--join-path /absolute/path/to/App.app/Contents/MacOS/App --json
|
||||
```
|
||||
|
||||
Shared-cache image sources `S` and `C` remain unjoined: UUID agreement does not
|
||||
establish that a standalone image has the cached layout.
|
||||
|
||||
For a FAT container every slice is examined. An image joins only when exactly
|
||||
one slice has that UUID **and** an architecture that agrees with the report's
|
||||
`arch`; `arm64` and `arm64e` stay distinct, and an all-zero UUID never joins. A
|
||||
UUID match with a different architecture, more than one compatible slice, or a
|
||||
slice without a readable `__TEXT` segment is reported as a rejected image with
|
||||
its reason and stays unjoined rather than being guessed.
|
||||
An unknown UUID in another slice prevents a unique join unless its architecture
|
||||
rules out a match. Missing or unrecognized architecture and unsupported CPU
|
||||
subtypes remain unknown; display-name fallbacks do not establish agreement.
|
||||
The parsed slice facts remain available even when no match can be derived.
|
||||
|
||||
`join.status` is `selected` with the artifact path, SHA-256, byte length, every
|
||||
slice's offset, arch, CPU type and subtype, UUID, and `__TEXT` vmaddr, plus
|
||||
`image_matches`, per-frame results, and join-specific limitations. A joined
|
||||
frame reports `static_address`, the slice `__TEXT` vmaddr plus the frame's
|
||||
recorded `imageOffset`, in decimal and hexadecimal. An unjoined frame reports
|
||||
a reason instead; an unknown image UUID, an absent `imageIndex` row, and a
|
||||
frame without `imageOffset` all stay unjoined rather than treated as aligned.
|
||||
|
||||
An artifact that is not a Mach-O image or FAT container reports
|
||||
`join.status: "unreadable"` with a typed reason and leaves every report fact
|
||||
intact. Symbol names printed inside the report stay recorded claims. Function
|
||||
or symbol lookup at a joined static address, and matching dSYM symbol tables,
|
||||
are not performed by this step.
|
||||
|
||||
Symbol names printed inside the report are recorded claims and are not
|
||||
verified. Linux ELF cores use the separate
|
||||
[recorded crash](guides/native/recorded-crashes.md) workflow.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
@@ -120,4 +160,27 @@ success or truncated integer facts.
|
||||
rea inspect-apple-ips /absolute/path/to/report.ips --max-integer-text-bytes 16777216 --json
|
||||
```
|
||||
|
||||
This workflow does not execute a target, launch atos, or search for dSYMs.
|
||||
`max_join_bytes` (`--max-join-bytes`) independently bounds the join artifact
|
||||
read, defaulting to 64 MiB. This workflow does not execute a target, launch
|
||||
atos, or search for dSYMs.
|
||||
|
||||
## Join admission and failures
|
||||
|
||||
The join uses the shared Mach-O container, slice, command-table and segment
|
||||
readers. Slice extents and `sizeofcmds` bound every identity observation; duplicate
|
||||
UUIDs or malformed commands cannot select the first plausible value. Unreadable
|
||||
join results retain the successfully read artifact's path, SHA-256 and byte count.
|
||||
|
||||
The integer-text allowance spans the report and join, including repeated integer
|
||||
facts and derived static addresses. Reservation precedes derived address
|
||||
expansion. If a selected join read, interpretation or allowance fails, the error
|
||||
retains the completed IPS report. Join read limits and recovery use
|
||||
`max_join_bytes`, even when the report and join paths are identical. Cancellation
|
||||
retains the caller's reason independently of those completed facts.
|
||||
|
||||
When a failure follows a completed join-file read, `partial_observation` retains
|
||||
both the decoded report and a `join_artifact` receipt with the independently
|
||||
observed path, SHA-256 and byte count. Frame rejection reasons reference
|
||||
`join.limitations`; source-sized architecture diagnostics are retained once per
|
||||
image rather than copied into every frame. Universal-image admission includes
|
||||
the shared reader's supported hidden ARM64 row and rejects overlapping slices.
|
||||
File renamed without changes.
+2
-2
@@ -65,14 +65,14 @@ cancellation can still prevent upload.
|
||||
that analysis was complete. A successful operation can retain partial analysis,
|
||||
unknowns, and limitations. Exit zero is not a security verdict, proof of complete
|
||||
coverage, or a policy gate for those findings. Inspect the saved Evidence and
|
||||
coverage before making such a decision. See [output and exit status](cli.md#output-and-exit-status).
|
||||
coverage before making such a decision. See [output and exit status](getting-started/cli.md#output-and-exit-status).
|
||||
|
||||
A nonzero exit can represent invalid input, unavailable tooling, an unsupported
|
||||
host/capability, or another operation failure. Keep the original JSON error (when
|
||||
emitted), stderr, and exit code, and use their category/message to diagnose it.
|
||||
An early startup failure may leave `analysis.json` empty; do not parse that as
|
||||
successful analysis. Select a supported operation or explicitly provision its
|
||||
[documented prerequisites](installation.md); do not silently switch providers,
|
||||
[documented prerequisites](getting-started/installation.md); do not silently switch providers,
|
||||
execute the artifact, or ignore the failure to obtain a green job.
|
||||
|
||||
To exercise the failure path, temporarily set `ARTIFACT_PATH` to
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
This guide explains the runtime settings design for maintainers and developers:
|
||||
who owns each value, when an update takes effect, how providers enforce it, and
|
||||
how to extend the system. The public tool contract is in
|
||||
[MCP contracts](../mcp-contracts.md#editable-analysis-settings); recorded runtime
|
||||
[MCP contracts](../reference/mcp-contracts.md#editable-analysis-settings); recorded runtime
|
||||
checks and their limitations are in the
|
||||
[verification report](../verification/runtime-analysis-settings.md).
|
||||
|
||||
@@ -399,7 +399,7 @@ application points, and resulting behavior. Check that adapters deliver the
|
||||
canonical recovery guidance, with independent assertions for its underlying
|
||||
facts. Avoid freezing prose or deriving all expected values from the same
|
||||
registry used by the implementation; either can hide the wrong failure.
|
||||
See [test design](../testing.md#test-design-and-pruning) for the assertion policy.
|
||||
See [test design](../development/testing.md#test-design-and-pruning) for the assertion policy.
|
||||
|
||||
Runtime checks cover atomic validation, stale writes, reset, runtime isolation,
|
||||
accepted-operation snapshots, and explicit argument precedence. Public MCP
|
||||
|
||||
@@ -47,6 +47,10 @@ computer would not have that entry. An `--executable` runs from
|
||||
the current directory, as it would from a shell, and a relative path to it is
|
||||
resolved there.
|
||||
|
||||
Desktop-entry string values retain literal trailing spaces. For example,
|
||||
`Path=/tmp/workspace ` and `Path=/tmp/workspace\s` name the same directory
|
||||
ending in a space. Use the escaped spelling to make such a suffix visible.
|
||||
|
||||
Before writing anything the command refuses to start if a window of the
|
||||
application is already open, or if the window list cannot be read. A launch
|
||||
beside a running instance can hand off to it, and that instance's unsaved
|
||||
@@ -90,12 +94,20 @@ Progress lines on stderr are JSON, `{"rea_progress": {"phase":
|
||||
"desktop_capture", "message": ...}}`. Those a driver waits on also carry an
|
||||
`event`: `{"kind": "window_open"}` once the window opens; `{"kind":
|
||||
"checkpoint", "name", "trigger", "at_ms", "entries", "changes",
|
||||
"retained_files", "retained_bytes"}` once a checkpoint has been taken, the
|
||||
baseline, `stop` and `exit` included, with the paths walked, the paths
|
||||
changed since the checkpoint before and the files retained; and `{"kind":
|
||||
"checkpoint_refused", "name", "reason"}` for a requested name it refused. A
|
||||
driver that sends `checkpoint <name>` waits for the event naming it rather
|
||||
than for a fixed time.
|
||||
"retained_files", "retained_bytes", "changed_files", "more_changed_files"}`
|
||||
once a checkpoint has been taken, the baseline, `stop` and `exit` included,
|
||||
with the paths walked, the paths changed since the checkpoint before, the
|
||||
files retained, and up to ten of the files (not folders) that changed,
|
||||
home-relative: those under a `--state-path` or absolute `--argument` first,
|
||||
then those the application held open, then those in its state directories,
|
||||
then the rest, and last caches (a folder whose name ends in `cache`, such as
|
||||
`~/.cache`) and WebKit or Chromium storage, each by path, with a count of the
|
||||
rest. An application can rewrite dozens of cache files on a save, and KDE's
|
||||
holds its service cache open, so the saved document would otherwise fall past
|
||||
the ten;
|
||||
and `{"kind": "checkpoint_refused", "name", "reason"}` for a requested name it
|
||||
refused. A driver that sends `checkpoint <name>` waits for the event naming it
|
||||
rather than for a fixed time.
|
||||
|
||||
When the session ends the capture sends SIGTERM to the launched process, its
|
||||
process group and every process that carries the run token, waits up to five
|
||||
@@ -262,8 +274,14 @@ found nowhere are listed in
|
||||
`missing_libraries`, and libraries no package owns in `unpackaged_libraries`.
|
||||
`library_packages_reason` says why the lists are incomplete: the executable is
|
||||
not an ELF image (a launcher script, for example), `ldconfig`, `dpkg-query` or
|
||||
`apt-cache` is missing, a library could not be read or names more than 512
|
||||
libraries, or the walk stopped after 512 libraries.
|
||||
`apt-cache` is missing, `dpkg-query -S` could not tell which package owns a
|
||||
library (it exits 2 rather than 1, which only says no package owns the paths
|
||||
it did not name), a library could not be read or names more than 512
|
||||
libraries, or the walk stopped after 512 libraries. A failed owner query does
|
||||
not list the libraries it covered in `unpackaged_libraries`, since a lookup
|
||||
that could not finish is not proof that no package owns them. Completed batches
|
||||
retain their package and unowned-library facts. Paths containing package-query
|
||||
pattern characters stay unknown unless another candidate identifies an owner.
|
||||
|
||||
A sources file, key or library whose handle REA cannot close fails the capture
|
||||
with the file as its cleanup resource. When the repository check and the
|
||||
@@ -300,16 +318,22 @@ the whole name is compared, so `~/.config/GIMPshop` does not. Dotfiles in the
|
||||
home named after the application (`.<name>rc`, or
|
||||
`.<name>` followed by `-`, `.` or `_`, for a name of three or more characters)
|
||||
that exist at the start join them, since an application may only read such a
|
||||
file during the capture. A `flatpak run` launch is named after its application
|
||||
file during the capture. So does KDE's settings file in the config folder,
|
||||
`<name>rc` such as Tellico's `~/.config/tellicorc`, for each such name of three
|
||||
or more characters, whether or not it exists yet. A `flatpak run` launch is named after its application
|
||||
id rather than the `flatpak` launcher, and adds `~/.var/app/<id>`.
|
||||
|
||||
**Session.** When it started, how long it ran and why it ended; the launched
|
||||
process's exit status; every process seen in the application's tree; every
|
||||
client window with its class pair, titles, owner pid and type, marked when it
|
||||
belongs to the application; when the first application window appeared; the
|
||||
belongs to the application. Titles and class names decode xprop's quoted
|
||||
delimiters, newline and tab escapes, and three-digit octal byte escapes;
|
||||
unsupported escape spellings leave that string unknown rather than inventing
|
||||
text. The session also records when the first application window appeared; the
|
||||
most common class pair of the application's windows, for matching its window
|
||||
later; files the application's processes held open under the walked roots; the first
|
||||
8 KiB of the launched process's stderr; and whether cleanup was verified. Each
|
||||
later; files the application's processes held open under the walked roots; the last
|
||||
8 KiB of the launched process's stderr, where a failing app's last words are,
|
||||
with `stderr_truncated` when earlier output was dropped; and whether cleanup was verified. Each
|
||||
process records whether the capture started it: the launched process, a
|
||||
process carrying the capture's run token, or a descendant of one, even when
|
||||
its environment cannot be read, as for a zombie or a sandboxed renderer.
|
||||
@@ -335,7 +359,9 @@ directory, which are named in the limitations instead; a selected path that is
|
||||
not a directory brings the `-wal` and `-journal` paths beside it, so a database
|
||||
selected on its own is captured with its logs), the state directories
|
||||
as walked (their physical spelling, which differs from the inventory's when one
|
||||
is a symlink), the paths every walk left out (the output folder and
|
||||
is a symlink), the selected paths (each `--state-path` and content-root
|
||||
`--argument` as named, absolute, beside the physical path walked, so a
|
||||
symlinked settings folder keeps what its name means), the paths every walk left out (the output folder and
|
||||
`--exclude` values), and the checkpoints in order: `baseline` before
|
||||
launch, each requested checkpoint, `stop` or `time-limit`, and `exit` after the
|
||||
application has gone. Each checkpoint records how many paths its walk saw,
|
||||
@@ -358,9 +384,14 @@ remaining content budget is not read, unless stored content of the same size
|
||||
could make it a duplicate. Files that could not be
|
||||
retained are listed with the reason: too large, over the content budget,
|
||||
changed since the walk, changed during the read, or unreadable.
|
||||
The baseline also records the paths and types of non-file entries it observed,
|
||||
including symlinks, without following them. This is required to distinguish an
|
||||
unreadable SQLite sidecar from an absent one. Captures made before this field
|
||||
was added must be made again before state inspection, task drafting or export.
|
||||
Directories the application held files open in, but whose starting content was
|
||||
not retained, are listed so a second capture can pass them with
|
||||
`--state-path`.
|
||||
`--state-path`, or `state_paths` on a build computer's `start_build_capture`,
|
||||
and a limitation names them, spelled from `~/` under the home.
|
||||
|
||||
**Limitations.** What the capture could not establish, such as a truncated
|
||||
walk or a missing window.
|
||||
|
||||
@@ -25,13 +25,18 @@ a `.deb` file; see [Applications from a .deb file](#applications-from-a-deb-file
|
||||
`--seed-checkpoint` names the checkpoint whose state seeds the bundle, the
|
||||
baseline by default, and `--end-checkpoint` the one a task must pass on, the
|
||||
capture's last by default; see [The seed checkpoint](#the-seed-checkpoint).
|
||||
`--synthetic-seed` says the seed was made for the task, as a build agent makes
|
||||
it in a [build computer](desktop-build-witness.md), rather than taken from the
|
||||
user's own data; see [A seed made for the task](#a-seed-made-for-the-task).
|
||||
|
||||
The command returns Evidence with operation `export_desktop_application` and
|
||||
predicate type `rea.desktop-application-export`, listing the environment name,
|
||||
the seed and end `checkpoints`, owned paths, seed files, the seeds it
|
||||
rewrote to remove the capture host's name and user (`scrubbed_files`), the
|
||||
bundle files that still hold them (`unscrubbed_files`), and written files,
|
||||
the last three by their path in the bundle. A failed export, cancellation
|
||||
gzip seeds it compressed again only to clear their headers
|
||||
(`recompressed_files`), the bundle files that still hold them
|
||||
(`unscrubbed_files`), and written files, the last four by their path in the
|
||||
bundle. A failed export, cancellation
|
||||
included, removes the bundle it had not yet published, so no partial copy of the
|
||||
user's data remains. If the bundle was published but its output handles could
|
||||
not be closed, the command reports a cleanup error that carries the export
|
||||
@@ -124,6 +129,17 @@ The class declares:
|
||||
desktop entry without `Path`), which a relative argument or program path
|
||||
such as `./app` also needs, and still starts if that folder is missing. The
|
||||
export refuses a capture that saw no application window.
|
||||
- The seed's document, opened at launch, so the app shows it rather than its
|
||||
start screen: when the seed holds exactly one file the state view gives the
|
||||
`document` role, and the desktop entry's `Exec` takes files (a `%f`, `%F`,
|
||||
`%u` or `%U` field code), its path under `$HOME` is appended to the command.
|
||||
A command that already names a document, absolute or from its working
|
||||
directory, as one captured with `--argument <file>` does, is kept as it is;
|
||||
a settings path under the home does not count. A seed with no document launches
|
||||
as captured. With several, no desktop entry or an `Exec` that takes no file,
|
||||
the app launches as captured and the README and the result's limitations say
|
||||
why. A reset
|
||||
relaunches the app, so it opens the document again.
|
||||
- For an Electron application (the capture found its fuse sentinel or a
|
||||
`resources/app.asar`), `--no-sandbox` right after the program unless the
|
||||
command already has it: Chromium's sandbox needs user namespaces the
|
||||
@@ -140,9 +156,11 @@ The class declares:
|
||||
Files the capture recorded under a symlinked state directory's physical
|
||||
spelling are mapped back to the innermost such directory's home spelling,
|
||||
unless that spelling is outside the captured home, as when the home itself is
|
||||
a symbolic link. When two files map to one home path, the export uses the one
|
||||
present before the capture, else the first by path, and a limitation names
|
||||
the other.
|
||||
a symbolic link. When a selected link names an application state directory,
|
||||
the bundle seeds the application's state path and restores the selected
|
||||
alias at boot. Selections nested under that alias are seeded under the same
|
||||
state path. An existing incompatible alias stops setup without replacing it. When two files map to one home path, the export uses the one present
|
||||
before the capture, else the first by path, and a limitation names the other.
|
||||
- Data hooks, because declaring any hook switches off agentenv's default data
|
||||
plane: the class seeds the home once per boot and keeps it as the initial
|
||||
state with `keep_initial`, `data/add` and `data/reset` call agentenv's `add`
|
||||
@@ -155,10 +173,43 @@ retain is not seeded: one in the state view without retained content at that
|
||||
checkpoint, or one the capture omitted (for example too large or past the
|
||||
content budget). The result lists them in `unseeded_files` and the README
|
||||
names them. When the application held files open in folders whose starting
|
||||
content the capture did not retain, a limitation names those folders. The
|
||||
desktop Trash, `~/.local/share/Trash`, is never the application's, so a file
|
||||
the user moved there is neither owned nor seeded, even when a window title
|
||||
names it; a limitation lists the files the Trash held at the seed.
|
||||
content the capture did not retain, a limitation names those folders, spelled
|
||||
from `~/` under the home: a file there is seeded only when the capture
|
||||
retained it, as it does one written during the capture, and the limitation
|
||||
names the seed files there or says there are none. The desktop Trash,
|
||||
`~/.local/share/Trash`, is never the application's, so a file the user moved
|
||||
there is neither owned nor seeded, even when a window title names it; a
|
||||
limitation lists the files the Trash held at the seed.
|
||||
|
||||
Files that changed during the capture outside the owned paths are neither
|
||||
owned nor seeded, so the app starts without what it saved there: MuseScore
|
||||
keeps its settings in `~/.config/MuseScore`, which its name rules miss, and
|
||||
showed its first-run wizard on every boot. A limitation and the README name
|
||||
those folders, leaving out desktop services' files, each collapsed to its
|
||||
folder in `~/.config`, `~/.local/share`, `~/.local/state` or `~/.local`, the
|
||||
hidden folder of the home it lies in, or else its own folder, up to eight and
|
||||
a count of the rest. Capture again naming them with `--state-path`, or
|
||||
`state_paths` on a build computer, to own them.
|
||||
|
||||
Lock files the app holds while it runs are left out of the seed: a copied one
|
||||
makes the app find its profile or document in use, and a LibreOffice Calc
|
||||
bundle whose seed held its profile's `.lock` showed no window at boot. They
|
||||
are `lockfile`, `lock`, `.lock`, `.parentlock`, `parent.lock` and
|
||||
`SingletonLock` anywhere, LibreOffice's document lock `.~lock.<name>#`, and
|
||||
`*.lock` or `*.lck` directly in one of the application's state directories.
|
||||
Elsewhere such a file may be a project's own, such as `Cargo.lock` or
|
||||
`yarn.lock`, which pin dependencies, and is seeded, even under a folder whose
|
||||
name starts with a dot. A file the state view makes a document, or one named
|
||||
itself by `--state-path` or an absolute `--argument`, is never left out,
|
||||
whatever its name. A limitation and the README list them, up to
|
||||
eight and a count, after "Left out of the seed". They stay under the owned
|
||||
paths, so `data/get` returns the lock the running app holds, and `data/reset`
|
||||
restores the seed without them. Other seed files the app keeps for its own
|
||||
running are seeded as captured and named, collapsed to the folder that holds
|
||||
them: WebKit or Chromium storage (such as `hsts-storage.sqlite`, `storage/`,
|
||||
`mediakeys/`, `Local Storage/`, `IndexedDB/`, `Cookies`), which may hold the
|
||||
app's own data, and caches (a folder whose name ends in `cache`); a stale one
|
||||
can change how the app starts.
|
||||
|
||||
The application's dconf keys at the seed, if any, are written once when the
|
||||
app first starts, also for an application that owns no files, and the class adds
|
||||
@@ -168,7 +219,11 @@ existing user database through a `file-db:` profile, then runs `dconf compile`
|
||||
on that dump and the captured keys, in that name order so the captured keys
|
||||
win, and replaces `~/.config/dconf/user`. If that fails, the server prints a
|
||||
one-line warning and the app starts without the captured keys. `data/reset` does
|
||||
not restore them.
|
||||
not restore them. No file of the bundle holds them, so `data/get` does not
|
||||
return them and no task check reads them; a draft whose only change between
|
||||
its checkpoints is to the application's dconf keys says so with
|
||||
`uncheckable_changes`, and one whose dconf database changed but could not be
|
||||
read says so with `unreadable_changes`.
|
||||
|
||||
## The seed checkpoint
|
||||
|
||||
@@ -185,6 +240,16 @@ The export refuses a name the capture does not hold exactly once, and an end
|
||||
checkpoint taken before the seed checkpoint; `inspect-desktop-application-state`
|
||||
lists the names in `capture.checkpoints`.
|
||||
|
||||
## A seed made for the task
|
||||
|
||||
By default the seed is the user's real data: the README and the result's
|
||||
limitations say to keep the bundle local and not publish it. With
|
||||
`--synthetic-seed` they say instead that the seed was made for the task, and
|
||||
to read `envs/<name>/seed/` before publishing the bundle; the export cannot
|
||||
tell the two apart, so the flag is the caller's word. `export_build_environment`
|
||||
passes it, since the building agent makes the seed in the build computer. The
|
||||
Evidence records it as `synthetic_seed`.
|
||||
|
||||
## Host name and user
|
||||
|
||||
A seed can hold the capture host's name and the user's: Geany saved its mail
|
||||
@@ -228,6 +293,26 @@ export removes them from what the bundle ships:
|
||||
boot, as it did the captured home before. The replacements read as the
|
||||
computer's own: its user is `user`, with its home in `/home/user`, and
|
||||
`localhost` is the name every host has for itself.
|
||||
- A gzip-compressed seed, such as a Gnumeric workbook, is decompressed, up to
|
||||
256 MiB, scrubbed as the format the state view read its document as, and
|
||||
compressed again whether or not its document changed, so no file name,
|
||||
comment or time its header held ships: with no file name, comment or extra
|
||||
field, modification time 0 and the operating system unknown, so the same
|
||||
document gives the same bytes on every host. It is deflated at the fastest
|
||||
level, or stored when deflating would make it expand more than the 100 times
|
||||
a view reads, so a seed that read still reads. It is listed in
|
||||
`scrubbed_files` when its document changed, and otherwise in
|
||||
`recompressed_files`, which the README counts rather than lists, so the
|
||||
example and template files an app copies on first run do not bury the
|
||||
document scrubbed; one already in that form ships as captured. The class copies it at
|
||||
boot as it is, so the home it holds stays `/home/user`. One that does not
|
||||
decompress ships as captured, its bytes searched, and one the state view did
|
||||
not read is only searched. One whose document needs no edit but a member of
|
||||
which has an extra field, where BGZF (`.vcf.gz`, `.bam`) and dictzip
|
||||
(`.dict.dz`) files index their blocks, also ships as captured, its bytes
|
||||
searched, so its blocks stay where its index says; one whose document
|
||||
changed is still compressed again as one member, losing them, as the
|
||||
export's limitation says.
|
||||
- Binary files, SQLite databases among them, and text files over 256 MiB are
|
||||
copied as captured. Then every file the bundle ships, the class module with
|
||||
its dconf keys and the README included, is searched by a looser rule than
|
||||
@@ -294,6 +379,39 @@ declared vendor repository installs the package already; when the URL is not
|
||||
written as `http://` or `https://` or holds a user name or password; and when
|
||||
the file is built for an architecture other than `amd64`, `arm64` or `all`.
|
||||
|
||||
## Grading once the app has saved
|
||||
|
||||
A task's verifier, `artifacts/<task>-check/verify.py`, grades the app's files
|
||||
only once they have settled, because an app can save on its own timer after the
|
||||
last change. Gnote saves a note 4 s after the last key, so a read taken as
|
||||
soon as the agent stops finds the text on screen but not yet in the file. The
|
||||
verifier reads the app's `data/get` every 0.5 s. It compares each file's bytes
|
||||
between reads by their SHA-256, as `data/get` returns them, and grades once
|
||||
every file has held for 3 s. The 3 s count from when a read returned the
|
||||
current bytes, not when it began, so a slow read that brings a change late
|
||||
does not count its own run as quiet. 15 s after the first read began, the
|
||||
bound, the verifier grades the last completed read: no read starts at or
|
||||
after the bound, and a read still running then is cut. Each result records
|
||||
whether the files settled in `settled`, and whether the bound cut a read in
|
||||
`read_cut`.
|
||||
|
||||
The window has a cost and a limit:
|
||||
|
||||
- An app whose files do not change during the check, such as one that saved
|
||||
at once, is graded 3 s after the first read returns.
|
||||
- A save that lands more than 3 s after the first read returns is still
|
||||
missed. An app that saves 4 s after the last key is caught only when the
|
||||
agent stops at least a second after that key.
|
||||
- Files the app rewrites more often than every 3 s, such as a log, never
|
||||
settle, so every check waits until the bound.
|
||||
- The bound counts the reads too, so a slow `data/get` ends the check at
|
||||
15 s. Only the first read, which every grade needs, runs to its own
|
||||
timeout.
|
||||
|
||||
The bound and window are `SETTLE_BOUND_S` and `SETTLE_WINDOW_S` in the
|
||||
verifier. `check_build_task` waits the same way before it grades each
|
||||
witness stage; see [witnessing](desktop-build-witness.md#witness).
|
||||
|
||||
## Typed views
|
||||
|
||||
The views follow the [state view](desktop-application-state.md)'s formats and
|
||||
@@ -308,10 +426,13 @@ as their entries, read with Python's `zipfile` from the file in place, with
|
||||
REA's entry, size, compression ratio and archive limits and its wording for an
|
||||
entry it does not read. The module reads the central directory itself, as REA
|
||||
does, and shows `zipfile` only the records it lists, reading each entry in
|
||||
bounded chunks no further than a byte past its declared size. A JSON file
|
||||
bounded chunks no further than a byte past its declared size. A gzip file is
|
||||
the view of the document inside it, with `"compression": "gzip"` beside its
|
||||
format, decompressed with Python's `zlib` within the same entry size and ratio
|
||||
limits, its members joined as REA joins them. A JSON file
|
||||
holding a number JavaScript cannot read exactly, such as an integer above 2^53,
|
||||
or nested more than 500 levels deep, gets an `error` instead of a view, as in
|
||||
REA, while text that is not one JSON
|
||||
or whose retained value nests more than 500 levels deep, gets an `error` instead of a view, as in
|
||||
REA. Duplicate keys keep their last value before the depth check. Text that is not one JSON
|
||||
document, such as JSON Lines, stays text. Format detection follows REA's
|
||||
rules. Files larger than 64 MiB get an `error` instead of a view
|
||||
and are not read. XML is read with Python's `expat` twice: with namespace
|
||||
@@ -337,6 +458,7 @@ when a DOCTYPE names a DTD. Known differences remain:
|
||||
and then gives the file an `error`, and so does a table or column name that
|
||||
is not UTF-8.
|
||||
|
||||
The seed is the user's real data. Keep the bundle local and do not publish it.
|
||||
Unless it was [made for the task](#a-seed-made-for-the-task), the seed is the
|
||||
user's real data. Keep the bundle local and do not publish it.
|
||||
The class was checked against agentenv-framework 0.9.1431 with
|
||||
`python -m agentenv_protocol.computer._declare` and `agent-env run --dry-run`.
|
||||
@@ -40,7 +40,16 @@ The role follows from the reasons, in this order: `shared_desktop` for a file
|
||||
in the desktop Trash, which the user deleted, whatever else names it;
|
||||
`application_state` for application keys in dconf, or a state directory outside shared desktop
|
||||
locations; `document` for a file named in a window title or selected by the
|
||||
caller, even if the application holds it open; `application_state` for another
|
||||
caller, even if the application holds it open, except that a selected file
|
||||
under a hidden folder of the home, such as `~/.config/MuseScore`, a dotfile
|
||||
there, or a lock an application holds, such as LibreOffice's `.~lock.<name>#`
|
||||
beside a document, is `application_state`, judged by the path as the caller
|
||||
named it, so a file reached through `~/.config/MuseScore` stays the application's
|
||||
when that folder is a link to `~/settings/MuseScore`; the innermost selected
|
||||
path holding a file decides, so a score selected itself inside the link's
|
||||
target keeps its own name and is a document (a capture written before it
|
||||
recorded selected paths is judged by their physical spelling);
|
||||
`application_state` for another
|
||||
open file outside shared locations; `shared_desktop` for other files in shared
|
||||
locations; `unrelated` otherwise. A window title names a file only when no
|
||||
other file name character adjoins the name, so `day.txt` does not match
|
||||
@@ -75,6 +84,9 @@ whether the file was present, the SHA-256 of its retained bytes, and a view:
|
||||
| `text` | Other UTF-8 text | Lines, up to 5,000 |
|
||||
| `binary` | NUL bytes or invalid UTF-8 | None |
|
||||
|
||||
A gzip file is read as the document inside it; see
|
||||
[compressed documents](#compressed-documents).
|
||||
|
||||
A JSON value holding a number JavaScript would round, such as an integer above
|
||||
2^53, is not read rather than shown rounded.
|
||||
|
||||
@@ -128,7 +140,15 @@ could misstate its committed rows. The capture records them under its content
|
||||
roots, which include both beside a database selected on its own, when its
|
||||
baseline walk listed every directory, read every path, entered no other
|
||||
device, did not stop early and recorded what it left out, and wherever they change; an excluded log, and any elsewhere, is
|
||||
unknown, since an unchanged file and a missing one look alike. A table
|
||||
unknown, since an unchanged file and a missing one look alike. After an
|
||||
incomplete checkpoint, a database or sidecar without an explicit
|
||||
later change remains unconfirmed even if a later walk completes. REA does not
|
||||
combine that older file with a newly recorded member of the SQLite set. The
|
||||
historical versions remain listed; the affected SQLite view has a `view_error`.
|
||||
A baseline non-file at a sidecar path, or a non-directory ancestor, cannot
|
||||
establish an absent file. Captures without the required baseline non-file
|
||||
inventory must be made again before inspection.
|
||||
A table
|
||||
that cannot be read keeps its `error` in place of its rows, and changes to that
|
||||
database are marked incomplete. dconf
|
||||
databases are read with `dconf dump /` against a private file profile, so the
|
||||
@@ -185,6 +205,37 @@ so an archive of hundreds of thousands of entries costs no more to read
|
||||
than one of a thousand. An archive whose central directory cannot be read has a
|
||||
`view_error` of its own.
|
||||
|
||||
## Compressed documents
|
||||
|
||||
Gnumeric's `.gnumeric`, Dia's `.dia`, Xournal++'s `.xopp`, GnuCash's default
|
||||
book and Inkscape's `.svgz` are XML compressed with gzip. A file that starts
|
||||
with gzip's magic bytes, `1f 8b 08`, whatever its name, is read as the
|
||||
document inside it: its members joined, then given a format and view by the
|
||||
rules above under the file's own name, so a pointer or check into it is
|
||||
written exactly as for the same document uncompressed, and the task draft is
|
||||
the same. The version records the compression beside the format:
|
||||
|
||||
```json
|
||||
{
|
||||
"format": "xml",
|
||||
"compression": "gzip",
|
||||
"view": {
|
||||
"root": { "name": "gnm:Workbook", "attributes": {}, "children": [] },
|
||||
"truncated": false
|
||||
},
|
||||
"view_error": null
|
||||
}
|
||||
```
|
||||
|
||||
The document is read only when it is at most 16 MiB and at most 100 times the
|
||||
file's size, an archive entry's limits, so decompressing stops there; past
|
||||
them, or when the stream is damaged or cut short, the version has `format`
|
||||
null and a `view_error`, and a check into it is undecided. A SQLite or dconf
|
||||
database inside keeps its format and has a `view_error`, an archive inside is
|
||||
read as an archive, and another gzip stream inside is binary. A gzip file
|
||||
inside an archive reads as binary. Other compression, such as xz, Zstandard
|
||||
or bzip2, is not read: such a file is binary.
|
||||
|
||||
## Kinds of change
|
||||
|
||||
Between consecutive versions a change is `created`, `deleted`, or a
|
||||
|
||||
@@ -42,9 +42,31 @@ operation `describe_desktop_application_task` and predicate type
|
||||
database is compared by its rows, since its hash leaves out the `-wal`
|
||||
file. Text changes list each line
|
||||
once and add `line_counts`, the lines found at both ends whose number of
|
||||
occurrences changed. Views appear only for the files the suggestions cover,
|
||||
with arrays past 200 items and strings past 2,000 characters cut
|
||||
occurrences changed. An XML file's change names its members by the
|
||||
[selectors](#pointers-and-selectors) checks use, as an archive's already
|
||||
does, and by position only where nothing names a member or where only the
|
||||
members' order changed. Views appear only for the files the suggestions
|
||||
cover, with arrays past 200 items and strings past 2,000 characters cut
|
||||
(`view_cut`).
|
||||
- `values`, in each of those files: the values its change added, changed and
|
||||
removed, each with the `pointer` a check names it by, its `kind` (`added`,
|
||||
`changed` or `removed`), and `before` and `after`: the scalar, an element as
|
||||
compact XML with the text the XML reader kept, spaces between runs included,
|
||||
or a JSON value as compact JSON, cut at 600 characters, and null at the end
|
||||
that lacks it. A file created or deleted lists what its one end holds,
|
||||
`added` or `removed`: an archive's entries, an XML file's root element, a
|
||||
JSON file's members or a key file's keys, each whole once. A value only
|
||||
position reaches has `note: "by_position"`, and its pointer cannot go into a
|
||||
check; noise an app writes as it saves has `view_state`, `renumbered`,
|
||||
`volatile`, `timestamp` or `upkeep` (see `task`). `refers_to` names up to
|
||||
three other elements a value equals the `key` or `id` of, with the
|
||||
`attribute` holding it, as HomeBank's `category="44"` names
|
||||
`<cat key="44" name="Groceries"/>`; where several elements share that key,
|
||||
the one whose tag shares the attribute's stem, as `payee` and `<pay>`. What a check can
|
||||
name comes first, then what only position reaches, then noise. A file lists
|
||||
at most 20 values and 8 KB, the draft 24 KB, and `values_cut` says when a
|
||||
limit left some out. Values cover XML, archives, JSON and key files; a text
|
||||
or SQLite file's change and suggestions already carry its lines and rows.
|
||||
- `task`: a draft with the name `change`, a placeholder prompt the export
|
||||
refuses, and suggested checks derived from the net change of the files with
|
||||
role `document`, or of the app's own state files when no document changed.
|
||||
@@ -56,21 +78,151 @@ operation `describe_desktop_application_task` and predicate type
|
||||
and the JSON, key file and XML views of a zip archive's entries, gain checks
|
||||
by [selectors](#pointers-and-selectors) and never through an element by
|
||||
position: in XML, first [`text_equals`](#whole-text) for each element whose
|
||||
text changed, then an element added whole that it exists, one removed whole
|
||||
that it is absent, then values changed, added and removed, an entry or a
|
||||
JSON value added whole through its members, and an empty array or object as
|
||||
it is. The text check names the paragraph rather than a run inside it: it
|
||||
goes up from an element sitting in its parent's text, and from one named by
|
||||
its tag or position alone to the nearest ancestor named by an attribute, as
|
||||
AbiWord's `p` by its `xid`; the text nodes and runs inside it get no other
|
||||
check, but an element holding no text that is added or removed there, such
|
||||
as an image or a line break, keeps its own, since the text check never
|
||||
reads it. Whitespace an app lays out between elements is not checked, and
|
||||
values that look like a time the app stamps, in ISO 8601 or as C's
|
||||
`asctime` writes it (`Thu Nov 5 09:20:31 2026`), are left out.
|
||||
text changed, then elements added or removed whole, then values changed,
|
||||
added and removed, an entry or a JSON value added whole through its
|
||||
members, and an empty array or object as it is.
|
||||
- A selector names a member by its tag, then by its identifiers (`name`,
|
||||
`id`, `xid`, `xml:id`), then by one other attribute, a name-like key such
|
||||
as Scribus's `ANNAME` or `inkscape:label`, a worded value or an integer of
|
||||
up to five digits first, then by two such attributes together, as
|
||||
Gnumeric's cells by `[@Col=3][@Row=2]`, and last by a coordinate, a long
|
||||
number or a token, such as `XPOS` or `ItemID`, or an attribute naming
|
||||
view state, such as which layer is `selected`. A pair counts every
|
||||
member holding both its values, whichever attributes that member ranks
|
||||
first. An element with identifiers is named by those alone. The selector
|
||||
must name the member alone at both ends, with the same values. An
|
||||
element whose one identifier changed, at its place among its tag's
|
||||
members, with every other attribute and its children alike, is that
|
||||
element renamed, as a MyPaint layer renamed from `Untitled` to `Sun`: it
|
||||
is named by its first other attribute naming it alone at both ends, as
|
||||
`[@src=data/layer-00.png]`, so the rename reads as its `name` changed,
|
||||
and the old name gets a check that it names nothing, unless its change
|
||||
is noise, as an id the app renumbered.
|
||||
An identifier the app numbers by position names nothing: where the
|
||||
members of a tag hold it as 1..N (or 0..N-1) in document order at both
|
||||
ends, members were inserted or removed, and every member another
|
||||
attribute names alone at both ends kept its number or moved it the way
|
||||
the count did, one at least, as Planner's task `id` after a task is
|
||||
inserted, members are paired by their other attributes, so an insertion
|
||||
reads as one task added. A value two members swap, or an id appended at
|
||||
the end, as Tellico's next `<entry id="4">`, leaves the ids identity.
|
||||
- The text check names the paragraph rather than a run inside it: it goes up
|
||||
from an element sitting in its parent's text, and from one named by its
|
||||
tag or position alone to the nearest ancestor named by an attribute, as
|
||||
AbiWord's `p` by its `xid`; where no attribute names one, to the nearest
|
||||
ancestor within three levels its tag names with no step by position, as
|
||||
MuseScore's `VBox` around untitled `<Text>` elements; and where only
|
||||
position reaches the element, to the ancestor above the outermost step by
|
||||
position, by an attribute of its own that names it alone where one does,
|
||||
as an ODS sheet's `table:table[@table:name=Q1 Sales]` above its rows. The
|
||||
text nodes and runs inside it get no other check, but an element holding
|
||||
no text that is added or removed there, such as an image or a line break,
|
||||
keeps its own, since the text check never reads it. A decimal that is an
|
||||
element's only text, such as a spreadsheet cell's, is checked by its
|
||||
number instead. Free text that gains a line, such as a shopping list,
|
||||
uses `text_equals` on the whole text: the current XML checks cannot
|
||||
compare an unstructured line as a whole item. This can reject a correct
|
||||
edit that puts the item elsewhere or changes spacing. A record added
|
||||
or removed whole, an element holding only elements, its fields, such as
|
||||
Tellico's `<entry>` or a record of repeated `<field>` elements, never
|
||||
makes the list holding records of its kind a check, whose text would hold
|
||||
the records the edit left alone, except a record removed whole that only
|
||||
position names, whose absence only the list's text shows. Text made of
|
||||
runs is no record: an element whose tag names a paragraph or a piece of
|
||||
text (`p`, Writer's `text:p` and `text:h`, `h1` to `h6`, `li`, `para`,
|
||||
SVG's `text` and `tspan`, a `span` or an `a`), or whose runs split a
|
||||
sentence at a space, as `Meet ` and a linked `Monday`. Nor does an
|
||||
element holding a date the app stamps in parts take a text check.
|
||||
- An element added to a list, where another element of its tag is at either
|
||||
end, gets a `value_equals` for each of its attributes, best ranked first,
|
||||
at most six, leaving out its selector's attributes, identifiers, times,
|
||||
volatile values and view state, as HomeBank's new `<ope>` gets its
|
||||
`amount`, `category` and `payee`. An element whose other attributes, two
|
||||
or more, a like sibling holds every one of, as a new Planner task copies
|
||||
its neighbour's defaults, and any other element added whole, get a check
|
||||
that it exists. A record added to a list that a selector names, as
|
||||
Tellico's `<entry id="4">`, gets a `text_equals` for each field, at most
|
||||
five, each by its selector among the record's fields, as `[name=title]`,
|
||||
leaving out a field repeating the record's identifier, a date the app
|
||||
stamps in parts, and blank text or times. A record only position names,
|
||||
such as Osmo's `<record>` of fields, also gets a `text_contains` for each
|
||||
new field of three or more characters, at most five, at the nearest
|
||||
ancestor a check can name, each absent from that ancestor's text at the
|
||||
seed.
|
||||
- A decimal written as text, such as `146.83`, is suggested as a number
|
||||
with `tolerance: 0.001`, unless the seed's value is that close too.
|
||||
- Noise leaves the suggestions when the file's change holds anything
|
||||
else, a change only position reaches included: view state, which a tag
|
||||
or attribute on the way names (the cursor, a selection, scrolling, zoom,
|
||||
the viewport, windows, splitters, Inkscape's `namedview`, view and
|
||||
configuration settings, the printer, a save's history, edit time,
|
||||
editing duration and cycles, last-saved time, the generator and
|
||||
document statistics), or the value of a name-like attribute or `key` on
|
||||
the way, when it is one token of several words, as LibreOffice's
|
||||
`config:config-item[@config:name=CursorPositionX]` inside
|
||||
`[@config:name=ooo:view-settings]`; an attribute ending in `ID` or `Id`,
|
||||
or an `rsid`, that the app renumbered, with everything else in its
|
||||
element, as Gnumeric empties a formula cell whose shared expression it
|
||||
renumbers, and an identifier the app numbers by position; volatile
|
||||
values, UUIDs and epoch times, and durations and counts under a
|
||||
document's metadata; times the app stamps, also as a date written in
|
||||
parts whose tag, or one it sits in, names when the app made, changed or
|
||||
saved something, as Tellico's `<cdate>` of `<year>`, `<month>` and
|
||||
`<day>` (`cdate`, `mdate`, `created`, `modified`, `saved`, `updated`),
|
||||
which no check ever reads, while a date a user enters in parts, as a
|
||||
birthday, is an edit like any other; and `upkeep`, the
|
||||
`loext:tab-stop-distance` attributes LibreOffice fills in `styles.xml`
|
||||
while another archive entry holds an edit. However much noise
|
||||
comes first, it never takes a check's place. When the change holds
|
||||
nothing else, the checks stay and a note flags them: up to three in a
|
||||
document, and as many as fit in the app's own state, where a view
|
||||
setting may be the task.
|
||||
- Whitespace an app lays out between elements is not checked, and values
|
||||
that look like a time the app stamps, in ISO 8601, as C's `asctime`
|
||||
writes it (`Thu Nov 5 09:20:31 2026`) or as a time of day to the
|
||||
second (`05:16:21.675302540`), are left out; noise never makes its
|
||||
ancestor's whole text a check.
|
||||
- `guards`: checks an author may add to show the edit left the rest alone,
|
||||
kept out of `task.checks`, with ids `guard-1` and on: for each suggested
|
||||
`value_equals` or `text_equals` on a member of a list, a field on up to
|
||||
two like siblings, nearest first, at its seed value, which the end holds
|
||||
too: the check's own field where like siblings hold different values in
|
||||
it, and otherwise one that varies among them, as Planner's `work` rather
|
||||
than the `type="normal"` every task shares; never through a sibling only
|
||||
position or a renumbered id pairs. A text file gets a `lines_present` of the
|
||||
unchanged list items beside its first new line with the same marker, as
|
||||
Zim's other `[ ]` action items, or else its nearest lines with words in
|
||||
them. At most four a file. They pass on the seed, which the export allows,
|
||||
since one check failing there is enough.
|
||||
- `notes`: why `files` is empty, or why a file's suggestions are thin. Each
|
||||
note has a `code` and a `message`. For a draft with no files: `no_change`
|
||||
when no file under the home changed between the two checkpoints and nor
|
||||
did the application's dconf keys; `unowned_changes` when files changed but
|
||||
none under the owned paths, with up to five of them in `files`, each with
|
||||
its home path and role (desktop services' files last), and how many more
|
||||
in `more`; `uncheckable_changes` when the application's keys in a dconf
|
||||
database changed, with the database in `files`: no check reads dconf, and
|
||||
the export only writes the keys as they were at the seed checkpoint, so
|
||||
make the task's change one the app saves in a file; `unreadable_changes`
|
||||
when a dconf database changed but REA could not read it, with the read
|
||||
failure in `error` (install `dconf-cli` or set `REA_DCONF_COMMAND` when it
|
||||
is missing), since whose keys changed is then unknown; and `no_document`
|
||||
when no file has the document role, as when no window title shows the
|
||||
file's name. A capture again with `--state-path` naming the file, or
|
||||
`state_paths` on a build computer's `start_build_capture`, makes it the
|
||||
app's. For a drafted file, named in `file`: `by_position` when
|
||||
changes reach their element only by position, the tags no attribute names
|
||||
alone in `elements`, or when only the elements' order changed;
|
||||
`view_state_only` when every change is noise, the checks kept in
|
||||
`pointers`; `long_text` when an element's text changed past the 2,000
|
||||
characters a text check compares, the elements in `pointers`; `cut_view`
|
||||
when the views hold only part of the file; and `unreadable_view` when no
|
||||
check can read it, as a document REA reads as binary.
|
||||
|
||||
The suggestions are a starting point. Keep the ones that say what the user
|
||||
did; drop the ones that only follow from how the app saves its file. A LibreCAD
|
||||
did; drop the ones that only follow from how the app saves its file. Read
|
||||
`values` for what changed and its pointers, and `refers_to` for what a number
|
||||
stands for, before writing the prompt and any check of your own. A LibreCAD
|
||||
capture that added four holes to a drawing rewrote it from DXF R12 to DXF 2007,
|
||||
so most of its lines changed; the draft suggests counts of `SECTION`, `ENDSEC`
|
||||
and `CIRCLE`, and only `CIRCLE` going from 5 to 9 is the user's change.
|
||||
@@ -129,7 +281,9 @@ The rules both evaluators follow:
|
||||
`{"groups": {"GROUP": {"KEY": "VALUE"}}}`, so a setting is
|
||||
`/groups/GROUP/KEY`; XML as `{"root": {"name", "attributes", "children"}}`;
|
||||
SQLite as `{"tables": {"TABLE": {"columns", "rows"}}}`; a zip archive as
|
||||
`{"entries": [{"name", "format", "view", …}]}`.
|
||||
`{"entries": [{"name", "format", "view", …}]}`; a gzip file, such as a
|
||||
Gnumeric `.gnumeric`, as the document inside it, so its pointers are those
|
||||
of the same document uncompressed.
|
||||
- With `tolerance`, a non-negative number, `value` must be a number, and the
|
||||
value found passes when it is a number, or a string that is a decimal
|
||||
numeral such as `"5.0000000000000000"`, at most `tolerance` from `value`.
|
||||
@@ -141,7 +295,10 @@ The rules both evaluators follow:
|
||||
- A check decided by what a view leaves out (`lines_absent`, `value_absent`,
|
||||
`row_absent`, the counts, `value_equals` of a whole object or array, and
|
||||
the text checks of an element) fails when that view is truncated; a check
|
||||
satisfied by what the view holds is decided on it.
|
||||
satisfied by what the view holds is decided on it. An element's text is not:
|
||||
the reader may have dropped text from between the runs it kept, so
|
||||
`text_contains` fails on a truncated view even where the kept runs hold its
|
||||
value. A text node or attribute value is whole, and decided.
|
||||
|
||||
The export refuses, naming the check, a file outside the owned paths, a file
|
||||
spelled with a leading slash, `.` or `..`, a pointer into a file that is text
|
||||
@@ -319,7 +476,10 @@ The bundle then holds, besides the app and `tasks/smoke.json`:
|
||||
|
||||
The verifier finds the app among the computer's child environments, calls its
|
||||
`data/get` under the run's grant of the computer's control token, and reads
|
||||
the `state` data part. It raises when the app cannot be reached, so the run
|
||||
the `state` data part. It reads again until the app's files settle, as
|
||||
[grading once the app has saved](desktop-application-export.md#grading-once-the-app-has-saved)
|
||||
describes, and each result's `settled` says whether they did, and `read_cut`
|
||||
whether the bound cut a read still running. It raises when the app cannot be reached, so the run
|
||||
fails rather than scoring the agent. The README lists the task, its prompt, its
|
||||
checks and the recipe below.
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ agent's computer-use actions to it through three MCP tools:
|
||||
The tools are MCP-only, like the debugger sessions: the computer lives as long
|
||||
as the REA MCP server that started it, or until it is closed. Capturing the
|
||||
app, exporting its bundle and witnessing the task on such a computer are in
|
||||
[Building and witnessing an environment](desktop-build-witness.md).
|
||||
[Building and witnessing an environment](desktop-build-witness.md), and REA's
|
||||
skill for doing all of it from a request is
|
||||
[desktop builds](https://github.com/morluto/rea/blob/main/.agents/skills/reverse-engineer-anything/references/desktop-build.md).
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -43,9 +45,11 @@ From a request, REA renders a bundle in a private temporary folder: a computer
|
||||
app on the `ubuntu-24.04` base with the `reference` driver that installs the
|
||||
app, opens it on demand with `gtk-launch <desktop entry>` from the computer
|
||||
user's home, so its open and save dialogs start there rather than in the
|
||||
framework's folder for the app, and keeps no seed and no data hooks. The app is not open when the computer starts: agentenv lists it
|
||||
in the desktop's Applications menu under Other by the environment's name, such
|
||||
as `mousepad`, and that entry launches it through the app's server.
|
||||
framework's folder for the app, and keeps no seed and no data hooks. The app is not open when the computer starts:
|
||||
`start_build_capture` opens it under REA's capture. When no capture is under
|
||||
way, open it from the desktop's Applications menu, where agentenv lists it
|
||||
under Other by the environment's name, such as `mousepad`; that entry launches
|
||||
it through the app's server.
|
||||
|
||||
When the app is Electron, set `electron` to true. The install rewrites that
|
||||
desktop entry's command with the same policy an export uses: `--no-sandbox`
|
||||
@@ -94,6 +98,10 @@ in the folder and its files stay as they were shared.
|
||||
REA runs the deploy with `run_bundle(keep=True, emulate=False)` on the local
|
||||
sandbox provider, so only the host's own architecture is built. The first start
|
||||
of a bundle builds its image and can take minutes; later starts reuse it.
|
||||
agentenv makes a start wait while another agentenv run on this host writes its
|
||||
bundle's ids, so starts at the same time wait for each other, several minutes
|
||||
when a few run together; the progress line then says it is waiting for another
|
||||
agent-env run to finish writing this bundle's ids.
|
||||
While it waits, REA sends an MCP progress notification every five seconds with
|
||||
agentenv's latest line, so a client that resets its request timeout on
|
||||
progress keeps waiting. REA then waits until the computer's readiness checks
|
||||
|
||||
+128
-23
@@ -10,7 +10,7 @@ grades the witness with the same checks the exported verifier runs.
|
||||
| Tool | What it does |
|
||||
| -------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| `start_build_capture` | Downloads the package lists as the computer's user and launches the app under REA's capture |
|
||||
| `mark_build_checkpoint` | Takes a named checkpoint and returns the capture's acknowledgement with its counts |
|
||||
| `mark_build_checkpoint` | Takes a named checkpoint and returns the capture's counts and the files that changed |
|
||||
| `stop_build_capture` | Stops the capture and returns its checkpoints and the task draft between `seed` and `end` |
|
||||
| `export_build_environment` | Exports the bundle with the agent's task inside the computer and copies it to a folder here |
|
||||
| `check_build_task` | Grades a task against the app's live state; with a `stage`, files the check in the witness |
|
||||
@@ -18,10 +18,19 @@ grades the witness with the same checks the exported verifier runs.
|
||||
Like the computer tools, these are MCP-only and act on a `computer_id` from
|
||||
`start_build_computer`.
|
||||
|
||||
REA's skill walks an agent from a request such as "build me an Inkscape
|
||||
environment where the agent changes a poster's headline" to a witnessed
|
||||
bundle with these tools: the questions it asks first, when it stops for the
|
||||
person, the install, the seed, the task, the witness and its final report.
|
||||
See [desktop builds](https://github.com/morluto/rea/blob/main/.agents/skills/reverse-engineer-anything/references/desktop-build.md).
|
||||
|
||||
## Build
|
||||
|
||||
1. `start_build_computer` from a request. REA is installed in the computer.
|
||||
2. `start_build_capture`. REA writes an apt configuration under
|
||||
2. `start_build_capture`. REA first checks the installed runtime's export
|
||||
schema for synthetic-seed support. If the archive is too old, repack a
|
||||
current REA, update `REA_BUILD_COMPUTER_REA_ARCHIVE`, restart the REA MCP
|
||||
server and start a new build computer. REA then writes an apt configuration under
|
||||
`~/.rea-build/apt` and runs `apt-get update` as the computer's user, so the
|
||||
capture finds the package's sources (`package_lists` counts the lists,
|
||||
and `package_lists_error` gives apt's exit status and last lines when the
|
||||
@@ -32,6 +41,34 @@ Like the computer tools, these are MCP-only and act on a `computer_id` from
|
||||
from a `.deb` file, the build layer keeps that file at
|
||||
`/opt/rea/package.deb` and the capture records it with `--package-file`. Do not open the app from
|
||||
the menu first: the capture refuses an app whose window is already open.
|
||||
When the capture ends before the window opens, REA reads its output. An app
|
||||
that exits at launch, such as one missing a runtime, is reported with its
|
||||
program, exit code, run time and the last lines of its stderr, at most 8
|
||||
lines and 800 characters of the last 8 KiB the capture keeps, and
|
||||
`details.diagnostics` keeps the capture's record of the session. A capture
|
||||
that failed, such as one refusing to start, gives its own message and
|
||||
remediation, with the whole failure in `details.diagnostics.command_failure`
|
||||
and, when its cleanup is incomplete, the run tokens and paths it left in
|
||||
`details.resources`. A checkpoint or stop that finds the capture ended
|
||||
reads its output the same way.
|
||||
|
||||
`state_paths` names files or folders in the computer's home that hold the
|
||||
app's state, relative to the home, after `~/` or absolute under it, at
|
||||
most 16; each becomes a `--state-path` of the capture, so it is retained
|
||||
from the start and its files count as the app's even before they exist.
|
||||
REA counts a file as a document only when an app window's title shows its
|
||||
name or `~/` path, so name the file the app will save when its title shows
|
||||
something else, as MuseScore's shows a score's title: a file outside
|
||||
hidden folders, other than a lock such as LibreOffice's `.~lock.<name>#`,
|
||||
becomes a document, which the bundle owns, seeds and opens
|
||||
at launch, and one under a hidden folder such as `~/.config/MuseScore` the
|
||||
app's own state, also when that folder is a link elsewhere in the home. A
|
||||
path with `..`, or naming the home itself, is refused before the computer
|
||||
is asked; the computer refuses an absolute path outside its home, one in
|
||||
`~/.rea-build`, and one a link leads out of the home or into
|
||||
`~/.rea-build`, resolving a path that does not exist yet through its
|
||||
nearest existing folder, and starts nothing.
|
||||
|
||||
3. Make the seed through the app with `act_on_build_computer`, saving it
|
||||
where the user keeps such files, such as `~/Documents`, then
|
||||
`mark_build_checkpoint` `seed`.
|
||||
@@ -39,18 +76,56 @@ Like the computer tools, these are MCP-only and act on a `computer_id` from
|
||||
`mark_build_checkpoint` `end`.
|
||||
5. `stop_build_capture`. The app is closed and the capture finishes. The
|
||||
result lists the checkpoints with their counts, the package and the
|
||||
sources the capture found, its limitations and the draft: each file that
|
||||
changed between `seed` and `end` with its net change, and suggested
|
||||
checks with a placeholder prompt.
|
||||
sources the capture found, its limitations and the draft: each file under
|
||||
the paths the export owns that changed between `seed` and `end`, with its
|
||||
net change and, for XML files, archives, JSON and key files, its `values`,
|
||||
the values the change added, changed and removed with what each was and
|
||||
became, at the pointer a check names it by; suggested checks with a
|
||||
placeholder prompt; and `guards`, optional checks that the rest kept its
|
||||
seed values. The draft's
|
||||
[task section](desktop-application-tasks.md#describe-the-change) describes
|
||||
each. `notes`, each with a `code` and a `message`, say why a draft has no
|
||||
files: `no_change` when no file under the home changed between them and
|
||||
nor did the app's dconf keys; `unowned_changes` when files changed but
|
||||
none under the owned paths, listing up to five in `files` with their
|
||||
roles, desktop files last, and counting the rest in `more`;
|
||||
`uncheckable_changes` when the app's keys in dconf were read and changed,
|
||||
listing the database in `files`, since no check reads dconf (a version
|
||||
the capture kept no copy of, as it keeps none of the database at the
|
||||
start, counts as holding none of the app's keys);
|
||||
`unreadable_changes` when a dconf database changed but REA could not read
|
||||
it, such as without `dconf-cli`, with the read `error`, so whose keys
|
||||
changed is unknown; and `no_document` when no file has the document role.
|
||||
`unowned_changes` and `no_document` point at `state_paths`. They also say,
|
||||
for a drafted `file`, why its suggestions are thin: `by_position`,
|
||||
`view_state_only`, `long_text`, `cut_view` or `unreadable_view`.
|
||||
6. Write the task: its name, the prompt in the user's own words, and checks
|
||||
that hold after the change and not on the seed.
|
||||
that hold after the change and not on the seed, from the suggestions,
|
||||
`values` and any `guards` worth keeping.
|
||||
7. `export_build_environment` with the task and a new or empty `directory`.
|
||||
The export runs inside the computer with `--seed-checkpoint seed
|
||||
--end-checkpoint end`, so it seeds what was saved at `seed`, scrubs the
|
||||
computer's host name and user from it, and refuses a task whose checks
|
||||
all pass on the seed. A task larger than 96 KiB as REA passes it to the
|
||||
computer is refused before anything runs. A file moved to the desktop Trash is not seeded,
|
||||
and the export's limitations name what the Trash held at `seed`. For a
|
||||
all pass on the seed. It also passes `--synthetic-seed`, since the agent
|
||||
made the seed for the task, so the README does not call it the user's real
|
||||
data. When the seed holds exactly one document and the app's desktop entry
|
||||
takes files, the bundle's app opens that document at launch. A file moved
|
||||
to the desktop Trash is not seeded, and the export's limitations name what
|
||||
the Trash held at `seed`. The limitations and the README also name the
|
||||
folders where files changed during the capture that the bundle neither
|
||||
owns nor seeds, such as settings that keep a first-run wizard away, up to
|
||||
eight collapsed to their top folder, such as `~/.config/MuseScore`, and a
|
||||
count of the rest; capture again with them in `state_paths` to own them.
|
||||
Lock files the app holds while it runs, such as LibreOffice's profile
|
||||
`.lock` and its document lock `.~lock.<name>#`, are left out of the seed,
|
||||
since a copied one can keep the app from starting, and the limitations
|
||||
and the README list them after "Left out of the seed"; a project's
|
||||
`Cargo.lock` or `yarn.lock`, a document or a path in `state_paths` is
|
||||
seeded. They name seeded
|
||||
WebKit or Chromium storage and caches too, which the app keeps for its
|
||||
own running. When the application held files open in a folder whose
|
||||
starting content the capture did not retain, a limitation names the
|
||||
folder and the seed files in it. For a
|
||||
`.deb` app that no apt source the capture found offers, the export takes
|
||||
the request's URL with `--package-url`; one apt offers installs from apt. REA lists the bundle's files with their sizes
|
||||
and SHA-256 in the computer, into a file beside the bundle that it reads
|
||||
@@ -65,7 +140,15 @@ A checkpoint name is lowercase letters, digits, dot, dash and underscore; the
|
||||
capture's own `baseline`, `stop`, `time-limit` and `exit` are refused, and so
|
||||
is a name already taken. The acknowledgement comes from the capture after it
|
||||
has walked the home and retained what changed: `entries` walked, `changes`
|
||||
since the checkpoint before, `retained_files` and `retained_bytes`.
|
||||
since the checkpoint before, `retained_files` and `retained_bytes`, and up to
|
||||
ten `changed_files`, home-relative, with `more_changed_files` counting the
|
||||
rest. Folders are left out; files under `state_paths` come first, then
|
||||
those the app held open, then those in its state directories, then the rest,
|
||||
and caches and WebKit or Chromium storage last, each by path, so a save's
|
||||
document leads the list. When the computer's REA is older than these lists,
|
||||
as when `REA_BUILD_COMPUTER_REA_ARCHIVE` still names an earlier build, the
|
||||
checkpoint is still taken and both are `null`: which files changed is
|
||||
unknown. Pack the current REA into the archive to get them back.
|
||||
|
||||
Each step can be asked again after its answer was lost:
|
||||
|
||||
@@ -89,7 +172,9 @@ computer's control token. REA sends each command through agentenv's
|
||||
`computer-exec/v1` route with that token, which stays in REA, and reads larger
|
||||
outputs, such as the draft, the export's Evidence and the bundle's file
|
||||
list, from files under `~/.rea-build` through `data/get`, since a command's
|
||||
output is capped at 1 MiB.
|
||||
output is capped at 1 MiB. In a command's Evidence or failure read this way,
|
||||
as in its own output, REA replaces the token in every string, after checking
|
||||
the Evidence's digest; the bundle's files arrive as they are.
|
||||
|
||||
Calls on one computer run one at a time, in the order REA receives them:
|
||||
an action, a capture step, a check or a close waits until the call before
|
||||
@@ -102,7 +187,12 @@ cancels the call in progress on it and refuses the calls still waiting.
|
||||
## Witness
|
||||
|
||||
Start a fresh computer from the exported folder with `start_build_computer`
|
||||
and `{"kind": "bundle", "path": ...}`; agentenv boots the app with the seed.
|
||||
and `{"kind": "bundle", "path": ...}`; agentenv boots the app with the seed,
|
||||
on the seed's document when the export opens one. When the computer never
|
||||
gets ready and the bundle's seed holds lock files, the start's error names
|
||||
them: delete them from the bundle, or export again, which leaves them out.
|
||||
A bundle records no state directories, so the error names only files by a
|
||||
profile lock's name and LibreOffice's document locks.
|
||||
Then, with the task exactly as exported:
|
||||
|
||||
| `stage` | Before it | Its checks must |
|
||||
@@ -115,7 +205,18 @@ Then, with the task exactly as exported:
|
||||
`check_build_task` reads the app's `data/get`, takes the views it returns
|
||||
beside the files and evaluates each check with REA's evaluator, the one the
|
||||
export validates tasks with and the exported verifier mirrors, one result per
|
||||
check. Without `stage` it only grades. The `seed` stage begins a recording
|
||||
check. Like the verifier, it grades only once the app's files settle, since an
|
||||
app such as Gnote saves a few seconds after the last key. It reads `data/get`
|
||||
every 0.5 s and grades once every file's bytes have held for 3 s, counted
|
||||
from the read that returned them. 15 s after the first read began, it grades
|
||||
the last completed read: no read starts then, and one still running is cut.
|
||||
It sends progress notifications while it waits. The result's `settled` says
|
||||
whether the files settled, and `read_cut` whether the bound cut a read; each
|
||||
stage in the record keeps both. Every check therefore costs at least 3 s,
|
||||
and a save that lands more than 3 s after the first read returns is still
|
||||
missed; see
|
||||
[grading once the app has saved](desktop-application-export.md#grading-once-the-app-has-saved).
|
||||
Without `stage` it only grades. The `seed` stage begins a recording
|
||||
of the display under REA's own request id, one per computer; a seed check
|
||||
that fails after it, such as on a failed read of the app's state or a lost
|
||||
reply to the recording's start, can be asked again, and asks for the
|
||||
@@ -137,14 +238,17 @@ SQLite file locked past the reader's wait, or because what it looks for may
|
||||
lie in what its view cut, is `undecided` in its result: it shows nothing
|
||||
about the task. That covers a line `lines_present` misses in a text view cut
|
||||
at 5,000 lines, a row `row_present` misses in a table whose view keeps only
|
||||
its first rows, a `value_equals` pointer that names nothing in a truncated
|
||||
view or past a cut zip listing, and the absence checks and counts on a cut
|
||||
view. A check that passes on what the view kept stays decided, and so does a
|
||||
value found there that differs from the one expected. The result's `passed`
|
||||
and description are the exported verifier's, which has no undecided results.
|
||||
A stage that only undecided checks would settle, such as a near miss whose
|
||||
one failing check could not read its file, files nothing and is refused;
|
||||
check it again once the files read whole.
|
||||
its first rows, a `value_equals` or text check pointer that names nothing
|
||||
in a truncated view or past a cut zip listing, the absence checks and counts
|
||||
on a cut view, and `text_equals` or `text_contains` of an element on one,
|
||||
even where the element's kept text holds the value, since the cut may have
|
||||
dropped text from between its runs. Any other check that passes on what the
|
||||
view kept stays decided, and so does a value found there that differs from
|
||||
the one expected.
|
||||
The result's `passed` and description are the exported verifier's, which has
|
||||
no undecided results. A stage that only undecided checks would settle, such
|
||||
as a near miss whose one failing check could not read its file, files nothing
|
||||
and is refused; check it again once the files read whole.
|
||||
|
||||
A stage whose checks do not show what it must ends the witness, and so does
|
||||
`after_reset`. REA then ends the recording, fetches its segments through
|
||||
@@ -154,13 +258,14 @@ A stage whose checks do not show what it must ends the witness, and so does
|
||||
- `recording/NNNN.mp4`, the recording's segments;
|
||||
- `witness.json`, REA Evidence (`rea.desktop-build-witness`) holding the
|
||||
verdict, the stage that failed if one did, the task's name and SHA-256,
|
||||
each stage's results with how many logged actions came before it, the
|
||||
each stage's results with how many logged actions came before it and
|
||||
whether the app's files had settled (`settled`), the
|
||||
computer's [action log](desktop-build-computer.md#act) as it keeps it, each
|
||||
action with its arguments, timing and outcome, with `actions_dropped`
|
||||
counting the earliest actions it no longer keeps, and the recording's
|
||||
segments with their sizes and SHA-256. The record's limitations say when
|
||||
the log dropped actions or cut arguments, which each entry names in
|
||||
`truncated_arguments`.
|
||||
`truncated_arguments`, and which stages graded files that had not settled.
|
||||
|
||||
The stages' rules read the log's count of actions and the last applied
|
||||
action of each kind, which it keeps for the whole session, so they hold
|
||||
|
||||
@@ -19,7 +19,7 @@ initialization, discovery and target-free request flow; it does not verify a
|
||||
client's configured launcher or its inherited environment. Test the generated
|
||||
registration through the actual client, including a reduced `PATH` when checking
|
||||
desktop or service startup. Record the client version and launch environment
|
||||
separately from terminal doctor results. See [launcher troubleshooting](client-configuration.md#launchers-and-path).
|
||||
separately from terminal doctor results. See [launcher troubleshooting](../getting-started/client-configuration.md#launchers-and-path).
|
||||
|
||||
## Published Pi code-mode renderer limit
|
||||
|
||||
@@ -33,7 +33,7 @@ shared form would leave later fields unknown instead. The existing
|
||||
its character limit by advertising reduced nested validation structure, while
|
||||
REA continues to validate calls against the complete canonical input schema.
|
||||
Compact is the default for the server's advertised inputs; an explicit `full`
|
||||
choice is preserved. See the [compact input schema profile](mcp-contracts.md#compact-input-schema-profile)
|
||||
choice is preserved. See the [compact input schema profile](../reference/mcp-contracts.md#compact-input-schema-profile)
|
||||
for details of its reduced forms.
|
||||
|
||||
Custom renderer hosts can raise `inputMaxChars` through `renderToolSignature` or
|
||||
@@ -47,7 +47,7 @@ and [renderer usage notes](https://github.com/earendil-works/pi/blob/b45e0ebcc5a
|
||||
|
||||
## llama.cpp
|
||||
|
||||
The [manual stdio connection](client-configuration.md#llamacpp) was checked on
|
||||
The [manual stdio connection](../getting-started/client-configuration.md#llamacpp) was checked on
|
||||
macOS arm64 with Node.js 24.18.0, llama-server b11715 (`9d1878a43`), and the
|
||||
published `[email protected]` package. `GET /tools` exposed 207 REA tools without
|
||||
enabling llama.cpp's built-in tools. With the source checkout at `9e372c6`, all
|
||||
@@ -486,7 +486,7 @@ 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).
|
||||
both public adapters. See [website script export](../guides/web/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,
|
||||
@@ -494,7 +494,7 @@ null/backtracking rejection, query/fragment identities, repeated module instance
|
||||
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).
|
||||
Chrome CI include this verifier. See [module relationships](../guides/web/website-module-trace.md).
|
||||
|
||||
## Agent evaluation and conformance records
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
# Documentation ownership and authoring
|
||||
|
||||
Use the [documentation directory](../README.md) to find existing material before
|
||||
adding another guide. Preserve one canonical owner for each contract or workflow;
|
||||
link to that owner instead of copying its claims into several guides.
|
||||
|
||||
## Choose a destination
|
||||
|
||||
| Document | Destination |
|
||||
| -------------------------------------------------------- | -------------------------------------- |
|
||||
| Installation, client setup and first CLI/MCP steps | `docs/getting-started/` |
|
||||
| Analyst workflows and evidence interpretation | `docs/guides/<domain>/` |
|
||||
| Analysis-engine configuration and format prerequisites | `docs/providers/` |
|
||||
| Shared runtime contracts and evidence semantics | `docs/reference/` |
|
||||
| Development, testing, release and authoring instructions | `docs/development/` |
|
||||
| Composition diagrams | `docs/architecture/` |
|
||||
| Compatibility changes for a released version | `docs/migrations/` |
|
||||
| One feature specification, plan and tasks | `docs/specs/<domain>/<feature-slug>/` |
|
||||
| One architectural decision | `docs/adr/<domain>/<decision-slug>.md` |
|
||||
|
||||
Use meaningful, lowercase domain and feature slugs. Global numeric prefixes are
|
||||
unnecessary: different domains can add features independently, and branches do
|
||||
not compete for the next sequence number. Check the existing domain directory
|
||||
and linked issues before creating a feature with the same slug.
|
||||
|
||||
Guides describe existing behavior and limitations. Specs define one proposed
|
||||
feature or domain change; an existing guide does not become a specification by
|
||||
moving it into `specs/`.
|
||||
|
||||
## Feature lifecycle
|
||||
|
||||
Create the specification before implementation. Each feature directory contains:
|
||||
|
||||
- `spec.md`: problem, desired behavior, requirements, acceptance and non-goals.
|
||||
- `plan.md`: the single implementation plan, contracts and architectural choices.
|
||||
- `tasks.md`: incremental, testable steps linked to requirements and verification.
|
||||
|
||||
Split independent domains or separately reviewable features before writing their
|
||||
specs. A broad `ROADMAP.md`, when useful, only lists child specifications, order
|
||||
and dependencies; requirements and implementation tasks belong to each child.
|
||||
Cross-repository contracts have one producer-owned specification. Consumers link
|
||||
to that contract instead of maintaining competing copies.
|
||||
|
||||
Record an isolated architectural decision separately in
|
||||
`docs/adr/<domain>/<decision-slug>.md`, with **Status**, **Context**,
|
||||
**Decision** and **Consequences**. Link the ADR from affected specifications.
|
||||
Do not create decision records for routine file moves or invent past decisions.
|
||||
|
||||
Specs do not replace the contribution-scope decision required for a new provider
|
||||
or expanded execution authority. Follow
|
||||
[contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope).
|
||||
|
||||
## Links and public routes
|
||||
|
||||
Use relative links to physical Markdown files so GitHub readers can follow them.
|
||||
Link repository files outside `docs/` with their full GitHub URLs. Preserve
|
||||
existing heading anchors when moving a guide.
|
||||
|
||||
[`documentation.ts`](https://github.com/morluto/rea/blob/main/docs/.vitepress/documentation.ts)
|
||||
owns categorized site navigation and the existing guides' stable public routes.
|
||||
Update it when adding or moving a guide. VitePress rewrites categorized sources
|
||||
to the existing public paths; its Markdown hook resolves repository links from
|
||||
the physical source and renders them against those public routes. Keep basenames
|
||||
and route assignments unique. Edit links use the physical source file.
|
||||
|
||||
For a move, search for both the basename and its old full path. Update README
|
||||
translations, authored skills, verification instructions, documentation-fact
|
||||
readers and release configuration when they consume that path. Preserve
|
||||
historical release records and references bound to earlier commits or tags.
|
||||
|
||||
## Generated ownership and checks
|
||||
|
||||
The [documentation directory](../README.md#machine-owned-documentation) identifies
|
||||
the machine-owned outputs and their producers. Their existing paths are retained
|
||||
because scripts, package consumers and release history depend on them. Change
|
||||
canonical sources and regenerate; do not fix a generated projection by hand.
|
||||
|
||||
Run `npm run docs:check` for documentation facts and generated consistency, and
|
||||
`npm run verify:docs:routes` to build the complete production site and check local
|
||||
links, anchors and physical edit targets.
|
||||
When a physical path moves, also run the tests that read it. Follow
|
||||
[development checks](testing.md#developer-commands) before requesting review.
|
||||
File renamed without changes.
@@ -192,7 +192,7 @@ registry metadata or changelog disagrees with that version before creating a tag
|
||||
|
||||
Before publishing a candidate, review its changelog's breaking changes and the
|
||||
migration notes for the release being prepared. The
|
||||
[6.1 to 6.2 migration guide](migration-6.2.md) records that release's changes;
|
||||
[6.1 to 6.2 migration guide](../migrations/migration-6.2.md) records that release's changes;
|
||||
it is a historical reference, not the compatibility checklist for later releases.
|
||||
|
||||
REA uses Release Please's `always-bump-minor` strategy: every release increments
|
||||
@@ -5,8 +5,8 @@ The [platform tracker](https://github.com/morluto/rea/issues/32),
|
||||
[browser tracker](https://github.com/morluto/rea/issues/39) track capability and
|
||||
verification work. Available tools and setup are documented in the
|
||||
[investigation guides](https://rea.tools/guides/),
|
||||
[installation guide](installation.md), and
|
||||
[generated catalog](mcp-contracts.md#generated-catalog).
|
||||
[installation guide](../getting-started/installation.md), and
|
||||
[generated catalog](../reference/mcp-contracts.md#generated-catalog).
|
||||
|
||||
## Priorities
|
||||
|
||||
@@ -27,7 +27,7 @@ fixture servers; custom orchestration needs a demonstrated requirement.
|
||||
Provider and platform claims require their corresponding
|
||||
[real verification lanes](testing.md#real-toolchain-verification-lanes).
|
||||
See [tool design](tool-design.md) for choosing a tool boundary and
|
||||
[Ghidra semantics](ghidra-provider.md) for the existing deep-provider contract.
|
||||
[Ghidra semantics](../providers/ghidra-provider.md) for the existing deep-provider contract.
|
||||
|
||||
Setup remains additive, reuses existing tools, and requires approval for disclosed
|
||||
configuration and Hopper installation changes. Additional installer choices need
|
||||
@@ -8,7 +8,7 @@ installed-client and agent runs.
|
||||
Historical verification records may refer to `experiments/analysis-efficiency`.
|
||||
Those experiment scripts are available in the [archived source tree](https://github.com/morluto/rea/tree/a2e2c29b59e8775b0e6aedb09a9eb16adf32646b/experiments/analysis-efficiency);
|
||||
they are not included in current checkouts. The retained [test support](https://github.com/morluto/rea/blob/main/tests/support/analysis-efficiency/README.md)
|
||||
contains deterministic checkers and fixtures. The [allocation report](verification/analysis-efficiency/mcp-integer-allocation.md)
|
||||
contains deterministic checkers and fixtures. The [allocation report](../verification/analysis-efficiency/mcp-integer-allocation.md)
|
||||
and its original receipt JSON remain documentation, checked by the report producer.
|
||||
|
||||
## Developer commands
|
||||
@@ -382,7 +382,7 @@ instrumentation remains equivalent.
|
||||
|
||||
## CodeQL production scope
|
||||
|
||||
[The production configuration](../.github/codeql/production.yml) excludes
|
||||
[The production configuration](https://github.com/morluto/rea/blob/main/.github/codeql/production.yml) excludes
|
||||
`tests/`, `scripts/fixtures/`, `*.test.*`, `*.fixture.*`, `test_*.py`, and `*_test.py` inputs
|
||||
during extraction. It retains the default queries and the existing `local`
|
||||
threat model. Production source, bridges, runtime scripts, installation and
|
||||
@@ -398,7 +398,7 @@ These exclusions do not change which behavioral tests CI executes. CodeQL's
|
||||
JavaScript/TypeScript, Python, and Actions lanes do not add shell, Java, or Swift
|
||||
analysis; their existing checks remain responsible for those languages.
|
||||
|
||||
[The production workflow](../.github/workflows/codeql.yml) is inactive until a
|
||||
[The production workflow](https://github.com/morluto/rea/blob/main/.github/workflows/codeql.yml) is inactive until a
|
||||
repository administrator disables CodeQL **default setup** and sets the Actions
|
||||
repository variable `REA_CODEQL_ADVANCED` to `true`. Disable default setup first:
|
||||
it rejects advanced CodeQL uploads. Then enable the variable and manually run
|
||||
@@ -602,6 +602,12 @@ For partial Evidence delivery, verify that same-session readback preserves
|
||||
identity and provenance without rerunning the provider. Include a no-writer
|
||||
control that keeps completed Evidence inline and preserves the original failure.
|
||||
|
||||
For a seekable file with a known extent, distinguish a provably impossible wire
|
||||
extent from an independent representation limit. Pair the malformed declaration
|
||||
with a structurally possible over-limit control. A count-only truncated fixture
|
||||
does not establish capacity behavior. This does not require decoding an opaque
|
||||
compressed payload merely to apply its declared expansion limit.
|
||||
|
||||
When producer order is unspecified, synchronize fixtures on the observed request
|
||||
or completion event. A filename, generated key, or fixed delay does not prove
|
||||
which item completed before cancellation. Preserve real producer ordering and
|
||||
@@ -702,16 +708,16 @@ the affected owners and applicable scenarios below. Include temporary snapshots
|
||||
and one-shot commands. Use public CLI/MCP workflows where practical and a
|
||||
controlled production seam for interleavings that cannot be reproduced reliably.
|
||||
|
||||
| Scenario | Assertion and control |
|
||||
| --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Target admitted; startup still pending | Status preserves the readiness distinction and observed startup activity; readiness requires the provider's documented proof. |
|
||||
| First handshake is late, absent, invalid, or recovered during close | Initial and recovery paths retain the same authenticated identity facts. Foreign run/token controls cannot authorize cleanup; authenticated idle/native work survives the unauthenticated listener deadline. |
|
||||
| Launch returns an error with a valid process handle | Cover already-exited and still-live owned processes. Verify observed exit separately from creation; failed termination or unavailable identity remains unresolved. |
|
||||
| Cancellation arrives after workload exit, during result reads or temporary-root removal | Return typed cancellation with available partial observations and actual cleanup status. The non-aborted control succeeds; existing primary/cleanup failures keep their precedence. |
|
||||
| Children have mixed health or cleanup outcomes | Missing peer health does not erase an observed failure or activity. Idle plus unknown stays unknown. Retry a failed child without closing a successful peer again, including after a close-option change. |
|
||||
| Cleanup fails after success or primary failure | Public output retains the completed observation or primary diagnostic, remaining resources, and owner recovery action. Restore the denied resource and verify the owning cleanup retry. |
|
||||
| Cleanup owners recover after an error was returned | Retain the original child and aggregate errors and project them after each owner releases. A successful peer stays released; the aggregate remains incomplete until all owners release. Preserve the first cause even when rejection is `undefined`. |
|
||||
| Target exits without an acknowledgement, or transport disappears while it stays alive | Positive owned exit proof resolves target lifetime; other resources still need cleanup. Lost transport alone does not prove exit. Verify unrelated/attached targets survive and same-connection recovery works when supported. |
|
||||
| Scenario | Assertion and control |
|
||||
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Target admitted; startup still pending | Status preserves the readiness distinction and observed startup activity; readiness requires the provider's documented proof. |
|
||||
| First handshake is late, absent, invalid, or recovered during close | Initial and recovery paths retain the same authenticated identity facts. Foreign run/token controls cannot authorize cleanup; authenticated idle/native work survives the unauthenticated listener deadline. |
|
||||
| Launch returns an error with a valid process handle | Cover already-exited and still-live owned processes. Verify observed exit separately from creation; failed termination or unavailable identity remains unresolved. |
|
||||
| Cancellation arrives after workload exit, during result reads or temporary-root removal | Before the documented commit cutoff, return typed cancellation with available partial observations and actual cleanup status. After commit, assert the owning publication outcome and receipt. The non-aborted control succeeds; existing primary/cleanup failures keep their precedence. |
|
||||
| Children have mixed health or cleanup outcomes | Missing peer health does not erase an observed failure or activity. Idle plus unknown stays unknown. Retry a failed child without closing a successful peer again, including after a close-option change. |
|
||||
| Cleanup fails after success or primary failure | Public output retains the completed observation or primary diagnostic, remaining resources, and owner recovery action. Restore the denied resource and verify the owning cleanup retry. |
|
||||
| Cleanup owners recover after an error was returned | Retain the original child and aggregate errors and project them after each owner releases. A successful peer stays released; the aggregate remains incomplete until all owners release. Preserve the first cause even when rejection is `undefined`. |
|
||||
| Target exits without an acknowledgement, or transport disappears while it stays alive | Positive owned exit proof resolves target lifetime; other resources still need cleanup. Lost transport alone does not prove exit. Verify unrelated/attached targets survive and same-connection recovery works when supported. |
|
||||
|
||||
Shared process-supervision controls separate leader exit from output closure.
|
||||
Cover output during held or failed cleanup, bounded retention and drain timeout,
|
||||
@@ -909,7 +915,7 @@ covers deterministic evaluator logic.
|
||||
reconstruction, native-boundary relationships and application graphs without
|
||||
executing fixture PE files. Operator-local manifests and actual ILSpy oracles
|
||||
remain optional, separately reported checks; the real Ghidra NativeAOT lane has
|
||||
its own toolchain prerequisites. See [the managed guide](managed-code-analysis.md)
|
||||
its own toolchain prerequisites. See [the managed guide](../guides/managed/managed-code-analysis.md)
|
||||
for those configurations. Generated completion-ledger checks use the same owning
|
||||
entrypoint and include its verifier/fixture files in their cache inputs.
|
||||
|
||||
@@ -1165,104 +1171,104 @@ public registry, and checks both the primary failure and live descendant absence
|
||||
|
||||
## Real-toolchain verification lanes
|
||||
|
||||
See [Real-toolchain verification lanes](testing-lanes.md#real-toolchain-verification-lanes).
|
||||
See [Real-toolchain verification lanes](../testing-lanes.md#real-toolchain-verification-lanes).
|
||||
|
||||
## Android APK analysis
|
||||
|
||||
See [Android APK analysis](testing-lanes.md#android-apk-analysis).
|
||||
See [Android APK analysis](../testing-lanes.md#android-apk-analysis).
|
||||
|
||||
## Apktool resource decoding
|
||||
|
||||
See [Apktool resource decoding](testing-lanes.md#apktool-resource-decoding).
|
||||
See [Apktool resource decoding](../testing-lanes.md#apktool-resource-decoding).
|
||||
|
||||
## Flutter build identification
|
||||
|
||||
See [Flutter build identification](testing-lanes.md#flutter-build-identification).
|
||||
See [Flutter build identification](../testing-lanes.md#flutter-build-identification).
|
||||
|
||||
## ADB device acquisition
|
||||
|
||||
See [ADB device acquisition](testing-lanes.md#adb-device-acquisition).
|
||||
See [ADB device acquisition](../testing-lanes.md#adb-device-acquisition).
|
||||
|
||||
## Optional NativeAOT Ghidra analysis
|
||||
|
||||
See [Optional NativeAOT Ghidra analysis](testing-lanes.md#optional-nativeaot-ghidra-analysis).
|
||||
See [Optional NativeAOT Ghidra analysis](../testing-lanes.md#optional-nativeaot-ghidra-analysis).
|
||||
|
||||
## IDA MCP adapter
|
||||
|
||||
See [IDA MCP adapter](testing-lanes.md#ida-mcp-adapter).
|
||||
See [IDA MCP adapter](../testing-lanes.md#ida-mcp-adapter).
|
||||
|
||||
## Kuna lane
|
||||
|
||||
See [Kuna lane](testing-lanes.md#kuna-lane).
|
||||
See [Kuna lane](../testing-lanes.md#kuna-lane).
|
||||
|
||||
## DOS Ghidra analysis
|
||||
|
||||
See [DOS Ghidra analysis](testing-lanes.md#dos-ghidra-analysis).
|
||||
See [DOS Ghidra analysis](../testing-lanes.md#dos-ghidra-analysis).
|
||||
|
||||
## Apple Interface Builder archives
|
||||
|
||||
See [Apple Interface Builder archives](testing-lanes.md#apple-interface-builder-archives).
|
||||
See [Apple Interface Builder archives](../testing-lanes.md#apple-interface-builder-archives).
|
||||
|
||||
## Native platform baseline in CI
|
||||
|
||||
See [Native platform baseline in CI](testing-lanes.md#native-platform-baseline-in-ci).
|
||||
See [Native platform baseline in CI](../testing-lanes.md#native-platform-baseline-in-ci).
|
||||
|
||||
### Termux Android browser smoke test
|
||||
|
||||
See [Termux Android browser smoke test](testing-lanes.md#termux-android-browser-smoke-test).
|
||||
See [Termux Android browser smoke test](../testing-lanes.md#termux-android-browser-smoke-test).
|
||||
|
||||
## Packet capture analysis
|
||||
|
||||
See [Packet capture analysis](testing-lanes.md#packet-capture-analysis).
|
||||
See [Packet capture analysis](../testing-lanes.md#packet-capture-analysis).
|
||||
|
||||
## Apple native metadata and UI
|
||||
|
||||
See [Apple native metadata and UI](testing-lanes.md#apple-native-metadata-and-ui).
|
||||
See [Apple native metadata and UI](../testing-lanes.md#apple-native-metadata-and-ui).
|
||||
|
||||
### Firmware adapters
|
||||
|
||||
See [Firmware adapters](testing-lanes.md#firmware-adapters).
|
||||
See [Firmware adapters](../testing-lanes.md#firmware-adapters).
|
||||
|
||||
### JavaScript source recovery
|
||||
|
||||
See [JavaScript source recovery](testing-lanes.md#javascript-source-recovery).
|
||||
See [JavaScript source recovery](../testing-lanes.md#javascript-source-recovery).
|
||||
|
||||
### Captured website source-map lane
|
||||
|
||||
See [Captured website source-map lane](testing-lanes.md#captured-website-source-map-lane).
|
||||
See [Captured website source-map lane](../testing-lanes.md#captured-website-source-map-lane).
|
||||
|
||||
### JavaScript large-output lane
|
||||
|
||||
See [JavaScript large-output lane](testing-lanes.md#javascript-large-output-lane).
|
||||
See [JavaScript large-output lane](../testing-lanes.md#javascript-large-output-lane).
|
||||
|
||||
### Website runtime attribution lane
|
||||
|
||||
See [Website runtime attribution lane](testing-lanes.md#website-runtime-attribution-lane).
|
||||
See [Website runtime attribution lane](../testing-lanes.md#website-runtime-attribution-lane).
|
||||
|
||||
### Offline binary layout
|
||||
|
||||
See [Offline binary layout](testing-lanes.md#offline-binary-layout).
|
||||
See [Offline binary layout](../testing-lanes.md#offline-binary-layout).
|
||||
|
||||
### Offline EVM interface
|
||||
|
||||
See [Offline EVM interface](testing-lanes.md#offline-evm-interface).
|
||||
See [Offline EVM interface](../testing-lanes.md#offline-evm-interface).
|
||||
|
||||
### Recorded crash evidence
|
||||
|
||||
See [Recorded crash evidence](testing-lanes.md#recorded-crash-evidence).
|
||||
See [Recorded crash evidence](../testing-lanes.md#recorded-crash-evidence).
|
||||
|
||||
### Exported environment bundles
|
||||
|
||||
See [Exported environment bundles](testing-lanes.md#exported-environment-bundles).
|
||||
See [Exported environment bundles](../testing-lanes.md#exported-environment-bundles).
|
||||
|
||||
## Agent evaluation and conformance records
|
||||
|
||||
See [Agent evaluation and conformance records](testing-lanes.md#agent-evaluation-and-conformance-records).
|
||||
See [Agent evaluation and conformance records](../testing-lanes.md#agent-evaluation-and-conformance-records).
|
||||
|
||||
## Frida instrumentation
|
||||
|
||||
See [Frida instrumentation](testing-lanes.md#frida-instrumentation).
|
||||
See [Frida instrumentation](../testing-lanes.md#frida-instrumentation).
|
||||
|
||||
### Offline WASM artifacts
|
||||
|
||||
See [Offline WASM artifacts](testing-lanes.md#offline-wasm-artifacts).
|
||||
See [Offline WASM artifacts](../testing-lanes.md#offline-wasm-artifacts).
|
||||
@@ -60,23 +60,11 @@ or ordinary script path when available. Identify the specific gap and what a
|
||||
new or extended contract would add; upstream capability alone does not require
|
||||
a new tool or equal support from every provider.
|
||||
|
||||
Exercise the task through REA as a whole and compare relevant provider behavior
|
||||
with an independent artifact or format observation where possible. Use the
|
||||
caller's selected target and authority. Record the provider version, target and
|
||||
observed coverage, and distinguish an unsupported operation from an empty
|
||||
result or an untested path.
|
||||
|
||||
Include the boundary cases that could change the answer: provider labels versus
|
||||
source facts, addresses versus file locations, partial results, and a useful
|
||||
recovery after failure or session close when those apply to the task. Check that
|
||||
composed results keep each observation's identity, limitations and source
|
||||
association. Existing real-provider lanes and focused tests establish their
|
||||
selected scenarios; they do not by themselves establish a different workflow or
|
||||
provider equivalence. If a provider cannot be exercised, report that limitation
|
||||
and continue with the available evidence. Measure agent tool selection only with
|
||||
an actual agent evaluation; a scripted tool sequence does not establish it. Use
|
||||
[testing guidance](testing.md#provider-backed-workflow-verification) to select
|
||||
the cases that establish the proposed contract.
|
||||
Use the caller's selected target and authority. Follow
|
||||
[provider-backed workflow verification](testing.md#provider-backed-workflow-verification)
|
||||
for independent observations, boundary controls and reporting unavailable
|
||||
provider coverage. A scripted tool sequence does not establish agent selection;
|
||||
that claim requires an actual agent evaluation.
|
||||
|
||||
## Audit existing tools
|
||||
|
||||
@@ -94,14 +82,10 @@ identity, session lifetime and available alternatives. Matching text between
|
||||
two renderers does not establish that their shared advice is correct or that an
|
||||
agent selected the workflow.
|
||||
|
||||
Exercise the selected public workflows, including the steps before and after a
|
||||
tool call. Check task selection, input choices, returned facts and their source,
|
||||
partial or unsupported outcomes, and applicable session and recovery behavior.
|
||||
Compare native provider output and an independent artifact observation where
|
||||
available. Inspect existing tests and real-provider lanes for the scenario they
|
||||
actually cover; a passing test does not establish a different task or host.
|
||||
Use [workflow verification](testing.md#provider-backed-workflow-verification)
|
||||
for counterexamples and lifecycle controls relevant to the audit.
|
||||
Exercise each selected workflow before and after the tool call. Use
|
||||
[workflow verification](testing.md#provider-backed-workflow-verification) to
|
||||
check returned facts, partial outcomes, recovery and the scope of existing
|
||||
provider evidence.
|
||||
|
||||
Report working routes as well as findings. Separate a reproduced contract bug,
|
||||
an intentional limitation, a design opportunity and an unverified hypothesis;
|
||||
@@ -178,14 +162,18 @@ does not establish another instance.
|
||||
provider-observed direct relationship set. `complete` means that set was
|
||||
returned without a known read limit; it does not claim every possible runtime
|
||||
edge. Provider and execution caveats stay in `limitations` and do not imply
|
||||
incomplete relationship coverage. Missing coverage remains `unknown`.
|
||||
incomplete relationship coverage. Directional `discovery` separately describes
|
||||
whether applicable static relationships could have been missed by discovery;
|
||||
missing discovery is unknown. Preserve paths supported by observed edges,
|
||||
and qualify negative and shortest-path claims by discovery scope. Missing
|
||||
relationship coverage remains `unknown`. Computed candidates and unestablished incoming targets qualify directional discovery; they do not by themselves mean that recorded edges were omitted.
|
||||
- Declare process, filesystem, network, UI, and mutation effects truthfully;
|
||||
enforce the requested target and lifecycle.
|
||||
- Add limits only for real format, protocol, authority, or measured resource
|
||||
constraints. Report pagination, truncation, cancellation, and partial failure.
|
||||
An assumed agent budget is insufficient justification for a limit. Name the
|
||||
ceiling and its recovery as described in
|
||||
[admission limits and recovery](design/limits-and-recovery.md).
|
||||
[admission limits and recovery](../design/limits-and-recovery.md).
|
||||
|
||||
### Compose declared Evidence inputs
|
||||
|
||||
@@ -229,8 +217,8 @@ MCP supplies the current ledger lookup. CLI commands that advertise
|
||||
`--evidence-bundle` use one explicitly selected, authenticated bundle for the
|
||||
command's lifetime. Keep cleanup with that owner. A retained reference does not
|
||||
grant filesystem access: file selectors remain separate, explicit contracts
|
||||
where supported. See [retained Evidence inputs](mcp-contracts.md#retained-application-evidence-inputs)
|
||||
and [CLI reuse](cli.md#import-export-and-compare-evidence).
|
||||
where supported. See [retained Evidence inputs](../reference/mcp-contracts.md#retained-application-evidence-inputs)
|
||||
and [CLI reuse](../getting-started/cli.md#import-export-and-compare-evidence).
|
||||
|
||||
### Interpret boundary facts once
|
||||
|
||||
@@ -344,13 +332,15 @@ stages that never ran.
|
||||
and resource release separate. A valid process handle, successful launcher,
|
||||
or selected target establishes only its own fact. Publish available identity
|
||||
and exit observations even when launch fails; retain unknown ownership.
|
||||
- Process exit does not establish output closure. The shared process supervisor
|
||||
retains at most 64 KiB of additional diagnostics from owned stop entry,
|
||||
including pending cleanup and retries, and drains for up to one second after
|
||||
verified stop. It marks output incomplete when closure cannot be
|
||||
observed and releases owned event-loop references without changing the proven
|
||||
process-cleanup outcome. Failed process cleanup retains capture for retry;
|
||||
borrowed processes and streams retain their own lifetime and reference state.
|
||||
- Process exit does not establish output closure. The
|
||||
[shared supervisor](https://github.com/morluto/rea/blob/main/src/process/ProviderProcess.ts)
|
||||
owns diagnostic retention and bounded draining through cleanup and retries.
|
||||
Report incomplete output separately from process cleanup. After verified stop
|
||||
and bounded draining, release owned event-loop references even if output closure
|
||||
stays unconfirmed. Keep the output capture owned for retry while process cleanup
|
||||
is unresolved. Borrowed processes and streams retain their own lifetime and
|
||||
reference state; select the matching
|
||||
[supervision controls](testing.md#lifecycle-regressions) when changing this code.
|
||||
- Authenticate and capture identity through the same boundary on initial and
|
||||
recovery handshakes. Bound abandoned unauthenticated listeners where the
|
||||
protocol permits it; that deadline must not expire authenticated idle sessions
|
||||
@@ -369,8 +359,9 @@ stages that never ran.
|
||||
analysis snapshot is part of `open_binary`; cancellation keeps that operation
|
||||
and the caller's reason through the shared JSON reader.
|
||||
- For cancellable observations, carry cancellation through result consumption
|
||||
and awaited cleanup. Before returning success, check the signal after the
|
||||
last awaited finalization step.
|
||||
and awaited cleanup. Check the signal after the last awaited finalization step
|
||||
unless the operation has passed its documented commit cutoff. Preserve the
|
||||
owning operation's committed outcome and receipt after that cutoff.
|
||||
Retain collected observations under typed cancellation. Preserve an existing
|
||||
primary failure and let incomplete cleanup retain its own classification.
|
||||
Preserve the caller's abort reason as the typed cancellation error's cause,
|
||||
@@ -543,5 +534,5 @@ metadata to either adapter.
|
||||
When discoverability changes, evaluate representative broad, direct, and negative
|
||||
tasks on the intended host. Record host/model/catalog, selected tools, arguments,
|
||||
errors, retries, and task outcomes. Schema validity and keyword heuristics do not
|
||||
establish successful tool selection. See [mcp-contracts.md](mcp-contracts.md) for
|
||||
establish successful tool selection. See [mcp-contracts.md](../reference/mcp-contracts.md) for
|
||||
shipped runtime behavior.
|
||||
@@ -44,6 +44,13 @@ file memory regions and paths (`NT_FILE`), fault signal and code (`NT_SIGINFO`),
|
||||
auxiliary vectors (`NT_AUXV`) across 32-bit and 64-bit images. Other owners or unparsed
|
||||
notes keep `core` null.
|
||||
|
||||
Linux `CORE` decoding requires System V/unspecified (0) or GNU/Linux (3)
|
||||
OSABI with ABI version zero. An unspecified OSABI alone does not establish
|
||||
Linux origin. An explicitly different OSABI or ABI version leaves `core` null
|
||||
and its Linux-specific `type_name` unknown, with a limitation explaining the
|
||||
profile. Owner/type numbers, descriptor ranges and hashes, GNU-owned notes,
|
||||
and complete table-examination coverage remain available.
|
||||
|
||||
`PT_NOTE` and `SHT_NOTE` are examined independently. The same file range may
|
||||
appear twice when both tables declare it.
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ and consider setting both `REA_MCP_INPUT_SCHEMA_PROFILE` and
|
||||
advertised output schema to 4,096 bytes by relaxing nested client validation;
|
||||
REA still validates complete results against the canonical contracts. Pair
|
||||
this with retained summaries and selected inventory views to limit the context
|
||||
needed for one question. See [MCP contracts](mcp-contracts.md) for the profiles
|
||||
needed for one question. See [MCP contracts](reference/mcp-contracts.md) for the profiles
|
||||
and their client compatibility tradeoffs.
|
||||
|
||||
The layout facts follow ESP-IDF v6.1 (`esp_app_format.h`, `esp_app_desc.h`,
|
||||
|
||||
@@ -4,7 +4,7 @@ Use the CLI for a direct inspection or a script. It uses the same application
|
||||
workflows and evidence contracts as REA's MCP server. Each CLI invocation is a
|
||||
separate process; save results when you want to use them in a later command.
|
||||
For a pinned, noninteractive workflow with retained reports, see
|
||||
[static analysis in GitHub Actions](ci-analysis.md).
|
||||
[static analysis in GitHub Actions](../ci-analysis.md).
|
||||
|
||||
## Run a command
|
||||
|
||||
@@ -19,7 +19,7 @@ Use an extracted application directory or an ASAR as the target. Static
|
||||
JavaScript analysis returns the application graph and Evidence directly.
|
||||
Generic `rea analyze PATH` selects this workflow for directories and `.asar`
|
||||
files when neither `--provider` nor `--snapshot` is supplied. See
|
||||
[JavaScript artifact reconstruction](javascript-artifact-reconstruction.md)
|
||||
[JavaScript artifact reconstruction](../guides/javascript/javascript-artifact-reconstruction.md)
|
||||
for results, integrity checks and coverage.
|
||||
|
||||
The complete application Evidence can be hundreds of megabytes for a real
|
||||
@@ -59,7 +59,7 @@ For example, a 334 MB Obsidian application Evidence file yields a summary view
|
||||
of about 10 KB. Replace the view with
|
||||
`{"kind": "page", "collection": "modules", "offset": 0, "limit": 32}` for a
|
||||
module page. See
|
||||
[JavaScript application workflows](javascript-application-workflows.md) for
|
||||
[JavaScript application workflows](../guides/javascript/javascript-application-workflows.md) for
|
||||
views, feature traces and comparisons that take the same saved Evidence.
|
||||
|
||||
Add `--timings` to a command to write one JSON timing record to stderr. For
|
||||
@@ -226,7 +226,7 @@ saving the complete original Evidence in a new bundle. Summary requires that
|
||||
explicit destination; existing files are preserved. Later
|
||||
`inspect-analysis-view` calls can page the exact parent from the saved bundle
|
||||
without reopening the assembly. See
|
||||
[CLI summary and saved member rows](managed-code-analysis.md#cli-summary-and-saved-member-rows)
|
||||
[CLI summary and saved member rows](../guides/managed/managed-code-analysis.md#cli-summary-and-saved-member-rows)
|
||||
for the complete command sequence. Omitted or `--detail complete` retains the
|
||||
full inline response.
|
||||
|
||||
@@ -234,8 +234,8 @@ Choose the workflow from the artifact's contents rather than its `.exe` or
|
||||
`.dll` extension. The managed parser requires PE/CLI metadata; it does not
|
||||
unpack .NET single-file hosts or decode IL2CPP. For the image, type and method
|
||||
names in a Unity `global-metadata.dat`, use
|
||||
[IL2CPP metadata](il2cpp-metadata.md). NativeAOT method bodies require native
|
||||
analysis. See the [managed-code guide](managed-code-analysis.md)
|
||||
[IL2CPP metadata](../il2cpp-metadata.md). NativeAOT method bodies require native
|
||||
analysis. See the [managed-code guide](../guides/managed/managed-code-analysis.md)
|
||||
for supported deployment forms, selection semantics, and coverage limits.
|
||||
|
||||
## SQLite snapshots
|
||||
@@ -243,7 +243,7 @@ for supported deployment forms, selection semantics, and coverage limits.
|
||||
For a local database snapshot, use `rea inspect-sqlite-database PATH --json`.
|
||||
Add `--table NAME --row-limit 20` to read a bounded sample from an ordinary
|
||||
table. This command does not require a native analysis provider. See
|
||||
[SQLite database snapshots](sqlite-databases.md) for database/WAL identity,
|
||||
[SQLite database snapshots](../guides/data/sqlite-databases.md) for database/WAL identity,
|
||||
source-file handling and row-value semantics.
|
||||
|
||||
## Native analysis
|
||||
@@ -256,7 +256,7 @@ rea inspect-go-binary /absolute/path/to/program --json
|
||||
```
|
||||
|
||||
The shared CLI/MCP workflow reports compiler version, modules, replacements,
|
||||
build settings, original bytes and SHA-256. See [Go binaries](go-binaries.md)
|
||||
build settings, original bytes and SHA-256. See [Go binaries](../guides/native/go-binaries.md)
|
||||
for supported containers and absent or malformed metadata.
|
||||
|
||||
Inspect a Godot PCK without running the game:
|
||||
@@ -267,7 +267,7 @@ rea extract-artifact game.pck --json
|
||||
```
|
||||
|
||||
Formats 2, 3 and 4 retain header, directory and integrity facts. Compact delivery
|
||||
keeps complete Evidence in the requested bundle. See [Godot PCK](godot-pck.md)
|
||||
keeps complete Evidence in the requested bundle. See [Godot PCK](../godot-pck.md)
|
||||
for embedded packs, batch queries and unknown encrypted coverage.
|
||||
|
||||
Inspect a UnityFS AssetBundle without running Unity:
|
||||
@@ -278,7 +278,7 @@ rea extract-artifact content.bundle --json
|
||||
```
|
||||
|
||||
Format versions 6 through 8 retain header, block and directory facts with
|
||||
none/LZ4/LZ4HC block decompression. See [UnityFS](unityfs.md) for encryption
|
||||
none/LZ4/LZ4HC block decompression. See [UnityFS](../unityfs.md) for encryption
|
||||
and LZMA coverage boundaries.
|
||||
|
||||
Inspect a WeChat mini-program package without WeChat or an unpacker:
|
||||
@@ -290,7 +290,7 @@ rea extract-artifact app.wxapkg --json
|
||||
|
||||
Plaintext packages retain header, table and member facts with verbatim member
|
||||
bytes. `V1MMWX` packages are detected as encrypted coverage and refused on
|
||||
extraction. See [wxapkg](wxapkg.md) for layout and coverage boundaries.
|
||||
extraction. See [wxapkg](../wxapkg.md) for layout and coverage boundaries.
|
||||
|
||||
Inspect an ESP32-family app or bootloader image without esptool:
|
||||
|
||||
@@ -301,7 +301,7 @@ rea extract-artifact firmware.bin --json
|
||||
|
||||
The inventory lists each segment with its ESP-IDF load classification, the
|
||||
checksum and SHA-256 results, the descriptor and any Secure Boot v2 signature
|
||||
blocks. See [ESP images](esp-image.md) for recognition, coverage and refusals.
|
||||
blocks. See [ESP images](../esp-image.md) for recognition, coverage and refusals.
|
||||
|
||||
Inspect an ESP flash dump, or one read from a flash address other than 0:
|
||||
|
||||
@@ -313,7 +313,7 @@ rea extract-artifact flash.bin --json
|
||||
|
||||
The inventory lists the bootloader, the partition table and each partition,
|
||||
with ESP image facts for app partitions and the OTA records. See
|
||||
[ESP flash images](esp-flash-image.md) for table location, inputs and limits.
|
||||
[ESP flash images](../esp-flash-image.md) for table location, inputs and limits.
|
||||
|
||||
Inspect a Node.js SEA carrier without running it:
|
||||
|
||||
@@ -322,7 +322,7 @@ rea inspect-artifact ./application --json
|
||||
rea extract-artifact ./application --json
|
||||
```
|
||||
|
||||
See [Node.js SEA](node-sea.md) for supported layouts, script and asset paths,
|
||||
See [Node.js SEA](../node-sea.md) for supported layouts, script and asset paths,
|
||||
fuse observations, and the real-fixture verification lane.
|
||||
|
||||
Inventory and extract Intel HEX or S-record regions:
|
||||
@@ -332,7 +332,7 @@ rea inspect-artifact ./firmware.hex --json
|
||||
rea extract-artifact ./firmware.hex --json
|
||||
```
|
||||
|
||||
See [Intel HEX and S-record images](hex-records.md) for recognition, region
|
||||
See [Intel HEX and S-record images](../hex-records.md) for recognition, region
|
||||
names, metadata and limits.
|
||||
|
||||
Inspect and extract stored U-Boot legacy uImage payloads and components:
|
||||
@@ -342,7 +342,7 @@ rea inspect-artifact ./firmware.bin --detail summary --evidence_output firmware.
|
||||
rea extract-artifact ./firmware.bin --json
|
||||
```
|
||||
|
||||
See [U-Boot uImage](uimage.md) for verified CRCs, physical component ranges,
|
||||
See [U-Boot uImage](../uimage.md) for verified CRCs, physical component ranges,
|
||||
unknown names, resource limits and retained views. Compressed bytes stay stored.
|
||||
|
||||
`inspect-artifact` and `extract-artifact` also read ZIP members compressed with
|
||||
@@ -361,7 +361,7 @@ rea inspect-artifact ./firmware.uf2 --json
|
||||
rea extract-artifact ./firmware.dfu --json
|
||||
```
|
||||
|
||||
See [UF2 and DfuSe images](uf2-dfuse.md) for recognition, families, numbering,
|
||||
See [UF2 and DfuSe images](../uf2-dfuse.md) for recognition, families, numbering,
|
||||
the DfuSe suffix CRC and limits.
|
||||
|
||||
Inventory and extract U-Boot FIT images:
|
||||
@@ -371,7 +371,7 @@ rea inspect-artifact ./boot.itb --json
|
||||
rea extract-artifact ./boot.itb --json
|
||||
```
|
||||
|
||||
See [U-Boot FIT images](fit-images.md) for recognition, data sources, hashes
|
||||
See [U-Boot FIT images](../fit-images.md) for recognition, data sources, hashes
|
||||
and limits.
|
||||
|
||||
Inspect local model declarations without loading weights:
|
||||
@@ -385,7 +385,7 @@ Default hashing reads only headers and leaves full-file identity unknown.
|
||||
`--hash full` streams the complete file for SHA-256. Both return typed metadata,
|
||||
original tensor declarations and derived totals. MCP summaries retain complete
|
||||
Evidence for filtered metadata, tensor and type-total pages; CLI compact delivery
|
||||
uses `--detail summary --evidence_output FILE`. See [model files](model-artifacts.md).
|
||||
uses `--detail summary --evidence_output FILE`. See [model files](../model-artifacts.md).
|
||||
|
||||
Inspect Unity IL2CPP metadata names without Unity or a disassembler:
|
||||
|
||||
@@ -402,7 +402,7 @@ method instances and `--ghidra-seeds PATH` then writes Ghidra function seeds. It
|
||||
with retained Evidence; query indexed rows with filters, batch indices and
|
||||
selected fields. The CLI defaults to complete Evidence;
|
||||
`--detail summary --evidence_output FILE` exports the full result to a new file
|
||||
and returns a compact overview. See [IL2CPP metadata](il2cpp-metadata.md).
|
||||
and returns a compact overview. See [IL2CPP metadata](../il2cpp-metadata.md).
|
||||
|
||||
Inspect an embedded cargo-auditable Rust dependency list without installing
|
||||
Rust or configuring a disassembler:
|
||||
@@ -414,7 +414,7 @@ rea inspect-rust-binary /absolute/path/to/program --json
|
||||
The same workflow reports package names, versions, sources, the root package,
|
||||
dependency edges, and the section's file range. A missing `.dep-v0` section is
|
||||
null metadata, not proof that the binary has no dependencies. See
|
||||
[Rust binaries](rust-binaries.md).
|
||||
[Rust binaries](../rust-binaries.md).
|
||||
|
||||
Inspect a PE Authenticode certificate table without executing the image or
|
||||
verifying signatures:
|
||||
@@ -426,7 +426,7 @@ rea inspect-pe-certificates /absolute/path/to/application.exe --json
|
||||
The workflow reports `WIN_CERTIFICATE` entries and, for PKCS#7 signedData,
|
||||
embedded X.509 serial, issuer, subject, and validity fields. A missing security
|
||||
directory is observed absence of that table. See
|
||||
[PE Authenticode certificate tables](pe-certificates.md).
|
||||
[PE Authenticode certificate tables](../pe-certificates.md).
|
||||
|
||||
Inspect PE import and delay-load tables without executing the image:
|
||||
|
||||
@@ -437,7 +437,20 @@ rea inspect-pe-imports /absolute/path/to/application.exe --json
|
||||
The workflow reports DLL names, named and ordinal functions, delay-load
|
||||
descriptors, and a pefile-compatible import hash of the standard import table.
|
||||
A missing import directory is observed absence of that table. See
|
||||
[PE import and delay-load tables](pe-imports.md).
|
||||
[PE import and delay-load tables](../pe-imports.md).
|
||||
|
||||
Inspect a Windows Shell Link (`.lnk`) without resolving or executing the
|
||||
target:
|
||||
|
||||
```bash
|
||||
rea inspect-windows-shortcut /absolute/path/to/shortcut.lnk --json
|
||||
```
|
||||
|
||||
The workflow reports header flags and FILETIMEs, IDList items, LinkInfo volume
|
||||
and network names, StringData arguments and icon location, ExtraData blocks
|
||||
including Tracker droid facts labelled derived, and derived observations such
|
||||
as argument length and a minimized ShowCommand. See
|
||||
[Windows Shell Link shortcuts](../guides/native/windows-shortcut.md).
|
||||
|
||||
Inspect ELF PT_NOTE and SHT_NOTE tables without executing the image:
|
||||
|
||||
@@ -447,7 +460,7 @@ rea inspect-elf-notes /absolute/path/to/program --json
|
||||
|
||||
The workflow reports note owners, types, descriptor hashes, and GNU build-id
|
||||
or ABI-tag fields when those descriptors match. A missing note table is
|
||||
observed absence of those declarations. See [ELF note tables](elf-notes.md).
|
||||
observed absence of those declarations. See [ELF note tables](../elf-notes.md).
|
||||
|
||||
Inspect an Apple `.ips` crash report without executing a target:
|
||||
|
||||
@@ -458,7 +471,7 @@ rea inspect-apple-ips /absolute/path/to/report.ips --json
|
||||
The workflow reports first-line metadata, process/exception/termination facts,
|
||||
threads, usedImages, lossless integer registers, and documented crash classes
|
||||
when `bug_type` is `"309"`. Other DiagnosticReports types return no crash
|
||||
result. See [Apple IPS crash reports](apple-ips.md).
|
||||
result. See [Apple IPS crash reports](../apple-ips.md).
|
||||
Inspect Linux kernel module metadata without executing the module or requiring
|
||||
`modinfo`:
|
||||
|
||||
@@ -474,7 +487,7 @@ not decoded and the signature is not validated. Other ELF types are not
|
||||
applicable. gzip, xz, and zstd containers are unsupported and name
|
||||
`external_decompression` as the next probe: decompress with an external
|
||||
utility, then inspect the decompressed file. See
|
||||
[Linux kernel modules](kernel-modules.md).
|
||||
[Linux kernel modules](../kernel-modules.md).
|
||||
|
||||
Inspect a CPython 3.7–3.13 `.pyc` header and nested marshal code objects (3.14 and
|
||||
3.15 headers are qualified but their marshal layout is not pinned)
|
||||
@@ -486,7 +499,7 @@ rea inspect-python-pyc /absolute/path/to/module.pyc --json
|
||||
|
||||
The workflow reports the pinned CPython version for the magic, PEP 552 hash or
|
||||
mtime/size fields, nested function names, and bytecode SHA-256. Bytecode is
|
||||
not decompiled. See [CPython pyc inspection](python-pyc.md).
|
||||
not decompiled. See [CPython pyc inspection](../python-pyc.md).
|
||||
|
||||
Inspect an Erlang BEAM file without executing bytecode:
|
||||
|
||||
@@ -496,7 +509,7 @@ rea inspect-erlang-beam /absolute/path/to/app.beam --json
|
||||
|
||||
The workflow reports IFF chunk names, atom tables, exports, imports, lambdas,
|
||||
and the Code chunk header. Missing optional tables stay null. See
|
||||
[Erlang BEAM files](erlang-beam.md).
|
||||
[Erlang BEAM files](../erlang-beam.md).
|
||||
|
||||
Complete `rea decompile --json` Evidence can be saved and inspected through
|
||||
`inspect-analysis-view` with an inline source and
|
||||
@@ -505,10 +518,10 @@ The projection reads that saved observation without starting a provider;
|
||||
offsets/limits count UTF-16 code units. A summary view preserves the original
|
||||
selector and distinguishes null from empty text. The MCP tool additionally
|
||||
supports `detail: "summary"` on its first call to retain the complete source
|
||||
without returning the body inline; see [native investigation](native-investigation.md).
|
||||
without returning the body inline; see [native investigation](../guides/native/native-investigation.md).
|
||||
|
||||
Configure [Hopper or Ghidra](installation.md#hopper), the
|
||||
[IDA adapter](ida-provider.md), or [Kuna](kuna-provider.md) before analyzing a
|
||||
[IDA adapter](../providers/ida-provider.md), or [Kuna](../kuna-provider.md) before analyzing a
|
||||
native target. Substitute
|
||||
your target, search text and function name or address in these examples:
|
||||
|
||||
@@ -536,11 +549,11 @@ MCP `analyze_function` defaults to the same summary and retains the complete
|
||||
dossier in the session for `inspect_analysis_view`.
|
||||
|
||||
Run `rea --help` or a command's `--help` for arguments and output options.
|
||||
The [generated catalog](mcp-contracts.md#generated-catalog) lists all CLI commands and MCP
|
||||
The [generated catalog](../reference/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), [GameCube DOL guide](ghidra-dol.md), and
|
||||
[Windows Ghidra guide](windows-ghidra-p0.md).
|
||||
[native guide](../guides/native/native-investigation.md), [DOS guide](../providers/ghidra-dos.md),
|
||||
[raw binary guide](../providers/raw-binary.md), [GameCube DOL guide](../ghidra-dol.md), and
|
||||
[Windows Ghidra guide](../providers/windows-ghidra-p0.md).
|
||||
|
||||
## Choose a provider
|
||||
|
||||
@@ -587,19 +600,20 @@ For Hopper, Ghidra, IDA, JADX, and Kuna, run
|
||||
such as `pwntools-elf`, report their configuration requirements directly and are
|
||||
not accepted by `doctor --provider`. See
|
||||
[task readiness](installation.md#check-readiness-for-your-task) and
|
||||
[provider selection](mcp-contracts.md#identity-and-discovery).
|
||||
[provider selection](../reference/mcp-contracts.md#identity-and-discovery).
|
||||
|
||||
The session reports work still in progress through `analysis_activity`.
|
||||
A client timeout can end its wait while the provider continues analyzing.
|
||||
`cleanup_incomplete` identifies resources whose shutdown or removal could not
|
||||
be verified. See [MCP contracts](mcp-contracts.md) for session lifecycle and
|
||||
[Ghidra first-query deadlines](mcp-contracts.md#ghidra-first-query-deadlines-and-recovery)
|
||||
be verified. See [MCP contracts](../reference/mcp-contracts.md) for session lifecycle and
|
||||
[Ghidra first-query deadlines](../reference/mcp-contracts.md#ghidra-first-query-deadlines-and-recovery)
|
||||
for import, client timeouts and recovery.
|
||||
|
||||
A one-shot command releases its provider session and REA runtime before it
|
||||
prints a failure, so it omits the same-session reuse and
|
||||
`update_analysis_settings` guidance an MCP connection receives. Its
|
||||
`details.limit` reports `scope: "rea-invocation"` and
|
||||
A one-shot command attempts provider-session and runtime cleanup before reporting
|
||||
a failure. If cleanup remains incomplete, inspect the reported resources and
|
||||
follow the error's remediation. [Same-session cleanup retry](../reference/mcp-contracts.md#retained-cleanup-retry),
|
||||
reuse and `update_analysis_settings` apply to a live MCP connection.
|
||||
For one-shot commands, `details.limit` reports `scope: "rea-invocation"` and
|
||||
`applies_at: "next_invocation"`; set the named `environment` (or the per-call
|
||||
`parameter`) for a new invocation and rerun. For example, a Ghidra decompile
|
||||
deadline names `REA_GHIDRA_DECOMPILE_TIMEOUT_SECONDS`.
|
||||
@@ -628,12 +642,10 @@ an exact result when the target bytes, operation, parameters, provider and
|
||||
settings match. Mutations and cursor-dependent calls are excluded from the
|
||||
cache. Snapshot files are local and use owner-only permissions.
|
||||
|
||||
One-shot binary CLI Evidence reports the exact path argument in `caller_input_path`,
|
||||
including relative spelling and symlink aliases. Its subject identifies the
|
||||
inspected artifact; `caller_input_path` does not change the Evidence ID or
|
||||
snapshot query. A replay reports the current invocation's path while leaving
|
||||
the saved Evidence unchanged. Provider inspections continue to include the
|
||||
established `parameters.input_path` field.
|
||||
A binary CLI replay reports the current invocation's selected path while leaving
|
||||
the saved Evidence and snapshot query unchanged. See
|
||||
[caller-selected paths](../reference/mcp-contracts.md#caller-selected-paths)
|
||||
for primary and auxiliary path fields and their relation to Evidence identity.
|
||||
|
||||
Importing an Evidence bundle refreshes retained request and subject display metadata.
|
||||
It preserves cached analysis results, including observations for other targets.
|
||||
@@ -742,6 +754,12 @@ rea compare left.json right.json --record_pairs '[{"left_evidence_id":"ev_<left-
|
||||
Migration: replace `rea compare-bundles` with `rea compare`; the former command
|
||||
has been removed. The MCP tool remains `compare_bundles`.
|
||||
|
||||
`rea evidence-import` performs process-local bundle authentication and
|
||||
validation, reporting record and Unknown-revision counts. `unknowns_added`
|
||||
counts revisions, not distinct Unknown IDs. It does not retain records in a
|
||||
separate or background MCP server process. To retain records across calls in an
|
||||
active MCP session, use the MCP tool `import_evidence_bundle` in that session.
|
||||
|
||||
`rea compare` compares records by Evidence identity and explicit pairs. It does
|
||||
not read artifact contents: the inventories of two builds are unresolved
|
||||
records, or one opaque change when you pair them. Use `compare-artifacts`,
|
||||
@@ -763,8 +781,8 @@ protection still applies. A genuine pathname refusal uses `resource_constraint`
|
||||
with `details.reason: path-limit` and `boundary: filesystem-path`.
|
||||
|
||||
For application traces and version comparisons, see
|
||||
[JavaScript application workflows](javascript-application-workflows.md).
|
||||
MCP [retained Evidence references](mcp-contracts.md#retained-application-evidence-inputs)
|
||||
[JavaScript application workflows](../guides/javascript/javascript-application-workflows.md).
|
||||
MCP [retained Evidence references](../reference/mcp-contracts.md#retained-application-evidence-inputs)
|
||||
belong to one connection. Separate CLI calls can consume full saved records or
|
||||
resolve exact retained IDs from an explicitly selected local bundle:
|
||||
|
||||
@@ -972,23 +990,23 @@ for percent signs, query marks and fragments.
|
||||
Historical-source import requires safe no-follow file opens on Linux or
|
||||
macOS. Native Windows returns `unsupported_host`; use Linux REA inside WSL
|
||||
or another supported host. See
|
||||
[source-to-bundle comparison](javascript-application-workflows.md#historical-source-to-bundle-comparison)
|
||||
[source-to-bundle comparison](../guides/javascript/javascript-application-workflows.md#historical-source-to-bundle-comparison)
|
||||
for mapping identities, inferences and unknowns.
|
||||
|
||||
## Capture runtime behavior
|
||||
|
||||
Choose the guide for the target and intended interaction:
|
||||
|
||||
- [Browser observation](browser-observation.md): inspect a selected page through CDP.
|
||||
- [Browser scenarios](browser-scenario-contract.md): run declared interactions and capture their results.
|
||||
- [Electron observation](electron-observation.md): inspect an Electron renderer or capture an application scenario.
|
||||
- [Electron fuses](electron-fuses.md): read packaged fuse bytes before expecting `--inspect` to reach an Electron main process.
|
||||
- [Node/Electron Inspector](javascript-runtime-observation.md): record script locations and execution contexts.
|
||||
- [Process capture](process-capture.md): run an executable and compare terminal, exit and filesystem observations.
|
||||
- [Desktop application capture](desktop-application-capture.md): launch a Linux desktop application and record its windows and home-directory state at checkpoints while it is used.
|
||||
- [Desktop application state](desktop-application-state.md): read a capture folder into the application's state files, typed views of each version and kinds of change.
|
||||
- [Desktop application export](desktop-application-export.md): write a capture folder as an agentenv computer app bundle with its class, skill and seed.
|
||||
- [Desktop application tasks](desktop-application-tasks.md): describe how a capture's files changed, then validate an agent-written task against the capture and export it with its verifier.
|
||||
- [Browser observation](../guides/web/browser-observation.md): inspect a selected page through CDP.
|
||||
- [Browser scenarios](../guides/web/browser-scenario-contract.md): run declared interactions and capture their results.
|
||||
- [Electron observation](../guides/javascript/electron-observation.md): inspect an Electron renderer or capture an application scenario.
|
||||
- [Electron fuses](../electron-fuses.md): read packaged fuse bytes before expecting `--inspect` to reach an Electron main process.
|
||||
- [Node/Electron Inspector](../guides/javascript/javascript-runtime-observation.md): record script locations and execution contexts.
|
||||
- [Process capture](../guides/runtime/process-capture.md): run an executable and compare terminal, exit and filesystem observations.
|
||||
- [Desktop application capture](../desktop-application-capture.md): launch a Linux desktop application and record its windows and home-directory state at checkpoints while it is used.
|
||||
- [Desktop application state](../desktop-application-state.md): read a capture folder into the application's state files, typed views of each version and kinds of change.
|
||||
- [Desktop application export](../desktop-application-export.md): write a capture folder as an agentenv computer app bundle with its class, skill and seed.
|
||||
- [Desktop application tasks](../desktop-application-tasks.md): describe how a capture's files changed, then validate an agent-written task against the capture and export it with its verifier.
|
||||
|
||||
Runtime requests name the target and actions. Launched targets run with your
|
||||
user permissions; consult the chosen guide for host requirements and effects.
|
||||
@@ -1027,7 +1045,7 @@ one client at a time: a session ends with the client's `DELETE`, and a client
|
||||
that connects while another session is open takes it over, so a client that
|
||||
exited without ending its session needs no restart. The listener runs until
|
||||
SIGINT or SIGTERM and does not stop when stdin closes. See
|
||||
[transports](mcp-contracts.md#transports) for the session, `Host` header and
|
||||
[transports](../reference/mcp-contracts.md#transports) for the session, `Host` header and
|
||||
shutdown contract. Client registrations written by setup and the MCP registry
|
||||
entry keep stdio.
|
||||
|
||||
@@ -1052,7 +1070,7 @@ answers every method with JSON-RPC `-32601`. The stopped document's `state`
|
||||
member is `{"served": true, "evidence_id": …}`,
|
||||
`{"served": false, "reason": "replay-only"}` or
|
||||
`{"served": false, "reason": "unavailable", "code": …, "message": …}`; see
|
||||
[serve from the state](agent-environments.md#serve-from-the-state).
|
||||
[serve from the state](../agent-environments.md#serve-from-the-state).
|
||||
|
||||
```sh
|
||||
rea environment-serve manifest.json --evidence capture.json --port 8765
|
||||
@@ -1072,7 +1090,7 @@ MCP_ALLOWED_HOSTS=127.0.0.1,rea.lan rea environment-serve manifest.json --eviden
|
||||
the served environment; set but blank, it is refused as `configuration_invalid`
|
||||
like a blank `MCP_HOST`. The admitted client URL is written to stderr as one JSON log line
|
||||
(`"msg":"MCP transport listening"`). See
|
||||
[agent environments](agent-environments.md) for what the state and replay
|
||||
[agent environments](../agent-environments.md) for what the state and replay
|
||||
return and do not establish.
|
||||
|
||||
## Build an environment bundle
|
||||
@@ -1097,7 +1115,7 @@ command. `--dry-run` writes nothing and may omit the directory.
|
||||
rea environment-build grafana.har ./grafana --json
|
||||
```
|
||||
|
||||
See [agent environments](agent-environments.md#build-a-bundle-in-one-step)
|
||||
See [agent environments](../agent-environments.md#build-a-bundle-in-one-step)
|
||||
for the report, the hints and what the bundle ships.
|
||||
|
||||
## Export an environment bundle
|
||||
@@ -1130,9 +1148,26 @@ name Windows reserves (`con`, `nul`, `com1` and the like) is refused. The
|
||||
command prints one JSON document listing the written files with their sizes,
|
||||
the pinned package source, the served `tool_count`, and `state` in the shape
|
||||
of the serve command's stopped document. See
|
||||
[agent environments](agent-environments.md#export-a-bundle) for the folder
|
||||
[agent environments](../agent-environments.md#export-a-bundle) for the folder
|
||||
layout and what the smoke task checks.
|
||||
|
||||
`rea environment-export` prints the written files and exits `0` on success.
|
||||
Input-pair refusals, an occupied destination, a missing package tarball, and
|
||||
invalid labels fail before writing output. Host permission failures identify
|
||||
whether reading or writing was denied and retain the affected path.
|
||||
|
||||
A failure during writing can leave a partial folder. Inspect it before removing
|
||||
it and retrying; the next attempt refuses a non-empty destination. When one
|
||||
file caused the failure, the diagnostic names that file. A folder-sync failure
|
||||
can report only its cause.
|
||||
|
||||
If `details.partial_observation.kind` is `environment-bundle-publication`, the
|
||||
bundle was already published. Its `directory` and `files` record the committed
|
||||
output, even when a later identity check or cleanup failed. Inspect that bundle
|
||||
and resolve the reported failure before using or replacing it; the receipt is
|
||||
not an instruction to delete published output. Cleanup resources remain a
|
||||
separate obligation.
|
||||
|
||||
## Compare an environment with its application
|
||||
|
||||
`rea environment-compare <manifest.json> --evidence <capture.json> --probe <probe.json> [--probe <probe.json> ...]`
|
||||
@@ -1143,7 +1178,7 @@ answer is compared with the application's after ids are mapped and clocks and ge
|
||||
makes no network call. It prints the report and exits `0`, or prints a structured `invalid_request` error and exits `1`
|
||||
for the same pair refusals as `environment-serve`, a probe that is not capture Evidence, or a browser probe captured
|
||||
without response bodies, or without the request bodies its writes need. See
|
||||
[agent environments](agent-environments.md#measure-fidelity-against-the-application) for the report.
|
||||
[agent environments](../agent-environments.md#measure-fidelity-against-the-application) for the report.
|
||||
|
||||
```sh
|
||||
rea environment-compare manifest.json --evidence capture.json --probe probe.json --json
|
||||
@@ -1324,62 +1359,17 @@ retains failed stages for retry; the CLI exposes no separate retry command.
|
||||
or prints the refusing stage's structured error and exits `1`, writing nothing
|
||||
when the refusal comes before the bundle is written. SIGINT cancels it with a
|
||||
`cancelled` error; a cancellation before the bundle stage writes nothing.
|
||||
`rea environment-export` is one-shot: it prints the written files and exits
|
||||
`0`, or prints a structured `invalid_request` error and exits `1` for the same
|
||||
pair refusals, a non-empty or file-occupied directory, a missing package
|
||||
tarball or a name that is not a kebab-case label or is a Windows device name,
|
||||
writing nothing in each case. A file occupying the destination is reported as
|
||||
requiring a directory; identity-change diagnostics are reserved for admitted
|
||||
paths that fail later identity checks. Host permission failures identify whether
|
||||
input reading or bundle writing was denied and retain the reported path.
|
||||
A write that fails after the first file (a permission, disk-space or
|
||||
pathname-length failure on a later path) propagates as the host's failure,
|
||||
naming its cause and, when it failed on one bundle file or the package
|
||||
tarball, that file. A failure while syncing the finished folder names only its
|
||||
cause. Either way the partial folder stays in place for inspection; remove it
|
||||
before retrying, since the next attempt refuses the non-empty directory.
|
||||
A `cancelled` result does not by itself determine the exit status. Commands
|
||||
that handle SIGINT or SIGTERM assign `130` or `143` after their operation and
|
||||
cleanup settle; their structured result can be printed before that status is
|
||||
assigned. Read the process status and typed result separately.
|
||||
|
||||
A `cancelled` result does not by itself determine the exit status; it depends on
|
||||
the command's signal handling. Commands routed through the shared
|
||||
`withCommandCancellation` handler in the CLI set status `130` for SIGINT or
|
||||
`143` for SIGTERM after their operation settles. Current source registrations
|
||||
use that handler for process capture and comparison (`capture-process`,
|
||||
`compare-process-captures`), desktop application capture and state
|
||||
(`capture-desktop-application`, `inspect-desktop-application-state`,
|
||||
`export-desktop-application`, `describe-desktop-application-task`), JavaScript application analysis (`analyze` when it
|
||||
selects the JavaScript lane, and `analyze-javascript-application`), selected
|
||||
browser, web and Electron commands (including `analyze-web-bundle`,
|
||||
`observe-web-execution`, `capture-browser-scenario` and
|
||||
`capture-electron-scenario`), and the platform and provider command families
|
||||
for Android/ADB, Apktool/JEB/Flutter, firmware, PCAP and signal analysis,
|
||||
WASM/EVM, Go/Rust and binary diagnostics, Frida instrumentation, the Cutter
|
||||
command, objdump, Rizin and GDB, and the agent environment server
|
||||
(`environment-serve`). The handler also wraps `doctor`,
|
||||
`inspect-sqlite-database`, `recover-javascript-sources`,
|
||||
`inspect-il2cpp-metadata`, and `inspect-desktop-application`. In these paths, a returned structured
|
||||
`cancelled` result can be printed before the wrapper assigns the
|
||||
signal-derived status. This describes the current source routing; it is not a
|
||||
claim that every command or provider runtime has been independently exercised.
|
||||
|
||||
Commands with `--evidence_output` select their delivered view, then publish the
|
||||
complete Evidence bundle atomically. Cancellation before publication leaves no
|
||||
new file. A publication that has committed can win a later cancellation; the
|
||||
`cancelled` result then keeps the written path and byte count under
|
||||
`details.diagnostics.evidence_bundle`. If staging cleanup stays incomplete
|
||||
after commit, the `cleanup_incomplete` error reports the same file as
|
||||
`details.published_path` and `details.bytes`.
|
||||
|
||||
When a failure retains a completed observation and no bundle committed,
|
||||
`details.source_closure` states what that observation cites. `publication` is
|
||||
`not_published`. `records` holds authentic source Evidence this invocation
|
||||
captured, within 64 KiB. `omitted` lists up to 64 other identities and
|
||||
`omitted_count` the total: `not_captured` means the invocation holds no such
|
||||
record, so nothing is shown for it or its ancestors; `not_inlined` means it was
|
||||
captured but is not in this response. `complete` is true only when every cited
|
||||
record is in `records` or embedded in the observation. If examining the closure
|
||||
itself fails, `collection_failure` names the error type and the closure state is
|
||||
unknown; the original failure is still returned. Nothing is retained after exit,
|
||||
and running the command again is a new observation.
|
||||
Commands with `--evidence_output` save the complete Evidence bundle before
|
||||
delivering the selected view. For committed-file receipts, retained partial
|
||||
Evidence and missing source records, see
|
||||
[Evidence publication and source recovery](../reference/mcp-contracts.md#evidence-publication-and-source-recovery).
|
||||
Other outputs have their own receipt shapes; for example,
|
||||
[environment export](#export-an-environment-bundle) reports a published directory.
|
||||
|
||||
When the reader of piped output closes early, as `rea ... | head` does, the
|
||||
CLI stops writing, prints no error and exits `141` (`128 + 13`, the status of a
|
||||
@@ -1423,7 +1413,7 @@ the total token count and have no next offset.
|
||||
|
||||
Inspect an explicit local FDT v16/v17 blob without execution or an external tool.
|
||||
Returns header, reservations, node/property tree, derived standard values and
|
||||
selected phandle references. See [devicetree inspection](devicetree.md) for
|
||||
selected phandle references. See [devicetree inspection](../devicetree.md) for
|
||||
limits and retained-view pagination.
|
||||
|
||||
```bash
|
||||
@@ -1439,7 +1429,7 @@ rea inspect-pe-load-config /absolute/path/to/application.exe --json
|
||||
|
||||
Reports TLS callbacks and size-covered load-config fields without execution.
|
||||
Use `--max-callbacks` and `--max-file-bytes` to set read budgets. See
|
||||
[PE TLS and load configuration](pe-load-config.md).
|
||||
[PE TLS and load configuration](../pe-load-config.md).
|
||||
|
||||
### Binary hardening
|
||||
|
||||
@@ -1449,9 +1439,9 @@ rea inspect-binary-hardening /absolute/path/to/program --json
|
||||
|
||||
Reports ELF, PE, and Mach-O hardening rows without execution. A missing import
|
||||
is `unknown`, not `disabled`. Use `--max-file-bytes` to set the read budget. See
|
||||
[binary hardening](binary-hardening.md).
|
||||
[binary hardening](../binary-hardening.md).
|
||||
|
||||
Bun standalone executables use the existing `inspect-artifact` and
|
||||
`extract-artifact` commands to inventory and materialize embedded source,
|
||||
sourcemaps and bytecode without running the executable. See
|
||||
[Bun standalone executables](bun-standalone.md) for layout coverage and limits.
|
||||
[Bun standalone executables](../bun-standalone.md) for layout coverage and limits.
|
||||
@@ -43,7 +43,7 @@ Rerun setup to review the registration and restart the client.
|
||||
executable and environment of the terminal running doctor. It does not launch
|
||||
the client's configured command or reproduce the client's environment. If doctor
|
||||
passes but the client disconnects, inspect the client's startup error and registered
|
||||
launcher; see [verification scope](client-verification.md#launch-environment-verification).
|
||||
launcher; see [verification scope](../development/client-verification.md#launch-environment-verification).
|
||||
|
||||
`rea doctor` has the same limit for provider checks, and reports a provider setting
|
||||
the registration's file does not carry as a
|
||||
@@ -68,7 +68,7 @@ not update an already running MCP server or desktop client.
|
||||
To select this profile for an agent, set `REA_MCP_INPUT_SCHEMA_PROFILE` in that
|
||||
client's existing REA registration `env` object (`environment` for OpenCode) and
|
||||
restart the client, preserving its other settings. A successful terminal doctor run does not verify the client's
|
||||
launch environment. See [launch-environment verification](client-verification.md#launch-environment-verification)
|
||||
launch environment. See [launch-environment verification](../development/client-verification.md#launch-environment-verification)
|
||||
and the client-specific instructions below. REA setup forwards supported selections,
|
||||
including `REA_MCP_INPUT_SCHEMA_PROFILE`, from its environment into the registration;
|
||||
it does not copy unrelated environment values. Restoring the shell's previous
|
||||
@@ -83,7 +83,7 @@ raising a REA startup or operation deadline, separately ensure the client allows
|
||||
enough time for the full request. Use `inspect_analysis_settings` for the running
|
||||
server's defaults; `rea doctor` checks launch configuration and cannot observe
|
||||
another process's runtime overrides. See the
|
||||
[settings design](design/limits-and-recovery.md) for ownership and lifetime.
|
||||
[settings design](../design/limits-and-recovery.md) for ownership and lifetime.
|
||||
|
||||
## Client tool names and discovery
|
||||
|
||||
@@ -102,13 +102,15 @@ does not repair a client's naming behavior or infer permission drift from an
|
||||
unfamiliar prefix. The unavailable fork reported in
|
||||
[#5512](https://github.com/morluto/rea/issues/5512) has not been reverified.
|
||||
|
||||
<a id="hotcold-catalogs"></a>
|
||||
|
||||
## Hot/cold catalogs
|
||||
|
||||
For a client that supports MCP catalog refresh, set
|
||||
`REA_MCP_TOOL_CATALOG_PROFILE=hot-cold` in REA's server environment and restart
|
||||
the connection. REA then advertises a small initial catalog and loads other
|
||||
named tools through `discover_tools`. Setup preserves this explicit setting.
|
||||
See the [discovery contract](mcp-contracts.md#hotcold-catalog-discovery) for
|
||||
See the [discovery contract](../reference/mcp-contracts.md#hotcold-catalog-discovery) for
|
||||
pagination, identity and family-scope semantics.
|
||||
|
||||
Analysis tools, including `inspect_analysis_view`, load on demand. For example,
|
||||
@@ -155,7 +157,7 @@ REA_MCP_TOOL_CATALOG_PROFILE=full
|
||||
|
||||
This advertises all tools without requiring catalog refresh. Compact output
|
||||
schemas widen client-side validation; REA still validates complete results
|
||||
against the canonical contracts. See [output schemas](mcp-contracts.md#output-schemas).
|
||||
against the canonical contracts. See [output schemas](../reference/mcp-contracts.md#output-schemas).
|
||||
|
||||
On main `3e0599a94`, a real FastMCP 4.1.6 / Python MCP 2.3.0 HTTP client with
|
||||
the default 1 MiB SSE event limit rejected the 4,108,975-byte full catalog.
|
||||
@@ -179,7 +181,7 @@ receive limits and full Evidence access still apply.
|
||||
|
||||
Connect Fiddler Everywhere's MCP server separately for HTTP traffic debugging,
|
||||
preserving your REA client entry. See the
|
||||
[setup instructions and public skills](web-network-captures.md#fiddler-everywhere-mcp-and-public-skills).
|
||||
[setup instructions and public skills](../guides/web/web-network-captures.md#fiddler-everywhere-mcp-and-public-skills).
|
||||
|
||||
## VS Code
|
||||
|
||||
@@ -217,7 +219,7 @@ tool inventory on Linux using a loopback model fixture. After setup, add
|
||||
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).
|
||||
Windows remain unverified; see [native client verification](../development/testing.md).
|
||||
|
||||
## Claude Desktop
|
||||
|
||||
@@ -329,7 +331,7 @@ and Claude Code reports that autocompact is thrashing. To avoid this:
|
||||
override.
|
||||
- To remove entire tool families from the upfront catalog, run
|
||||
`rea setup --client claude_code --tool-families <ids>` with the families the
|
||||
workflow needs (see [the advertising scope contract](mcp-contracts.md#tool-family-advertising-scope)).
|
||||
workflow needs (see [the advertising scope contract](../reference/mcp-contracts.md#tool-family-advertising-scope)).
|
||||
Out-of-scope tools are not advertised and their calls fail with the SDK's
|
||||
disabled-tool error, so widen the selection when a task needs another
|
||||
family. Setup writes the scope into the entry's `env` as
|
||||
@@ -346,7 +348,7 @@ Both keep canonical result validation and complete structured results; `compact`
|
||||
keeps a widened root shape and `off` advertises nothing. On catalogs large
|
||||
enough that full input schemas alone approach the frame limit, also keep the
|
||||
input profile at its `compact` default. See [MCP output schema
|
||||
profiles](mcp-contracts.md#output-schemas).
|
||||
profiles](../reference/mcp-contracts.md#output-schemas).
|
||||
|
||||
## Kimi Code
|
||||
|
||||
@@ -391,7 +393,7 @@ doctor reports its readiness separately. Explicit selections override discovered
|
||||
defaults, including when setup runs again with a changed selection. Unrelated
|
||||
environment variables, process ownership tokens and one-shot target paths are not
|
||||
copied. For an explicitly configured startup target, see the
|
||||
[initial-target settings](mcp-contracts.md#initial-target-at-startup). Existing
|
||||
[initial-target settings](../reference/mcp-contracts.md#initial-target-at-startup). Existing
|
||||
client environment overrides remain intact unless setup supplies the same key.
|
||||
You can edit `startupTimeoutMs` and `toolTimeoutMs` there; doctor keeps positive
|
||||
caller-selected values aligned and reports a non-blocking advisory when a tool
|
||||
@@ -502,7 +504,7 @@ standalone CLI check.
|
||||
A model API's `400 INVALID_ARGUMENT` alone does not identify a rejected schema,
|
||||
tool-count limit or skill defect. Preserve the response's parameter path and
|
||||
diagnostic, the actual running REA version, Gemini CLI version and selected
|
||||
model. For schema rejection, review the [input presentation profiles](mcp-contracts.md#compact-input-schema-profile)
|
||||
model. For schema rejection, review the [input presentation profiles](../reference/mcp-contracts.md#compact-input-schema-profile)
|
||||
and reconnect after changing REA's registration environment. Compact is the
|
||||
current default; an explicitly stored `full` choice is preserved. The generic
|
||||
error in [#4620](https://github.com/morluto/rea/issues/4620) does not establish
|
||||
@@ -583,7 +585,7 @@ Responses-compatible Kimi gateway as “infinite recursion”; expanding those
|
||||
references succeeded. A separate full-profile input failed the provider's
|
||||
schema-size limit. These are distinct reported failures, not proof that the
|
||||
canonical schema is recursive. Current REA inputs are already self-contained;
|
||||
see [schema advertisement](mcp-contracts.md#schema-advertisement).
|
||||
see [schema advertisement](../reference/mcp-contracts.md#schema-advertisement).
|
||||
|
||||
For this failure, inspect the active MCP launch command and refresh the REA
|
||||
installation that command actually runs. A configured package selector or the
|
||||
@@ -832,7 +834,7 @@ 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)
|
||||
REA's optional [native client verification](../development/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.
|
||||
@@ -898,7 +900,7 @@ servers if you are adding REA to an existing configuration. `timeout_ms` is
|
||||
llama.cpp's per-tool-call timeout, including cold engine startup. The example
|
||||
allows REA's default 330-second Ghidra startup budget plus 120 seconds for the
|
||||
operation. Increase it if you configure a longer provider allowance or need more
|
||||
operation time; see [provider deadlines](mcp-contracts.md#ghidra-first-query-deadlines-and-recovery).
|
||||
operation time; see [provider deadlines](../reference/mcp-contracts.md#ghidra-first-query-deadlines-and-recovery).
|
||||
|
||||
Start the server with your own tool-capable GGUF model:
|
||||
|
||||
@@ -933,7 +935,7 @@ keep the server local, and select targets and operations you are authorized to u
|
||||
|
||||
See llama.cpp's [MCP server configuration](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md#mcp-servers)
|
||||
and [function-calling guidance](https://github.com/ggml-org/llama.cpp/blob/master/docs/function-calling.md).
|
||||
The [verification record](client-verification.md#llamacpp) distinguishes connection
|
||||
The [verification record](../development/client-verification.md#llamacpp) distinguishes connection
|
||||
checks from model behavior and lists the tested versions.
|
||||
|
||||
## Other client settings
|
||||
@@ -3,14 +3,14 @@
|
||||
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) |
|
||||
| Install a Claude Code/Codex plugin | [Agent plugins and marketplaces](#agent-plugins-and-marketplaces) |
|
||||
| Diagnose one task | [Scoped readiness checks](#check-readiness-for-your-task) |
|
||||
| Configure an analysis engine | [Hopper](#hopper), [Ghidra](#ghidra), the [IDA guide](ida-provider.md), or [Kuna](kuna-provider.md) |
|
||||
| Update or remove REA | [Maintenance](#diagnose-update-and-remove) |
|
||||
| Resolve a client-specific problem | [Client configuration](client-configuration.md) |
|
||||
| Task | Section |
|
||||
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| Connect an agent | [Start setup](#start-setup), then [review changes](#review-setup-changes) |
|
||||
| Install a Claude Code/Codex plugin | [Agent plugins and marketplaces](#agent-plugins-and-marketplaces) |
|
||||
| Diagnose one task | [Scoped readiness checks](#check-readiness-for-your-task) |
|
||||
| Configure an analysis engine | [Hopper](#hopper), [Ghidra](#ghidra), the [IDA guide](../providers/ida-provider.md), or [Kuna](../kuna-provider.md) |
|
||||
| Update or remove REA | [Maintenance](#diagnose-update-and-remove) |
|
||||
| Resolve a client-specific problem | [Client configuration](client-configuration.md) |
|
||||
|
||||
## Start setup
|
||||
|
||||
@@ -374,7 +374,7 @@ choosing an operation; it works before a target is opened, and
|
||||
`result.tool_availability` reports per-operation availability, reasons and
|
||||
client requirements for the current session state. It does not guarantee that
|
||||
a particular caller-supplied input will be valid. See
|
||||
[MCP discovery](mcp-contracts.md#identity-and-discovery).
|
||||
[MCP discovery](../reference/mcp-contracts.md#identity-and-discovery).
|
||||
|
||||
Select the part you want to check:
|
||||
|
||||
@@ -390,8 +390,15 @@ A scoped report has `scope.mode: "explicit"`. Its `scope_checks` determine
|
||||
`environment_healthy` summarizes the full audit. `--target` adds a target check,
|
||||
but the report remains audit-wide unless a scope option is also supplied.
|
||||
|
||||
Provider checks read the terminal running doctor. A client-started server may
|
||||
receive a different environment, and doctor cannot observe it. When an available
|
||||
With one selected client, Ghidra, IDA, JADX and Kuna provider checks use the
|
||||
client's recorded environment over the terminal it inherits. If that registration
|
||||
cannot be read or a setting a provider needs cannot be resolved, its available
|
||||
value is `null` and its check is `unknown`; its configured value is also `null`
|
||||
when the configuration setting itself is unknown. Doctor does not infer
|
||||
readiness from the terminal. A missing registration still uses terminal settings
|
||||
for setup. Other checks, including Hopper, use the terminal running doctor. A
|
||||
client-started server may receive a different environment, and doctor cannot
|
||||
observe it. When an available
|
||||
provider relies on a setting that a registration's file does not record, or
|
||||
records with other text, doctor adds a non-blocking
|
||||
`registration_environment:<client>` check with `classification: "unknown"`. The
|
||||
@@ -698,7 +705,7 @@ Linux architectures; configure [Ghidra](#ghidra) there instead. REA itself runs
|
||||
Linux distribution with a recognized apt, dnf, or pacman package family, where
|
||||
an existing Hopper launcher is selected through `HOPPER_LAUNCHER_PATH`. Ghidra
|
||||
and IDA have their own provider-specific host requirements; Windows Ghidra uses
|
||||
the [experimental P0 boundary](windows-ghidra-p0.md).
|
||||
the [experimental P0 boundary](../providers/windows-ghidra-p0.md).
|
||||
|
||||
Bazzite uses RPM packages, but REA does not install Hopper automatically on it.
|
||||
Setup skips the Hopper offer because Bazzite is outside the supported host list,
|
||||
@@ -1025,7 +1032,7 @@ output-stream closure; `output_closed: false` keeps that uncertainty explicit.
|
||||
Later requests retain the known exit instead of reducing it to socket loss.
|
||||
An external GUI's helper exit does not establish that the GUI itself exited.
|
||||
For cursor navigation, string decoding, symbol-name limits, and regex matching,
|
||||
see [Hopper analysis behavior](native-investigation.md#hopper-analysis-behavior).
|
||||
see [Hopper analysis behavior](../guides/native/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. The macOS Hopper application
|
||||
@@ -1150,13 +1157,13 @@ session metadata edits leave executable bytes unchanged and are discarded on clo
|
||||
require Hopper; Windows P0 remains read-only.
|
||||
|
||||
Windows P0 admits native x86, x86-64, ARMNT (Thumb-2) and ARM64 PE applications and DLLs,
|
||||
[DOS MZ executables](ghidra-dos.md), plus explicitly
|
||||
selected [raw NMOS 6502 images](raw-binary.md#nmos-6502) with a caller-supplied
|
||||
[DOS MZ executables](../providers/ghidra-dos.md), plus explicitly
|
||||
selected [raw NMOS 6502 images](../providers/raw-binary.md#nmos-6502) with a caller-supplied
|
||||
entry at file offset 0, on fixed local NTFS volumes. Other raw CPU families remain
|
||||
unsupported on Windows.
|
||||
The npm package bundles native Job Object ownership, protected private runtime
|
||||
DACLs, and handle-based path admission; no separate addon installation is needed.
|
||||
See the [Windows Ghidra P0 guide](windows-ghidra-p0.md) for verified scope and
|
||||
See the [Windows Ghidra P0 guide](../providers/windows-ghidra-p0.md) for verified scope and
|
||||
limitations.
|
||||
|
||||
Extract Ghidra and install the JDK outside REA, then export absolute paths:
|
||||
@@ -1199,7 +1206,7 @@ REA skill after approval. Managed registrations use the absolute selected Node o
|
||||
Bun runtime and REA entry script, including when setup ran through a package runner. Hopper
|
||||
installation remains unavailable on Windows. Setup never installs Ghidra,
|
||||
Java, or Python. It preserves valid detected Ghidra/JDK settings in agent
|
||||
registrations. See [Windows Ghidra P0](windows-ghidra-p0.md) for provider diagnostics.
|
||||
registrations. See [Windows Ghidra P0](../providers/windows-ghidra-p0.md) for provider diagnostics.
|
||||
|
||||
The separate `rea mcp add` builtin delegates most clients to Incur's package-runner
|
||||
child launcher. Run that acquisition from a trusted directory; prefer managed
|
||||
@@ -1317,7 +1324,7 @@ passes the deadline to each provider client; a startup failure is returned by th
|
||||
without exposing partial analysis. This deadline is separate from MCP transport
|
||||
initialization and the client's deadline for that individual tool call. A client
|
||||
can time out earlier even when Ghidra would complete within its startup deadline.
|
||||
See [Ghidra first-query deadlines and recovery](mcp-contracts.md#ghidra-first-query-deadlines-and-recovery)
|
||||
See [Ghidra first-query deadlines and recovery](../reference/mcp-contracts.md#ghidra-first-query-deadlines-and-recovery)
|
||||
for client options and the close/reopen recovery flow.
|
||||
|
||||
The 330-second default can be changed on a running MCP server by setting
|
||||
@@ -1370,7 +1377,7 @@ invocation instead. In MCP, `ghidra.decompile_timeout_seconds` can override the
|
||||
value for newly accepted operations on the existing Program; explicit `null`
|
||||
removes the deadline. A transient timeout remains uncached so the same function
|
||||
can be retried after an update. See the
|
||||
[settings design](design/limits-and-recovery.md#runtime-settings-through-mcp).
|
||||
[settings design](../design/limits-and-recovery.md#runtime-settings-through-mcp).
|
||||
Codex/Kimi registrations derived by `rea setup` add the selected launch value
|
||||
to the tool deadline as a single-decompile estimate; a runtime update does not
|
||||
change that registration. A bulk call can need that limit for
|
||||
@@ -1558,6 +1565,11 @@ For supported header-selected MIPS ELF targets, the profile also binds the
|
||||
selected target's ELF metadata; it does not claim a fresh-import MIPS lane was
|
||||
used for the saved project.
|
||||
A matching recorded import digest does not claim that the database is unedited.
|
||||
Caller and callee coverage therefore remains unknown. A single-direction query
|
||||
with known omissions remains partial and also reports the unknown project history.
|
||||
Observed call edges are still available: a path to an observed caller or callee
|
||||
can be reached, but a missing path is unknown when the project's prior analysis
|
||||
cannot establish completeness.
|
||||
Saved REA seed/analyzer reports remain historical facts in retained source Evidence;
|
||||
they are not interpreted as overrides applied by this session.
|
||||
Project content participates in snapshot identity, so different project states
|
||||
@@ -1735,7 +1747,7 @@ contains the launch arguments and `/proc/<jvm-pid>/status` reports
|
||||
session and retain the resource flags needed for the measurement rather than
|
||||
copying full command lines or environments into reports. Heap and affinity
|
||||
settings affect cost and latency; they are not part of REA's semantic analysis
|
||||
profile identity. See [real-provider testing](testing.md) for bounded
|
||||
profile identity. See [real-provider testing](../development/testing.md) for bounded
|
||||
verification workflows.
|
||||
|
||||
### Ghidra diagnostics and verification
|
||||
@@ -1845,7 +1857,7 @@ Code, `codex plugin list` in Codex).
|
||||
For analysis engines, ask the connected server: have the agent call
|
||||
`binary_session` and read `result.tool_availability`, which reports what the
|
||||
server the plugin started can use, with reasons and remediation. See
|
||||
[MCP contracts](mcp-contracts.md).
|
||||
[MCP contracts](../reference/mcp-contracts.md).
|
||||
|
||||
A plugin does not put `rea` on your `PATH`. To check an engine from a
|
||||
terminal, use the package runner at the version the plugin pins:
|
||||
File renamed without changes.
@@ -188,7 +188,7 @@ and during shutdown.
|
||||
property value remains available in `properties`.
|
||||
- **Device paths are not host paths.** `base_apk_device_path` values live on
|
||||
the device filesystem. Only pulls and captures produce host-local paths,
|
||||
each paired with byte size and SHA-256 digest. A pulled file's host name is
|
||||
with byte size and SHA-256 digest on success. A pulled file's host name is
|
||||
the device path's final POSIX segment. REA preserves the original device
|
||||
path and filename; a missing final segment or `.`/`..` is refused before
|
||||
output creation. Windows hosts follow [Windows filename rules](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file),
|
||||
@@ -249,6 +249,10 @@ and during shutdown.
|
||||
- Pull and capture outputs are additive: the destination must not already
|
||||
exist. Re-running a completed pull refuses the existing directory instead
|
||||
of overwriting evidence.
|
||||
- If a single-file pull fails and REA observes a regular file at the destination,
|
||||
the error includes its `local_path` with `transfer_status: "unconfirmed"`
|
||||
and `digest_status: "unknown"`. The file remains in place; the receipt does
|
||||
not establish that the transfer completed.
|
||||
- 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.
|
||||
@@ -288,7 +292,7 @@ Record: verified against adb 34.0.5 on Linux against an Android 14
|
||||
(API 34) x86_64 emulator — all operations above, a 224-package inventory,
|
||||
287 services, 92 features, a real two-APK split set pulled with byte-exact
|
||||
digests, a verified push/pull roundtrip, a 1.3 MB screen capture, and the
|
||||
complete package lifecycle; see `docs/testing.md` for the lane summary.
|
||||
complete package lifecycle; see `docs/development/testing.md` for the lane summary.
|
||||
|
||||
Intent integer extras use signed decimal text. The ADB argument encoder removes
|
||||
redundant leading zeros for Android's radix-sensitive `--ei` parser while retained
|
||||
@@ -6,12 +6,12 @@ kept as an unmodified, commit-pinned Git submodule; see
|
||||
application workflow and return artifact-bound Evidence inline.
|
||||
|
||||
This family is present on repository main and in npm 4.1.0. Check the
|
||||
[released package boundary](installation.md#released-package-and-main) and the
|
||||
[released package boundary](../../getting-started/installation.md#released-package-and-main) and the
|
||||
connected server's tool list before selecting it.
|
||||
|
||||
On Linux, JADX launches an REA-owned process and requires a procps-compatible
|
||||
`ps` on REA's `PATH`; see the shared
|
||||
[Linux process prerequisite](installation.md#linux-owned-process-prerequisite).
|
||||
[Linux process prerequisite](../../getting-started/installation.md#linux-owned-process-prerequisite).
|
||||
|
||||
## Optional package delivery
|
||||
|
||||
@@ -687,14 +687,14 @@ bounds each upstream call. Timeout recovery reports the effective milliseconds
|
||||
and range, with `details.limit` identifying the runtime setting. An invalid
|
||||
provider-local launch value can also be repaired by a runtime override; reset
|
||||
exposes that invalid launch value again. See the
|
||||
[settings design](design/limits-and-recovery.md#invalid-launch-configuration).
|
||||
[settings design](../../design/limits-and-recovery.md#invalid-launch-configuration).
|
||||
A passing JADX configuration check in `rea doctor` reports its launch-derived
|
||||
`operation_timeout_ms`; it does not inspect another running server's overrides. Explicit
|
||||
cancellation still ends the operation immediately, and partial observations
|
||||
and owned-process cleanup are unchanged. Raising the deadline does not extend
|
||||
the bridge's 30-second startup handshake or the upstream **90-second**
|
||||
decompilation limit. MCP clients enforce their own tool-call timeouts, and
|
||||
setup's derived [client tool timeout](client-configuration.md) does not include
|
||||
setup's derived [client tool timeout](../../getting-started/client-configuration.md) does not include
|
||||
this setting, so also raise the client timeout when selecting a longer
|
||||
deadline.
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ OpenJDK 25 against a signed aapt2-built probe APK carrying two resource
|
||||
locales — launcher version, on-disk digest agreement, apktool.yml metadata
|
||||
(1.2.3, SDK 24–34), manifest package agreement, default and `de` string
|
||||
tables projected. Parser goldens in the test suite come from the same
|
||||
decode. See `docs/testing.md` for the lane summary.
|
||||
decode. See `docs/development/testing.md` for the lane summary.
|
||||
|
||||
Multi-locale and table-only projection were also verified through real CLI and
|
||||
stdio MCP workflows on Linux with Apktool 3.0.3/JDK 21 against NewPipe 0.29.1,
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -90,9 +90,20 @@ column limit. The selected database is readable and is not reported as
|
||||
malformed; request fewer columns per call instead. `row_limit`
|
||||
requires `table`, defaults to 20 and accepts positive safe integers. Samples
|
||||
remain subject to the byte and worker resource limits below, regardless of row count. The result reports
|
||||
the selected limit, returned count and whether more rows were observed. Row
|
||||
order is unspecified; a truncated sample does not prove anything about omitted
|
||||
records. View, virtual-table and shadow-table row reads are unsupported.
|
||||
the selected limit, returned count and whether more rows were observed.
|
||||
|
||||
Rows are read in a stated unique order reported as `rows.order`: `rowid` for
|
||||
rowid tables, and `primary_key` for `WITHOUT ROWID` tables, reusing the
|
||||
primary-key index's own direction and declared collation. `rows.row_offset`
|
||||
reports the rows skipped before the window and `rows.next_row_offset` the offset
|
||||
to request for the following page; it is `null` once the window reaches the end.
|
||||
Pass `row_offset` (CLI `--row-offset`, requires `table`, default 0) to skip into
|
||||
a table rather than repeating earlier rows. A table that declares all of
|
||||
`rowid`, `_rowid_` and `oid` as columns and has no primary key reports
|
||||
`order: "unspecified"` and refuses a non-zero `row_offset`, because the skipped
|
||||
prefix would be arbitrary. Pages compose only while the reported database and
|
||||
WAL SHA-256 match; re-inspecting a changed snapshot restarts the sequence.
|
||||
View, virtual-table and shadow-table row reads are unsupported.
|
||||
|
||||
SQLite integers are decimal strings so every signed 64-bit value survives JSON
|
||||
serialization. Real values retain their numbers; `"Infinity"`, `"-Infinity"`
|
||||
File renamed without changes.
@@ -11,7 +11,7 @@ select a returned ELF separately for supported Ghidra analysis.
|
||||
|
||||
On Linux, Binwalk and Unblob run as REA-owned processes and require a
|
||||
procps-compatible `ps` on REA's `PATH`; see the shared
|
||||
[Linux process prerequisite](installation.md#linux-owned-process-prerequisite).
|
||||
[Linux process prerequisite](../../getting-started/installation.md#linux-owned-process-prerequisite).
|
||||
|
||||
## Compare stored firmware components
|
||||
|
||||
@@ -21,7 +21,7 @@ For supported FIT and legacy uImage containers, use the built-in
|
||||
Unblob or extraction: exact logical paths, stored-byte hashes and declared
|
||||
metadata establish component changes, with source Evidence and explicit unknowns.
|
||||
The outer container at `.` is separate from its children. See the
|
||||
[FIT version comparison recipe](fit-images.md#comparison) for CLI,
|
||||
[FIT version comparison recipe](../../fit-images.md#comparison) for CLI,
|
||||
MCP, summary delivery and selected supporting facts. Its real-data verification
|
||||
covers a pair of OpenWrt FIT releases; it does not establish comparison of
|
||||
decoded root filesystems or arbitrary firmware formats.
|
||||
@@ -209,7 +209,7 @@ Select a verified native child for the existing tools:
|
||||
|
||||
Then use `analyze_function`, `inspect_native_api` or the other native primitives.
|
||||
Native architecture and executable validation still apply. Generic
|
||||
[MIPS ELF](ghidra-mips.md) and [RISC-V ELF](ghidra-riscv.md) lanes are separate
|
||||
[MIPS ELF](../../providers/ghidra-mips.md) and [RISC-V ELF](../../providers/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.
|
||||
@@ -317,7 +317,7 @@ bootloader image, such as an OTA download or app partition, for its chip,
|
||||
classified segments, checksum and SHA-256 results, descriptor and Secure Boot
|
||||
v2 signature blocks. `extract-artifact` / `extract_artifact` writes one file
|
||||
per segment and signature block. Reading is portable and needs no external
|
||||
tool. See [ESP images](esp-image.md).
|
||||
tool. See [ESP images](../../esp-image.md).
|
||||
|
||||
## Inspect ESP flash dumps
|
||||
|
||||
@@ -328,11 +328,11 @@ facts for the bootloader and each app partition, and the OTA records with a
|
||||
derived selection; the running partition stays unknown. Extraction writes
|
||||
each partition, `nvs_keys` included, as an ordinary file. For a dump that
|
||||
does not start at flash address 0, select `esp-flash-image` with
|
||||
`flash_offset`. See [ESP flash images](esp-flash-image.md).
|
||||
`flash_offset`. See [ESP flash images](../../esp-flash-image.md).
|
||||
|
||||
## Inspect extracted devicetrees
|
||||
|
||||
Use [`inspect_devicetree`](devicetree.md) / `rea inspect-devicetree` on an
|
||||
Use [`inspect_devicetree`](../../devicetree.md) / `rea inspect-devicetree` on an
|
||||
extracted DTB for its node/property tree, reservations, hardware summary and
|
||||
selected phandle relationships. FDT v16/v17 inspection is portable and requires
|
||||
no external tool or disassembler.
|
||||
@@ -343,7 +343,7 @@ Use `inspect-artifact` / `inspect_artifact` on an Intel HEX or Motorola S-record
|
||||
file for its address regions, declared start address and record facts, then
|
||||
`extract-artifact` / `extract_artifact` for one raw file per region. Decoding is
|
||||
portable and requires no external tool. See
|
||||
[Intel HEX and S-record images](hex-records.md).
|
||||
[Intel HEX and S-record images](../../hex-records.md).
|
||||
|
||||
## Inspect U-Boot legacy uImages
|
||||
|
||||
@@ -356,7 +356,7 @@ is extractable as `payload.bin`, and multi-file and script images additionally
|
||||
expose each sub-image as `image-<n>.bin` from the stored size table. Declared
|
||||
addresses are facts from the header, not proven entry points, and compressed
|
||||
payloads stay as stored. Intel HEX/S-record and FIT images are separate
|
||||
readers and are not covered here. See [U-Boot legacy uImage](uimage.md) for
|
||||
readers and are not covered here. See [U-Boot legacy uImage](../../uimage.md) for
|
||||
component padding, preserved names, resource policies and verification scope.
|
||||
|
||||
## Inspect UF2 and DfuSe images
|
||||
@@ -366,7 +366,7 @@ address regions and its block numbering, or on a DfuSe file for its targets,
|
||||
elements and DFU suffix, then `extract-artifact` / `extract_artifact` for one
|
||||
raw file per region or element. A DfuSe suffix CRC mismatch follows
|
||||
`integrity_policy`. Decoding is portable and requires no external tool. See
|
||||
[UF2 and DfuSe images](uf2-dfuse.md).
|
||||
[UF2 and DfuSe images](../../uf2-dfuse.md).
|
||||
|
||||
## Inspect U-Boot FIT images
|
||||
|
||||
@@ -374,4 +374,4 @@ Use `inspect-artifact` / `inspect_artifact` on a U-Boot FIT (`.itb`) for its
|
||||
images, declared load and entry addresses, configurations and verified hashes,
|
||||
then `extract-artifact` / `extract_artifact` for one raw file per image.
|
||||
Decoding is portable and requires no external tool. See
|
||||
[U-Boot FIT images](fit-images.md).
|
||||
[U-Boot FIT images](../../fit-images.md).
|
||||
File renamed without changes.
@@ -6,7 +6,7 @@ Disconnecting the inspection's page session can clear caller-owned
|
||||
`navigator.platform` emulation inside Chromium. REA cannot restore another
|
||||
client's complete user-agent/client-hint configuration. Use a disposable target
|
||||
or let the owning client reapply its configuration; see the shared
|
||||
[CDP state limitation](browser-observation.md#provider-authorities).
|
||||
[CDP state limitation](../web/browser-observation.md#provider-authorities).
|
||||
|
||||
This passive runtime surface is distinct from the target-free static
|
||||
[`analyze_javascript_application`](javascript-artifact-reconstruction.md)
|
||||
@@ -14,7 +14,7 @@ workflow. Static analysis reads a local ASAR or extracted directory without
|
||||
executing application code. Passive observation inspects an existing Electron
|
||||
page. The results keep static inferences and runtime observations distinct.
|
||||
Packaged fuse state is a separate static read:
|
||||
[`inspect_electron_fuses`](electron-fuses.md) reports whether this binary will
|
||||
[`inspect_electron_fuses`](../../electron-fuses.md) reports whether this binary will
|
||||
honor Inspector flags, `ELECTRON_RUN_AS_NODE`, embedded ASAR integrity, and
|
||||
`app.asar`-only loading.
|
||||
Use the separate
|
||||
@@ -265,6 +265,9 @@ retained arrays and counters without invoking application iterators or Array
|
||||
species.
|
||||
|
||||
Listener-chain recognition distinguishes owned, unowned and unknown metadata.
|
||||
Only a directly owned wrapper establishes hook dispatch. An application's data
|
||||
link to an owned wrapper remains unknown: `.listener` can name that wrapper
|
||||
without invoking it.
|
||||
Data links may be inherited; absence is established only after completing the
|
||||
bounded prototype lookup. Exhausting either walk, encountering a getter or seeing a Proxy leaves
|
||||
ownership unknown. The hook preserves native registration without adding another
|
||||
@@ -328,7 +331,7 @@ budget used by static ASAR reads: 16 MiB / 16777216 bytes by default, seeded by
|
||||
`update_analysis_settings` can override `asar.max_header_bytes` for new
|
||||
operations without restarting REA. Cached headers are checked against each
|
||||
operation's admission, including after a decrease. See the
|
||||
[settings design](design/limits-and-recovery.md#failure-and-retry).
|
||||
[settings design](../../design/limits-and-recovery.md#failure-and-retry).
|
||||
An oversized header is
|
||||
not parsed; selecting a member path does not bypass admission, and the page
|
||||
stays unauthorized. The header cache separately retains at most that many bytes
|
||||
File renamed without changes.
+6
-3
@@ -50,6 +50,9 @@ A path-filtered reference reports the caller-selected path while keeping its
|
||||
shared node identity. Item selection also accepts any retained path when it
|
||||
identifies one module; if several module kinds share that path, select the
|
||||
reported `node_id`. Node-ID selection uses the stable representative path.
|
||||
Exported symbol bindings reuse the `javascript-module` kind but name one export
|
||||
of their owning module, so module pages, items, and summary counts include only
|
||||
module units and an exported module never becomes an extra path candidate.
|
||||
|
||||
## Retained module facts
|
||||
|
||||
@@ -180,7 +183,7 @@ large application can exceed one MCP response. Over MCP, pass
|
||||
the session and return only selected rows with the trace's identity and
|
||||
coverage. Page the retained trace with `inspect_analysis_view`; an oversized
|
||||
complete reply offers its first `paths` page as a ready-to-call continuation.
|
||||
See [MCP contracts](mcp-contracts.md) for filters. A handoff binds
|
||||
See [MCP contracts](../../reference/mcp-contracts.md) for filters. A handoff binds
|
||||
the exact native artifact digest and requested exports from the application
|
||||
graph. Trace direction selects the reachable addons; requested
|
||||
exports for each selected addon come from the complete supplied graph, so an
|
||||
@@ -632,7 +635,7 @@ All six CLI commands accept inline JSON or a path to a JSON file. The CLI
|
||||
returns an Evidence record directly. Later workflow inputs can contain full
|
||||
records, or exact retained references when `--evidence-bundle PATH` selects an
|
||||
authenticated exported bundle. A separate CLI process has no retained MCP
|
||||
connection state. See [CLI Evidence reuse](cli.md#import-export-and-compare-evidence).
|
||||
connection state. See [CLI Evidence reuse](../../getting-started/cli.md#import-export-and-compare-evidence).
|
||||
|
||||
File inputs must be regular files; symlinks to regular files are accepted.
|
||||
Directories, named pipes and device files produce an input error before JSON
|
||||
@@ -665,7 +668,7 @@ References are scoped to one connection; `close_binary` clears them. Export a
|
||||
bundle before closing and import it on another connection, or supply the full
|
||||
inline Evidence there. Versions before 4.1.0 accept full inline Evidence only; installing
|
||||
newer skill instructions does not change that schema. See
|
||||
[MCP Evidence inputs](mcp-contracts.md#retained-application-evidence-inputs).
|
||||
[MCP Evidence inputs](../../reference/mcp-contracts.md#retained-application-evidence-inputs).
|
||||
|
||||
For two operator-provided directories or ASARs, run:
|
||||
|
||||
+35
-5
@@ -86,6 +86,11 @@ properties and remains readable without migration.
|
||||
|
||||
## Select sources before analysis
|
||||
|
||||
Explicit `source_paths` retain the acquisition owner's requested order, including
|
||||
selected dependency files. First-party priority applies only to unscoped analysis.
|
||||
Recovered syntax or incomplete semantic examination keeps Electron coverage
|
||||
partial even when useful windows or IPC facts were retained.
|
||||
|
||||
For a question about known entry sources, supply exact artifact-relative file
|
||||
paths in `source_paths`, or repeat `--source-path` on either CLI route:
|
||||
|
||||
@@ -160,7 +165,7 @@ must also satisfy the new admission. For CLI or future MCP processes, set
|
||||
`REA_ASAR_MAX_HEADER_BYTES` in the launch environment. Changing that environment
|
||||
requires a new REA process. Invalid launch values are configuration errors,
|
||||
never a silent fallback. See the
|
||||
[settings design](design/limits-and-recovery.md#failure-and-retry) for recovery
|
||||
[settings design](../../design/limits-and-recovery.md#failure-and-retry) for recovery
|
||||
metadata, precedence, and reset behavior.
|
||||
|
||||
The archive index is read before any member can be selected, so
|
||||
@@ -255,7 +260,7 @@ those missing bytes. New ASAR file occurrences record `unpacked: true` for
|
||||
companion files and `unpacked: false` for packed entries, including when the
|
||||
file bytes are unavailable. An omitted flag in an older inventory remains
|
||||
unknown; it does not establish either storage mode. See
|
||||
[MCP integrity handling](mcp-contracts.md#integrity-record-and-continue) for the
|
||||
[MCP integrity handling](../../reference/mcp-contracts.md#integrity-record-and-continue) for the
|
||||
tool-result contract.
|
||||
|
||||
JavaScript whose syntax cannot be parsed retains unavailable semantic coverage
|
||||
@@ -280,7 +285,7 @@ does not bypass ASAR header/index admission.
|
||||
|
||||
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
|
||||
[MCP tool results](../../reference/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.
|
||||
@@ -306,7 +311,7 @@ and caller selection remain available without implying applicable AST work.
|
||||
|
||||
MCP returns a `partial_observation` retained reference after recording succeeds;
|
||||
open it with `inspect_analysis_view` on the same connection. If the SDK stopped
|
||||
waiting before receiving the reply, follow [MCP cancellation recovery](mcp-contracts.md#progress-and-cancellation)
|
||||
waiting before receiving the reply, follow [MCP cancellation recovery](../../reference/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.
|
||||
@@ -323,6 +328,12 @@ failure does not authorize expanding relationships that parent admission decline
|
||||
|
||||
## What is reconstructed
|
||||
|
||||
Electron `BrowserView` and `WebContentsView` expose `webContents` and accept
|
||||
`webPreferences`, including declared preloads. `BaseWindow` has neither surface
|
||||
of its own. Preload associations retain the parsed constructor's mechanism rather
|
||||
than labeling every view as a BrowserWindow. These are static associations, not
|
||||
proof that a renderer or preload executed.
|
||||
|
||||
The projector reuses the content-addressed artifact inventory and safe artifact
|
||||
readers. It retains canonical artifact-relative paths, exact byte counts,
|
||||
SHA-256 digests, inventory IDs, ASAR container identity, and `.asar.unpacked`
|
||||
@@ -515,6 +526,25 @@ If fingerprint construction reaches its structural
|
||||
bound, the fingerprint is unavailable and its status is `truncated`; a bounded
|
||||
prefix is never presented as a complete stable fingerprint.
|
||||
|
||||
## Cached-data compilation boundaries
|
||||
|
||||
The [feature specification](../../specs/javascript/v8-cached-data/spec.md) defines
|
||||
the static admission and uncertainty contract.
|
||||
|
||||
A `node:vm` compilation reports whether `cachedData` is declared, absent or
|
||||
unknown. Explicitly supplied undefined bytes are treated as absent; shadowed
|
||||
identifiers remain declarations. Source syntax alone does not establish valid cache bytes, V8 acceptance
|
||||
or execution. The summary counts declared compilations, not executions.
|
||||
|
||||
A proven synchronous filesystem read or awaited promise-based read supplies a
|
||||
cache path. The producer retains its path base: source-directory expressions
|
||||
can name inventoried artifacts, while relative literal paths depend on the
|
||||
target working directory and remain unresolved. Other supplied values retain
|
||||
their bounded source expression. Declared paths, exact-file lookup
|
||||
status, candidate paths and resolution limitations remain separate; an unresolved
|
||||
path never becomes a resolved file. Opaque inventoried cache bytes can remain
|
||||
unavailable to the JavaScript resolver even when their occurrence is known.
|
||||
|
||||
## Authority and unknowns
|
||||
|
||||
API identity is a derivation: a familiar method or property name does not
|
||||
@@ -810,7 +840,7 @@ analyzer; the caller's `NODE_OPTIONS` still controls the CLI/MCP process heap.
|
||||
For defaults across new MCP operations, use `update_analysis_settings` with
|
||||
`javascript.max_heap_mb` or `javascript.analysis_timeout_ms`. Explicit per-call
|
||||
arguments take precedence, and accepted work keeps its original settings. See
|
||||
the [settings design](design/limits-and-recovery.md#precedence-and-lifetime).
|
||||
the [settings design](../../design/limits-and-recovery.md#precedence-and-lifetime).
|
||||
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.
|
||||
@@ -149,6 +149,6 @@ non-retryable `resource_constraint` with `resource: "file-size"` and
|
||||
valid UTF-8 is an `invalid_format` request issue. These limits apply per
|
||||
operation and do not claim aggregate host containment across concurrent callers.
|
||||
|
||||
See [testing.md](testing.md#javascript-source-recovery) for the focused real
|
||||
See [testing.md](../../development/testing.md#javascript-source-recovery) for the focused real
|
||||
Wakaru CLI/MCP lane and its source-owned compiler fixtures. Other host platforms
|
||||
and Bun/Vue recovery are not claimed by this adapter.
|
||||
+10
-4
@@ -37,7 +37,7 @@ application starts, and REA never resumes it or sends
|
||||
caller-owned debugger before requesting application runtime observations.
|
||||
|
||||
For a packaged Electron app, read
|
||||
[`inspect_electron_fuses`](electron-fuses.md) before starting an `electron-main`
|
||||
[`inspect_electron_fuses`](../../electron-fuses.md) before starting an `electron-main`
|
||||
target. When `EnableNodeCliInspectArguments` is disabled or removed, Electron
|
||||
ignores `--inspect` and `--inspect-brk`. A missing main-process target after
|
||||
launch does not, by itself, show that fuse.
|
||||
@@ -114,7 +114,8 @@ caller cancellation still reports cancellation.
|
||||
The direct observations are:
|
||||
|
||||
- `Debugger.scriptParsed`, establishing that a bounded script location was
|
||||
parsed in the observed execution context;
|
||||
parsed with the reported execution-context ID; association with a particular
|
||||
context lifetime is known only when its creation was observed;
|
||||
- `Debugger.scriptFailedToParse`, retained only as a bounded invalid-script
|
||||
count in `scripts.parse_failed_total`. A well-formed parse-failure
|
||||
event is distinct from malformed protocol data and does not make loaded
|
||||
@@ -163,8 +164,13 @@ and collection overhead, and projected URL fields. Each CDP message also has a
|
||||
16 MiB transport limit. A message over that limit fails with `payload_limit`;
|
||||
when the aggregate budget is reached, later metadata events are dropped and
|
||||
the partial result reports `events_dropped`, `truncated: true`, and
|
||||
`retained_metadata_budget_exceeded`. Repeated context transitions update the
|
||||
current context record instead of accumulating duplicate objects. Scripts are
|
||||
`retained_metadata_budget_exceeded`. Context records retain each observed lifetime, and scripts refer to the context
|
||||
lifetime active when parsed. The reported numeric execution-context ID is
|
||||
retained separately on both records; a script with no observed context creation
|
||||
has an unknown context key. Repeated transitions within one lifetime update its
|
||||
record; the state records the last observed lifecycle event and does not prove
|
||||
that the context is still live. This changes context keys and Evidence identities from older captures;
|
||||
recapture observations to obtain lifetime associations. Scripts are
|
||||
validated after capture, deduplicated by stable metadata, and canonically
|
||||
sorted. Wall-clock timestamps and protocol script IDs are excluded from the
|
||||
durable result, so identical inputs and captured metadata produce the same
|
||||
File renamed without changes.
@@ -0,0 +1,121 @@
|
||||
# V8 code cache inspection
|
||||
|
||||
`inspect_v8_code_cache` reads one explicitly selected V8 code cache container as static
|
||||
bytes: a bytenode `.jsc`, the bytes `vm.Script.createCachedData()` writes, or a cache
|
||||
carried inside a Node single-executable application or an Electron app. It never executes
|
||||
the file, never starts a V8 runtime, never installs bytenode, and never invokes a
|
||||
decompiler.
|
||||
|
||||
```bash
|
||||
rea inspect-v8-code-cache /absolute/path/to/module.jsc --json
|
||||
rea inspect-v8-code-cache /absolute/path/to/module.jsc --minStringBytes 8 --json
|
||||
```
|
||||
|
||||
The MCP tool is `inspect_v8_code_cache` with the same inputs and the same retained
|
||||
Evidence.
|
||||
|
||||
## What is read
|
||||
|
||||
A V8 code cache is a producer-written container, not a documented file format. This reader
|
||||
admits one container shape and reports everything else as an observation, so a build it
|
||||
has never seen still yields facts instead of a false parse.
|
||||
|
||||
The 32-byte header is eight little-endian 32-bit words. Every word is reported in
|
||||
`header.fields` with its byte offset, its observed value, the role this reader believes it
|
||||
has, and how confident that role is:
|
||||
|
||||
| Offset | Role | Status |
|
||||
| -------------- | -------------- | ----------- |
|
||||
| `0x00` | magic | confirmed |
|
||||
| `0x04` | version hash | inferred |
|
||||
| `0x08` | source length | confirmed |
|
||||
| `0x0c` | flag hash | inferred |
|
||||
| `0x10` | build constant | inferred |
|
||||
| `0x14` | payload length | confirmed |
|
||||
| `0x18`, `0x1c` | reserved | unconfirmed |
|
||||
|
||||
`confirmed` means the role is demonstrated by the reader's own tests against the producer.
|
||||
`inferred` means the word's behaviour is consistent with the role but a different producer
|
||||
could plausibly differ. `unconfirmed` means the word is reported and nothing more is
|
||||
claimed.
|
||||
|
||||
Only three facts gate admission:
|
||||
|
||||
1. the header size this reader pins (32 bytes);
|
||||
2. the V8 code cache magic high half, `0xc0de`. The low half is
|
||||
`ExternalReferenceTable::kSize` and varies per V8 build, so it is reported as a build
|
||||
fingerprint and never required to match a fixed value;
|
||||
3. the declared payload length must equal the bytes that follow the header exactly.
|
||||
|
||||
`header.source_length` is the producer's recorded source length in UTF-16 code units.
|
||||
V8's serializer calls this field the source hash; on the producers measured here its value
|
||||
equals the source length exactly, including sources whose UTF-8 byte length differs, so the
|
||||
reader reports it under the name the measurement supports. Treat that name as an
|
||||
observation, not as a claim about what any other build stores there.
|
||||
`header.producer` names the producer family from the flag bits in that word. Bit 29
|
||||
marks `vm.compileFunction` (`compile_function`); bit 30 marks `vm.SourceTextModule`
|
||||
(`module`). When neither flag is present, the producer remains `unknown`:
|
||||
`vm.Script`, bytenode output and older unflagged function caches cannot be
|
||||
separated by those bits alone. The source-length mask is `0x1fffffff`, so both
|
||||
flags sit outside the reported length. This describes the admitted header
|
||||
profile rather than a version-independent V8 ABI.
|
||||
|
||||
## Failed inspection and provenance
|
||||
|
||||
After a stable read completes, format and observation-budget refusals retain a
|
||||
`file-snapshot-hash` partial observation with the selected path, exact SHA-256 and
|
||||
byte count. This proves which bytes were read; it does not claim the format was
|
||||
successfully decoded. A refusal before read completion does not invent an identity.
|
||||
Descriptor cleanup remains owned for retry if finalization fails.
|
||||
|
||||
## Embedded byte patterns
|
||||
|
||||
`embedded_strings` lists printable runs found in the payload, each with its absolute byte
|
||||
offset in the selected file and its observed byte length. `min_string_bytes` (default 4)
|
||||
sets the shortest reported run; `max_strings` caps how many may be reported, and exceeding
|
||||
it fails without partial success.
|
||||
|
||||
These are **byte-pattern observations inside serialized V8 heap data, not parsed heap
|
||||
objects**. A reported run is not proof V8 retained it as a string. A literal that is absent
|
||||
from the payload is not proof it is absent from the program: V8 may encode a string in a
|
||||
form the run scan does not surface, and a string can be produced at runtime rather than
|
||||
retained.
|
||||
|
||||
A run longer than 4096 bytes is reported with `truncated: true` and a `retained_bytes`
|
||||
prefix.
|
||||
|
||||
## Limitations
|
||||
|
||||
Every result states these, and they are part of the contract:
|
||||
|
||||
- the payload is serialized V8 heap data, not source; no logic is recovered and no
|
||||
bytecode is decompiled;
|
||||
- recovering logic needs a version-pinned V8 decompiler (View8-style) that this tool
|
||||
neither provides nor depends on;
|
||||
- header roles beyond magic, source length, and payload length are version-dependent
|
||||
observations;
|
||||
- the tool never executes the selected file and never claims recovered source.
|
||||
|
||||
## Failure behaviour
|
||||
|
||||
An unknown magic is a typed `unsupported_target` failure, because the file is not a V8
|
||||
code cache. A short header, a payload-length disagreement, or bytes past the declared
|
||||
payload is a typed `invalid_request` failure. Neither is a partial parse, and no Evidence
|
||||
is recorded for them.
|
||||
|
||||
`max_file_bytes` (default 32 MiB, ceiling 64 MiB) is the caller-selected read budget. The
|
||||
payload SHA-256 is computed over the declared payload, so two containers with the same
|
||||
payload length and content but different version hashes have different whole-file digests
|
||||
and identical payload digests.
|
||||
|
||||
## Relationship to other tools
|
||||
|
||||
- `inspect_binary_layout` reads the surrounding ELF/PE container of a single-executable
|
||||
application; it does not decode the embedded code cache.
|
||||
- A cache embedded in a Node single-executable application or an Electron app must be
|
||||
**extracted first**: this reader admits a container whose magic is at byte zero, so
|
||||
passing the surrounding ELF/PE executable here returns `unsupported_target`. Run
|
||||
`extract_artifact` on the application, then pass the extracted `.jsc` path to this tool.
|
||||
- `inspect_artifact` inventories the file without decoding V8 structures.
|
||||
- This tool is in the same family as `inspect_python_pyc`, `inspect_erlang_beam`, and
|
||||
`inspect_kernel_module`: one explicit local file, bounded parsing, no execution.
|
||||
@@ -24,7 +24,7 @@ Native-body bridge mapping and managed runtime execution are outside the
|
||||
current tool set.
|
||||
|
||||
The canonical tool inventory is the
|
||||
[build-generated catalog](mcp-contracts.md#generated-catalog).
|
||||
[build-generated catalog](../../reference/mcp-contracts.md#generated-catalog).
|
||||
|
||||
## Inspect an assembly
|
||||
|
||||
@@ -212,13 +212,9 @@ rea inspect-managed-members /absolute/path/Assembly.dll --type Namespace.Type \
|
||||
bundle format. Its parent directory must exist, and it never replaces an
|
||||
existing path. Relative paths resolve against the command's working directory.
|
||||
The option also works with complete delivery when a saved bundle is useful.
|
||||
Summary without a destination is rejected before analysis. A publication failure
|
||||
returns a typed error with the completed Evidence under
|
||||
`details.partial_observation`; it does not report successful summary delivery.
|
||||
Cancellation before publication prevents the new output. Once atomic
|
||||
publication has started, it can complete despite cancellation; a cancelled
|
||||
delivery then retains the committed path and byte count under
|
||||
`details.diagnostics.evidence_bundle`.
|
||||
Summary without a destination is rejected before analysis. For partial Evidence
|
||||
and committed-file receipts after failure or cancellation, see
|
||||
[Evidence publication and source recovery](../../reference/mcp-contracts.md#evidence-publication-and-source-recovery).
|
||||
|
||||
Copy `normalized_result.parent_evidence_id` from the summary into the
|
||||
`source.evidence_id` field of the `managed-members` request above, then save that
|
||||
@@ -245,13 +241,13 @@ The canonical parser admits PE/CLI bytes and their metadata/CIL without loading
|
||||
an assembly. It reports observed implementation markers and unavailable facts;
|
||||
it does not itself unpack .NET single-file hosts or infer a NativeAOT identity
|
||||
from an ordinary native PE. It does not decode IL2CPP; use
|
||||
[IL2CPP metadata](il2cpp-metadata.md) for the image, type and method names in a
|
||||
[IL2CPP metadata](../../il2cpp-metadata.md) for the image, type and method names in a
|
||||
Unity `global-metadata.dat`. Inputs without admitted CLI metadata do not
|
||||
become managed assemblies through naming or routing guesses.
|
||||
Inspect separately obtained components explicitly and preserve their identities.
|
||||
|
||||
For ordinary .NET single-file hosts, use the existing artifact tools to
|
||||
[inventory and extract bundle members](dotnet-bundles.md), then inspect the
|
||||
[inventory and extract bundle members](../../dotnet-bundles.md), then inspect the
|
||||
extracted assembly explicitly with the managed tools.
|
||||
|
||||
A valid implementation marker establishes a candidate native boundary, not
|
||||
@@ -608,13 +604,13 @@ describes exported shared-library entry points.
|
||||
REA offers a built-in read-only snapshot parser for x64 PE/RTR 9.1 metadata and
|
||||
an optional Linux headless Ghidra adapter for annotations and broader recovery.
|
||||
The adapter requires a locally built `REA_GHIDRA_NATIVEAOT_JAR`; REA does not
|
||||
install it or its toolchain. The [NativeAOT guide](ghidra-nativeaot.md) defines
|
||||
install it or its toolchain. The [NativeAOT guide](../../providers/ghidra-nativeaot.md) defines
|
||||
these routes, their layout/host restrictions, derived-memory provenance, and
|
||||
verification coverage.
|
||||
|
||||
REA's experimental Windows Ghidra boundary admits native x86, x86-64, ARMNT (Thumb-2) and ARM64 PE
|
||||
applications and DLLs for static analysis. For x64 PE NativeAOT, the read-only
|
||||
parser also runs there; the [NativeAOT guide](ghidra-nativeaot.md) lists what a
|
||||
parser also runs there; the [NativeAOT guide](../../providers/ghidra-nativeaot.md) lists what a
|
||||
Windows host covers.
|
||||
|
||||
For NativeAOT analysis, preserve the selected native artifact's path and digest
|
||||
@@ -623,6 +619,7 @@ to native function addresses requires verified
|
||||
provider evidence; names or vtable similarity alone do not prove that a native
|
||||
function implements a specific managed method.
|
||||
|
||||
<div id="managednative-boundary-rules"></div>
|
||||
<div id="managed-native-boundaries"></div>
|
||||
|
||||
## Managed/native boundary rules
|
||||
@@ -677,7 +674,7 @@ partial when unknown MethodDef ownership can hide a selected body.
|
||||
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.
|
||||
[Ghidra NativeAOT extension](../../providers/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,
|
||||
@@ -849,7 +846,7 @@ Target platform is not host support. The canonical parser must inspect
|
||||
Windows-produced PE/CLI bytes on REA's supported Linux and macOS hosts with the
|
||||
same result. Pinned Windows oracle jobs may provide additional conformance, but
|
||||
do not establish that the REA managed analysis workflow has been verified on a
|
||||
Windows host. The [experimental Windows Ghidra boundary](windows-ghidra-p0.md)
|
||||
Windows host. The [experimental Windows Ghidra boundary](../../providers/windows-ghidra-p0.md)
|
||||
has its own host and provider verification scope. Native
|
||||
ReadyToRun, C++/CLI, NativeAOT, or IL2CPP coverage is additionally constrained
|
||||
by the selected Hopper/Ghidra host and format matrix.
|
||||
@@ -860,7 +857,7 @@ The current lane uses source-owned byte-built fixtures and malformed-input
|
||||
regressions, with optional operator-supplied applications and ILSpy verification.
|
||||
|
||||
Run the deterministic lane with `npm run verify:managed`. See
|
||||
[testing](testing.md#real-toolchain-verification-lanes) for prerequisites and
|
||||
[testing](../../development/testing.md#real-toolchain-verification-lanes) for prerequisites and
|
||||
coverage. Generated outputs belong outside tracked fixture directories and must
|
||||
not remain after verification or packaging.
|
||||
|
||||
@@ -125,7 +125,7 @@ reply budget applies to the decoder record; the CLI/MCP Evidence envelope adds
|
||||
copies and encoding overhead. The
|
||||
pinned MCP SDK defaults to a 10 MiB receive buffer. Large complete results need
|
||||
a caller-configured `StdioClientTransport({ maxBufferSize: ... })` and a matching
|
||||
server `REA_MCP_MAX_RESPONSE_BYTES`. See [MCP delivery budgets](mcp-contracts.md#tool-results).
|
||||
server `REA_MCP_MAX_RESPONSE_BYTES`. See [MCP delivery budgets](../../reference/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,
|
||||
@@ -272,6 +272,12 @@ regular files only and rejects symbolic links.
|
||||
|
||||
## Byte entropy triage
|
||||
|
||||
Entropy admission preserves the caller's spelling in `caller_input_path`. On
|
||||
Windows, the selected regular file's case-only filesystem spelling is used
|
||||
consistently in committed paths through both CLI and MCP. Symlink, junction and
|
||||
short-name aliases are not replaced with a different path. General path
|
||||
normalization remains lexical and does not probe source-discovered paths.
|
||||
|
||||
`inspect_byte_entropy` / `inspect-byte-entropy` profiles any local regular file
|
||||
without an analysis engine, execution, extraction or network access.
|
||||
|
||||
@@ -49,14 +49,16 @@ selected dependency versions without reopening the file:
|
||||
}
|
||||
```
|
||||
|
||||
Go views support `dependencies` (exact `paths`) and `settings` (exact `keys`),
|
||||
optional original `indices`, field selection, and pagination. Filters intersect;
|
||||
empty filter arrays select no rows and `fields: []` returns only row identity.
|
||||
Each row keeps its original `index`, scoped to the parent Evidence and collection;
|
||||
duplicate module paths and setting keys keep distinct indices. Page offsets
|
||||
count matching records. Exhausting retained rows does not establish complete
|
||||
runtime dependencies. Original bytes, unknown lines and all complete metadata
|
||||
remain in the parent and can be exported as an Evidence bundle.
|
||||
Go views support `dependencies` (exact `paths`), `settings` (exact `keys`) and,
|
||||
when collected with `include_string_literals: true`, `string_literals` (exact
|
||||
`values` and substring `contains`), plus optional original `indices`, field
|
||||
selection, and pagination. Filters intersect; empty filter arrays select no rows
|
||||
and `fields: []` returns only row identity. Each row keeps its original `index`,
|
||||
scoped to the parent Evidence and collection; duplicate module paths and setting
|
||||
keys keep distinct indices. Page offsets count matching records. Exhausting
|
||||
retained rows does not establish complete runtime dependencies or string
|
||||
coverage. Original bytes, unknown lines and all complete metadata remain in the
|
||||
parent and can be exported as an Evidence bundle.
|
||||
|
||||
One-shot CLI summaries save complete Evidence before returning the projection:
|
||||
|
||||
@@ -113,6 +115,22 @@ their empty dependency array does not establish the absence of dependencies.
|
||||
The result's limitations state this explicitly. A module-mode build with a main
|
||||
module record and no dependency records has an observed empty dependency list.
|
||||
|
||||
When `include_string_literals: true` (CLI `--include-string-literals`, optional
|
||||
`max_string_literals` / `--max-string-literals`, default `2000`, maximum `10000`)
|
||||
is selected, `string_literals` reports `evidence_kind: "inferred"` alongside
|
||||
deduplicated printable UTF-8 literals referenced by word-aligned two-word
|
||||
`(ptr, len)` string headers in non-executable initialized data. Because Go packs
|
||||
read-only string data contiguously without NUL terminators, slicing by `(ptr, len)`
|
||||
recovers exact literal boundaries instead of concatenated C-string runs. Each
|
||||
target slice (`1`–`4096` bytes) must stay within a single read-only mapped
|
||||
section or segment, decode as printable UTF-8 (`\t`, `\n`, `\r`, joiners
|
||||
`U+200C` / `U+200D` and printable Unicode scalar values, excluding control and
|
||||
other format characters), and fit within
|
||||
a 64 MiB header-scan budget and 512 KiB aggregate string budget
|
||||
(`truncated: true` when capped). Compiler-inlined or
|
||||
stack-constructed strings without static headers, unapplied relocation addends
|
||||
and Mach-O `LC_DYLD_CHAINED_FIXUPS` pointer encodings are noted in `limitations`.
|
||||
|
||||
## Supported boundary
|
||||
|
||||
The built-in TypeScript reader supports ELF, PE and thin Mach-O images, and one
|
||||
@@ -196,7 +214,7 @@ the same virtual alignment are searched once; partially overlapping spans
|
||||
consume the cumulative search budget
|
||||
and fail with a CPU resource constraint when it is exhausted. Oversized results
|
||||
fail without partial success. MCP also applies
|
||||
its [response transport budget](mcp-contracts.md), which counts both text and
|
||||
its [response transport budget](../../reference/mcp-contracts.md), which counts both text and
|
||||
structured content; a report within the metadata limit can still require export
|
||||
from retained Evidence. These limits are not operating-system memory or CPU
|
||||
isolation.
|
||||
@@ -21,7 +21,7 @@ breakpoint names.
|
||||
|
||||
## Start with a function
|
||||
|
||||
Choose an installed provider from [setup](installation.md#hopper). For Ghidra:
|
||||
Choose an installed provider from [setup](../../getting-started/installation.md#hopper). For Ghidra:
|
||||
|
||||
```bash
|
||||
rea inspect /absolute/path/to/program --provider ghidra --json
|
||||
@@ -83,6 +83,9 @@ its address when selecting the containing function. `search_procedures` matches
|
||||
the same names, in leaf or qualified spelling: the function appears once with
|
||||
its primary name as `value`, and `matched_aliases` lists the qualified names of
|
||||
the secondary symbols that matched.
|
||||
For Ghidra case-insensitive literal searches of procedures or strings,
|
||||
`raw_result` contains bridge candidates before REA applies Unicode-aware
|
||||
matching. Use `normalized_result` for matches; a raw candidate need not match.
|
||||
Overloads can share a fully qualified name; ambiguity errors return every
|
||||
matching entry address so the caller can select the intended function directly.
|
||||
|
||||
@@ -97,6 +100,36 @@ body are excluded. `procedure_references` returns internal and external edges;
|
||||
The reference collector's semantics participate in the analysis profile, so
|
||||
older snapshots cannot replay the former incomplete results under this profile.
|
||||
|
||||
For a bounded handoff, request `procedure_references` with `detail: "summary"`.
|
||||
The summary retains the complete observation and reports the selected procedure,
|
||||
direction and counts. Page it with `inspect_analysis_view`, using the summary's
|
||||
`normalized_result.parent_evidence_id` and a view such as
|
||||
`{"kind":"native-procedure-references","collection":"references","source_address":"0x1234","offset":0,"limit":64}`.
|
||||
The optional exact source and target filters apply before paging. A row's
|
||||
`source_index` identifies it in the original retained collection, including
|
||||
duplicates. Endpoint `kind: "selected-procedure"` refers to the full procedure
|
||||
in the page summary; `kind: "null"` preserves the original null without asserting
|
||||
why it was unavailable. `kind: "shared"` carries an index into `items.endpoints`,
|
||||
where each other procedure object is stored once per page. Use collection
|
||||
`unresolved_calls` for paged unresolved call sites and their original reasons.
|
||||
Page coverage describes retained rows, not complete provider discovery or runtime
|
||||
execution. A 1 MiB projection allowance, also used by other bounded analysis views, can
|
||||
shorten a requested page; `byte_limited: true` and `coverage.next_offset` identify the
|
||||
continuation. A single row or summary that cannot fit returns a resource error;
|
||||
retrieve or export the complete parent Evidence. This allowance has no runtime
|
||||
override. Omit detail to receive the complete observation inline.
|
||||
|
||||
For a one-shot CLI handoff, save the complete Evidence and its linked sources:
|
||||
|
||||
```bash
|
||||
rea procedure-references /absolute/path/to/program my_function --provider ghidra \
|
||||
--direction incoming --detail summary --evidence_output /absolute/path/to/references.json
|
||||
```
|
||||
|
||||
Use `rea inspect-analysis-view` with that bundle as an `evidence-file` source to
|
||||
page it without reopening the target. This command requires a provider supporting
|
||||
`procedure_references`; Kuna currently reports that capability unavailable.
|
||||
|
||||
Ghidra regex searches use Java Pattern semantics. If compiling or matching a
|
||||
pattern exhausts the engine's stack, REA returns a resource constraint and
|
||||
preserves the active database and annotations. Retry in literal mode or simplify
|
||||
@@ -225,7 +258,7 @@ single-procedure CLI operation.
|
||||
`detail: "summary"` retains the complete batch and returns only its counts,
|
||||
identities and sizes. `inspect_analysis_view` then reads rows or one body from
|
||||
the retained record, an Evidence file or a portable bundle without repeating
|
||||
decompilation: see [selected batch results](mcp-contracts.md#selected-batch-decompile-results).
|
||||
decompilation: see [selected batch results](../../reference/mcp-contracts.md#selected-batch-decompile-results).
|
||||
|
||||
Each batch schedules one provider read at a time, but has no shared input-count
|
||||
or aggregate retained-output allowance. It retains every requested row and full
|
||||
@@ -252,8 +285,18 @@ The manifest reports the procedure-inventory limitations of the current call in
|
||||
call's filters, selected and excluded counts, and inventory limitations; older
|
||||
runs remain represented only by their retained function records, so a later
|
||||
inventory warning is not presented as the history of every file.
|
||||
Use `retry_failed: "independent_fresh"` (CLI: `--retry-failed independent_fresh`)
|
||||
to request an independent attempt after a null pseudocode observation that the
|
||||
provider explicitly reports as a function failure. The failed observation is
|
||||
appended before the retry, so cancellation or a later failure keeps it. The
|
||||
retry can use different analysis context. Other errors and entries merely
|
||||
missing from an export are not retried. A null without a reported function
|
||||
failure carries a limitation explaining why no independent retry was attempted.
|
||||
A provider that does not report this distinction leaves the cause unknown.
|
||||
Each function's `decompile-index.json` record, whatever its status, keeps the
|
||||
complete limitations of the observations it used.
|
||||
complete limitations of the observations it used. The index keeps the latest
|
||||
record for each function; `decompile-journal.jsonl` keeps earlier attempts and
|
||||
their separate limitations.
|
||||
When available, `provider_source` records the source of that attempt's
|
||||
pseudocode observation: a file path, SHA-256 and byte range, or a
|
||||
single-function decompile. The latter describes the method, not a unique run. A file
|
||||
@@ -289,6 +332,10 @@ crashed run can be recovered by the next run. Failed descriptor or staging clean
|
||||
could not be written or read, for example on a full disk, the export stops with
|
||||
an error instead of decompiling the rest. Files and records already committed
|
||||
stay, `decompile-index.json` is still written, and a later resume continues.
|
||||
If the index was published before cancellation or a later failure, the error's
|
||||
`diagnostics.published_output` retains its `output_directory` and `index_path`.
|
||||
This receipt confirms publication, not completion of every selected function.
|
||||
Failed staging cleanup retains the same receipt through cleanup retry.
|
||||
|
||||
Type inspection selects one exact database pathname or typed data address.
|
||||
Struct/union fields, enums, pointers, arrays, typedefs, size, alignment, packing
|
||||
@@ -370,7 +417,7 @@ configuration errors and do not fall back to 128. The setting is read from
|
||||
the environment that starts REA, while MCP `regex.worker_heap_request_mib`
|
||||
can override it for workers belonging to newly accepted searches. Use
|
||||
`update_analysis_settings` for either runtime control; accepted work keeps its
|
||||
budget. See the [settings design](design/limits-and-recovery.md).
|
||||
budget. See the [settings design](../../design/limits-and-recovery.md).
|
||||
A heap failure names the effective request, known source, default, floor, and
|
||||
maximum. A positive Node.js
|
||||
`--max-old-space-size` on the process that starts
|
||||
@@ -531,8 +578,17 @@ The raw Java `is_dead` flag can remain set after Ghidra decodes a live block;
|
||||
`block_membership` reports actual syntax-tree membership separately.
|
||||
|
||||
The provider dossier itself retains up to 3,000 p-code operations, 64 inputs per
|
||||
operation and 12,000 def-use edges, with explicit omitted counts. A `STORE`
|
||||
may describe stack memory and does not itself prove persistent state.
|
||||
operation and 12,000 def-use edges, with explicit omitted counts. Memory effects
|
||||
cover high-p-code `LOAD` and `STORE` operations; direct memory address varnodes
|
||||
in other operations are excluded, so an empty effect list does not establish
|
||||
that the function accesses no memory. `procedure_references` can supply
|
||||
complementary recorded instruction references, with its own coverage limits. A
|
||||
`STORE` may describe stack memory and does not itself prove persistent state.
|
||||
The Ghidra analysis profile commits to this effect scope. Snapshots from before
|
||||
that commitment are rejected; analyze without the snapshot and save a fresh one.
|
||||
To keep historical Evidence, copy the old snapshot's `evidence_bundle` object to
|
||||
a separate JSON file and import that bundle. Import validates the Evidence; it
|
||||
does not replay the old provider analysis.
|
||||
|
||||
Jump-table evidence keeps numeric `mappings`, explicit `default_targets`, and
|
||||
backing `data_sources` separate. A null case value denotes an unresolved
|
||||
@@ -622,11 +678,12 @@ node of the decoder's DOM at a measured upper bound, so a plist made of many
|
||||
small elements reaches it at a few MiB of source. JSON decode memory has not
|
||||
been measured and has no equivalent decode estimate. A refused input reports non-retryable `resource_constraint` with
|
||||
`reported_limits.maximum_input_bytes` or `maximum_decoded_bytes` as applicable.
|
||||
Ordinary direct-source decoding has a ceiling of 998 source nesting levels,
|
||||
derived from the existing 1000-level JSON result capacity by reserving one level
|
||||
for typed scalar fields and one for the result's `value` field. Deeper input reports
|
||||
`resource_constraint` with `reported_limits.maximum_nesting_depth: 998` and names
|
||||
the fixed nesting allowance. XML admission also requires native validation, which
|
||||
Ordinary direct-source decoding has a ceiling of 997 source nesting levels,
|
||||
derived from the existing 1000-level JSON result capacity. Three levels are
|
||||
reserved for typed scalar fields, the report value and its Evidence envelope.
|
||||
Deeper input reports `resource_constraint` with
|
||||
`reported_limits.maximum_nesting_depth: 997` and names the fixed nesting allowance.
|
||||
XML admission also requires native validation, which
|
||||
can refuse input below this decoding ceiling. Compatibility conversions can
|
||||
likewise encounter an earlier native utility refusal; both retain native
|
||||
diagnostics. Archive and Interface Builder decoding retain their separate
|
||||
@@ -757,7 +814,7 @@ complete observation.
|
||||
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).
|
||||
[Apple application analysis](../apple/apple-application-analysis.md#dylib-load-resolution).
|
||||
ARM64 slice labels distinguish `arm64v8`, `arm64e`, and `arm64e.x1` while
|
||||
retaining raw CPU subtype and capability bits. The `arm64` and `arm64e`
|
||||
request filters select their respective families; a shared family label
|
||||
@@ -1078,6 +1135,9 @@ original JSON scalar types. Values that JSON cannot represent faithfully,
|
||||
including unsafe integers, negative zero and non-finite numbers, remain null
|
||||
with a path-specific gap and incomplete capture coverage. Null alone does not
|
||||
establish that an accessibility value was successfully read or absent.
|
||||
Failed role, title, value or action reads add a path-specific gap and mark the
|
||||
capture truncated. An empty `actions` array with an action-read gap means the
|
||||
available actions are unknown.
|
||||
|
||||
An initial PID or window mismatch is `invalid_request` on `pid` or
|
||||
`window_id` and leaves provider availability intact. A selected window that
|
||||
@@ -1154,6 +1214,25 @@ arguments. The receiver class comes from LLDB's Objective-C runtime reader
|
||||
without running target code; no expression is evaluated, and REA never
|
||||
attaches to a process it did not launch.
|
||||
|
||||
Resolved breakpoint locations, entries and caller frames also retain
|
||||
`source_location` from LLDB's line tables when available. Its `file_path`,
|
||||
one-based `line` and one-based `column` are independently nullable. An invalid
|
||||
line entry is null; historical captures may omit the field. This is debug metadata
|
||||
attribution: REA does not read that source path or verify the source file bytes.
|
||||
Absent coordinates do not imply that the executable has no source code.
|
||||
|
||||
Free Pascal programs with retained native symbols and usable DWARF can use this
|
||||
same bounded call observation on macOS. Select an exact emitted symbol from the
|
||||
binary rather than assuming a source procedure name. The owned Pascal fixture
|
||||
uses an explicit C calling convention and a public symbol; its verification
|
||||
covers call entries, raw integer registers and source coordinates, without
|
||||
establishing typed Pascal locals or interactive stepping. After building REA,
|
||||
run the real lane with an existing caller-selected compiler:
|
||||
|
||||
```sh
|
||||
REA_VERIFY_FPC_COMMAND=/absolute/path/to/fpc npm run verify:native:pascal-calls
|
||||
```
|
||||
|
||||
The run ends when the process exits, `max_events` entries are recorded,
|
||||
`duration_ms` elapses, or the aggregate trace resource budget is exhausted.
|
||||
Bounded termination reports partial coverage. REA checks process termination
|
||||
@@ -1219,15 +1298,17 @@ Install a Ghidra 12.x (>=12.1) release and the 64-bit full JDK it declares, then
|
||||
use them. Ghidra analysis supports Linux x64/arm64 and macOS x64/arm64; each installation requires
|
||||
the matching native decompiler. Experimental Windows x64 P0 admits native
|
||||
x86, x86-64, ARMNT (Thumb-2) and ARM64 PE applications and DLLs, [DOS MZ
|
||||
executables](ghidra-dos.md), plus explicitly selected
|
||||
[raw NMOS 6502 images](raw-binary.md#nmos-6502) with a caller-supplied load address,
|
||||
executables](../../providers/ghidra-dos.md), plus explicitly selected
|
||||
[raw NMOS 6502 images](../../providers/raw-binary.md#nmos-6502) with a caller-supplied load address,
|
||||
on fixed local NTFS volumes. Other raw CPU families remain unsupported on Windows.
|
||||
The boundary uses bundled Job Object ownership, protected runtime DACLs, and
|
||||
handle-based path admission. See [Windows Ghidra P0](windows-ghidra-p0.md) and
|
||||
handle-based path admission. See [Windows Ghidra P0](../../providers/windows-ghidra-p0.md) and
|
||||
[issue #527](https://github.com/morluto/rea/issues/527).
|
||||
On Linux and macOS, `annotate_native_function` atomically edits a function name
|
||||
and entry comments in the ephemeral database, returning refreshed analysis
|
||||
without changing executable bytes. Annotation text must contain no NUL or
|
||||
without changing executable bytes. A Ghidra address inside a function selects
|
||||
the containing function; the name and comments are changed at its entry, not
|
||||
at the selected instruction. Annotation text must contain no NUL or
|
||||
unpaired Unicode surrogate; a rejection identifies the field and UTF-16 index
|
||||
and leaves every annotation unchanged. CRLF, supplementary Unicode characters,
|
||||
and combining characters are preserved. Windows P0 remains read-only. Ghidra has no
|
||||
@@ -1245,6 +1326,11 @@ and slice commitments establish the same canonical entry. The result reports
|
||||
remain separate dimensions. Equal numeric addresses without applicable coordinate
|
||||
commitments do not establish same-entry correspondence. Inspect the retained
|
||||
source Evidence and coverage when correspondence remains ambiguous.
|
||||
When both inputs authenticate to the same Evidence ID and an applicable entry
|
||||
comparison is unavailable, the match reports `method: "same-evidence"`.
|
||||
This identifies one selected observation, not a correspondence between distinct
|
||||
records or proof of complete analysis. Unavailable facets and unestablished
|
||||
call coverage remain unknown.
|
||||
To aggregate already-retained comparison results, pass their exact IDs to
|
||||
`find_changed_behavior`, for example:
|
||||
|
||||
@@ -1472,7 +1558,7 @@ Use `start`/`end` to constrain the inclusive address window, and continue with
|
||||
`next_cursor` until `complete` is true. Inspect `searched` for page coverage and
|
||||
skipped uninitialized blocks. A missing match does not establish absence from
|
||||
uninitialized or excluded memory. See
|
||||
[Ghidra byte search](ghidra-provider.md#masked-byte-search) for mask and coverage
|
||||
[Ghidra byte search](../../providers/ghidra-provider.md#masked-byte-search) for mask and coverage
|
||||
semantics. This query never executes or modifies target bytes.
|
||||
|
||||
Exact-name xref lookup reports distinct candidate addresses as an input ambiguity;
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
`inspect_recorded_crash` / `rea inspect-recorded-crash` inspect a caller-selected
|
||||
Linux ELF64 little-endian core independently of an active binary target. Apple
|
||||
`.ips` crash reports use the separate [Apple IPS](apple-ips.md) workflow. Two
|
||||
`.ips` crash reports use the separate [Apple IPS](../../apple-ips.md) workflow. Two
|
||||
architecture profiles are interpreted, x86-64 and AArch64; each binds registers
|
||||
to its own `NT_PRSTATUS` layout, and any other `e_machine` is refused as
|
||||
`unsupported_target` before note interpretation.
|
||||
@@ -0,0 +1,94 @@
|
||||
# Windows Shell Link shortcuts
|
||||
|
||||
`inspect_windows_shortcut` / `inspect-windows-shortcut` answers whether one
|
||||
selected local file is a Windows Shell Link (`.lnk`), which target path,
|
||||
arguments, working directory, and icon location it records, which volume and
|
||||
network names `LinkInfo` stores, and which ExtraData blocks follow the
|
||||
strings. It reads the file without resolving or executing the target and does
|
||||
not require a Windows SDK, COM, or a network.
|
||||
|
||||
```bash
|
||||
rea inspect-windows-shortcut /absolute/path/to/shortcut.lnk --json
|
||||
```
|
||||
|
||||
The CLI resolves relative paths against the caller's working directory. MCP
|
||||
and the advertised input schema require an absolute filesystem path and
|
||||
preserve that exact selection:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inspect_windows_shortcut",
|
||||
"arguments": { "path": "/artifacts/shortcut.lnk" }
|
||||
}
|
||||
```
|
||||
|
||||
## Observations
|
||||
|
||||
The inline Evidence result contains the artifact path, SHA-256, and byte
|
||||
length. `header` is the 76-byte `ShellLinkHeader`: `LinkFlags` and
|
||||
`FileAttributes` as raw values plus documented names, creation/access/write
|
||||
FILETIMEs as a raw 64-bit decimal and ISO-8601 UTC when the timestamp is in
|
||||
range, file size, icon index, `ShowCommand` (`normal`, `maximized`, or
|
||||
`minimized`), and hotkey modifiers. Undocumented `ShowCommand` values are
|
||||
decoded as `normal`, as specified.
|
||||
|
||||
`id_list` is present when `HasLinkTargetIDList` is set. Each item keeps its
|
||||
file offset, size, and type byte. Root-folder, volume, and file-entry items
|
||||
are decoded when those layouts match documented shell-item headers, including
|
||||
the 8.3 short name on a file entry. Every other item is `raw` with a SHA-256
|
||||
of its payload. Unknown items are not guessed.
|
||||
|
||||
`link_info` reports volume drive type, serial, label, local base path, and
|
||||
common network relative link names, with Unicode variants when the header
|
||||
declares them. ANSI strings use a byte-preserving Latin1 projection; the
|
||||
original system ANSI code page is unobserved.
|
||||
|
||||
`string_data` reports name, relative path, working directory, command-line
|
||||
arguments, and icon location according to `LinkFlags`, each with encoding,
|
||||
`CountCharacters`, byte length, and the decoded value. `IsUnicode` selects
|
||||
UTF-16LE; otherwise the Latin1 projection is used.
|
||||
|
||||
`extra_data` enumerates every block: signature, size, and offset.
|
||||
`EnvironmentVariableDataBlock` and `IconEnvironmentDataBlock` expose ANSI and
|
||||
Unicode targets. `TrackerDataBlock` exposes the NetBIOS machine id and droid /
|
||||
birth-droid GUIDs. Version-1 UUID MAC and timestamp values are labelled
|
||||
`evidence_kind: "derived"`. `KnownFolderDataBlock` and `SpecialFolderDataBlock`
|
||||
keep their folder identifiers. `ConsoleFEDataBlock` keeps the code page.
|
||||
`PropertyStoreDataBlock` and unrecognized signatures stay raw with SHA-256.
|
||||
Unknown signatures are listed and are not dropped.
|
||||
|
||||
`observations` are derived only from those documented fields: whether
|
||||
arguments are present, argument character length, target extension, whether
|
||||
`ShowCommand` is minimized, and whether the icon location differs from the
|
||||
recorded target path. That comparison is `null` unless the icon and a recorded
|
||||
target are both full paths: a stored filename, relative path, or `%VAR%` form
|
||||
cannot show that two locations differ. This workflow does not emit verdicts
|
||||
about intent.
|
||||
|
||||
A missing optional section is observed absence of that structure. It is not
|
||||
proof the shortcut never carried that data in another container.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
The selected file is limited to 1 MiB by default (16 MiB maximum). At most 256
|
||||
IDList items (4096 maximum) and 64 ExtraData blocks (1024 maximum) are
|
||||
examined by default. Retained string payload bytes across StringData,
|
||||
LinkInfo, and ExtraData are limited to 64 KiB by default (1 MiB maximum).
|
||||
Malformed `HeaderSize` or `LinkCLSID`, and exhausted budgets, fail without
|
||||
partial success. Truncation after a valid header, ExtraData size overruns, and
|
||||
odd Unicode lengths return partial coverage with `coverage.failing_offset`.
|
||||
A LinkInfo offset that points outside its structure is reported at the
|
||||
offset field itself, so every issue offset lies inside the file.
|
||||
Coverage is never `complete` when issues are present.
|
||||
|
||||
The selected path must be a regular file. Symbolic links are rejected.
|
||||
UNC paths and other host-prefixed device paths, such as `\\server\share\a.lnk`
|
||||
and `\\?\UNC\server\share\a.lnk`, are rejected before any filesystem call. On
|
||||
Windows, a path whose parent directory is a symbolic link or junction is
|
||||
rejected before anything follows that link. The check covers the directories
|
||||
Windows opens after removing `.` and `..`, so `C:\alias\..\real\a.lnk` is
|
||||
checked at `C:\real` only; a `\\?\` path is checked as written. A mapped
|
||||
network drive cannot be told apart from a local drive by its path and is not
|
||||
rejected.
|
||||
This workflow does not resolve, open, or execute the link target or call COM,
|
||||
and it does not contact a network for a path on a local volume.
|
||||
@@ -4,7 +4,7 @@ REA exposes Frida device and process discovery, attach or spawn sessions, and ca
|
||||
|
||||
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.
|
||||
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 cleanup fails, the session remains available for cleanup retry but refuses new script loads and resume requests. 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.
|
||||
|
||||
`instrument-with-frida --json` returns the Evidence record directly, matching MCP. Consumers of the earlier `{evidence, cleanup_error}` CLI wrapper should read the record at the JSON root and the session cleanup observation at `normalized_result.cleanup_error`. If final provider cleanup fails or cancellation arrives during it, the typed error retains completed Evidence in `details.partial_observation`. Discovery commands retain their device or process report in the same field.
|
||||
|
||||
@@ -97,6 +97,18 @@ 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.
|
||||
The MCP tool accepts each complete capture inline or as an exact
|
||||
`{"kind":"retained-evidence","evidence_id":"ev_..."}` reference to capture
|
||||
Evidence already retained by the current session.
|
||||
|
||||
Capture-local observer timing remains in Evidence for provenance, but scheduler
|
||||
and observation latency alone do not make behavior changed: terminal,
|
||||
interaction-dispatch, settlement/finalization, process-sample, and filesystem
|
||||
checkpoint times are excluded from the default semantic equality projection.
|
||||
To make a timing value part of the question, supply a `trace_spec` whose exact
|
||||
event includes that field. Semantic fields such as output, interaction outcome,
|
||||
exit status, finalization delivery, process identity/command, and filesystem
|
||||
contents still participate in the default comparison.
|
||||
|
||||
For scenarios where independent scheduling can change event order, the CLI
|
||||
also accepts an optional trace-specification JSON file as the third argument.
|
||||
@@ -508,8 +520,9 @@ a representability limit, not a timer limit. The nominal lifecycle budget is tha
|
||||
sum; polling, snapshotting and cleanup lie outside it. Scenario `events` keep
|
||||
being dispatched during finalization and are recorded as usual. `finalization_ms`
|
||||
of `0`, the default, keeps today's behaviour and the committed identity of every
|
||||
existing scenario. `elapsed_ms` and `sent_at_ms` are timing data and take part in
|
||||
exit comparison like `settlement.elapsed_ms`.
|
||||
existing scenario. `elapsed_ms` and `sent_at_ms` are retained timing provenance
|
||||
like `settlement.elapsed_ms`. The default semantic comparison excludes these
|
||||
capture-local times; an exact trace event can assert them explicitly.
|
||||
|
||||
Every capture requires `truncation_details`, with separate accounting for:
|
||||
|
||||
File renamed without changes.
@@ -1,7 +1,8 @@
|
||||
# Offline WebAssembly artifacts
|
||||
|
||||
`inspect_wasm_artifact` / `inspect-wasm-artifact` inspects explicitly selected
|
||||
local WASM bytes using caller-supplied WABT 1.0.42. No active binary target is
|
||||
local WASM bytes using caller-supplied WABT 1.0.x (verified with 1.0.42). No
|
||||
active binary target is
|
||||
required. REA does not install tools or fetch artifacts and does not execute WASM.
|
||||
|
||||
`open_binary` is not the WASM inspection route. A recognized WASM v1 header
|
||||
@@ -28,11 +29,17 @@ been exercised on macOS arm64; other hosts require their own verification.
|
||||
|
||||
Configuration failures do not establish anything about the selected WASM bytes.
|
||||
For a rejected version probe, `details.diagnostics` identifies the executable,
|
||||
tool, expected version and configuration key; `details.captured_output` preserves
|
||||
tool, verified version, accepted release range and configuration key;
|
||||
`details.captured_output` preserves
|
||||
its actual stdout and stderr, including empty banners or warnings. Fix the
|
||||
reported directory, executable access or release rather than changing the module
|
||||
or repeating an unchanged call. All three tools must report 1.0.42 on stdout with
|
||||
empty stderr. For CLI calls, set the environment before the next invocation. For
|
||||
or repeating an unchanged call. All three tools must report the same release on
|
||||
stdout with empty stderr, and that release must fall within the accepted range
|
||||
(`>=1.0.42 <1.1.0`, verified with 1.0.42). A release above 1.0.42 in that range is
|
||||
admitted: the observed banner becomes `tool_profile.release` and the
|
||||
`provider.version`, and the report states that only 1.0.42 was verified. Managed
|
||||
downloads stay pinned to 1.0.42. For CLI calls, set the environment before the
|
||||
next invocation. For
|
||||
MCP, change the server's launch environment and restart/reconnect that server;
|
||||
exporting a variable in a different shell does not update a running server.
|
||||
REA never installs tools or relaxes version admission to recover.
|
||||
@@ -122,7 +129,7 @@ To change the default across new MCP operations, set `wasm.command_timeout_ms`
|
||||
through `update_analysis_settings`. An explicit `command_timeout_ms` still wins;
|
||||
correct that argument if it caused the timeout. Runtime defaults do not insert
|
||||
omitted arguments into Evidence parameters. See the
|
||||
[settings design](design/limits-and-recovery.md#precedence-and-lifetime).
|
||||
[settings design](../../design/limits-and-recovery.md#precedence-and-lifetime).
|
||||
|
||||
For example, `rea inspect-wasm-artifact /artifacts/module.wasm
|
||||
--command-timeout-ms 60000 --format json` uses a 60-second per-command deadline;
|
||||
@@ -170,7 +177,7 @@ Candidates are caller-selected files; their identity does not imply validation.
|
||||
Both CLI and MCP use the same typed port and application service. MCP publishes
|
||||
SDK-compatible schemas and records Evidence for `get_evidence_bundle` readback.
|
||||
See [WABT provenance](https://github.com/morluto/rea/blob/main/third_party/wabt/README.md) and
|
||||
[testing](testing.md#offline-wasm-artifacts) for real-tool verification.
|
||||
[testing](../../development/testing.md#offline-wasm-artifacts) for real-tool verification.
|
||||
|
||||
## Compare core-module interfaces
|
||||
|
||||
@@ -31,7 +31,7 @@ authority are validated independently before selection and connection.
|
||||
|
||||
For a compact route query, select `detail: "summary"` and a
|
||||
`view: {kind: "javascript-routes", collection: "routes", limit: 20}`. The
|
||||
shared [route inventory](javascript-route-inventory.md) preserves source IDs,
|
||||
shared [route inventory](../../javascript-route-inventory.md) preserves source IDs,
|
||||
precise locations, partial coverage, and the complete parent Evidence for
|
||||
subsequent filtered pages. Static candidates never establish complete application
|
||||
coverage or reachability.
|
||||
@@ -147,7 +147,7 @@ Caller-owned JSON/base64 strings, input parsing and validation, transport
|
||||
buffers, garbage-collector behavior, and other runtime memory are outside this
|
||||
estimate; the budget does not promise a bound on total process memory.
|
||||
|
||||
Electron `file://` pages use a separate provider and target boundary; see [electron-observation.md](electron-observation.md).
|
||||
Electron `file://` pages use a separate provider and target boundary; see [electron-observation.md](../javascript/electron-observation.md).
|
||||
|
||||
## Provider authorities
|
||||
|
||||
@@ -177,7 +177,7 @@ See [the reproduction and Chromium ownership limitation](https://github.com/morl
|
||||
|
||||
Existing static application Evidence and passive web/Electron captures can be
|
||||
combined later through
|
||||
[JavaScript static/runtime reconciliation](javascript-runtime-reconciliation.md).
|
||||
[JavaScript static/runtime reconciliation](../javascript/javascript-runtime-reconciliation.md).
|
||||
|
||||
## Start a browser
|
||||
|
||||
@@ -239,10 +239,21 @@ file for you.
|
||||
`observe_web_session`, `discover_webmcp_tools`, and `capture_web_screenshot`
|
||||
accept a browser socket. Website runtime attribution, Electron inspection,
|
||||
and scenario attach mode still require HTTP discovery.
|
||||
- Each call opens one WebSocket and uses it for discovery
|
||||
(`Browser.getVersion`, `Target.getTargets`) and for the selected page.
|
||||
Discovery must finish within the same 10-second deadline as HTTP discovery.
|
||||
Chrome may ask you to approve each connection.
|
||||
- An admitted browser socket is retained by the active browser provider across
|
||||
calls to the same normalized browser WebSocket URL, and concurrent cold-start
|
||||
calls share one handshake so MCP sessions do not re-open the browser socket on
|
||||
every step. Scheme case, uncompressed IPv6 loopback spellings, and leading
|
||||
port zeros normalize to one reuse key, while `127.0.0.1`, `[::1]`, and
|
||||
distinct `/devtools/browser/<id>` paths remain separate sockets. Each target
|
||||
operation detaches its flattened target session when finished: unconfirmed
|
||||
target attach or detach cleanup closes the shared browser socket for session
|
||||
containment, whereas a caller's own discovery deadline or cancellation
|
||||
releases only its lease when transport state remains clean. Provider shutdown
|
||||
closes the retained browser socket. One-shot CLI invocations close their
|
||||
provider on exit, so Chrome may still ask you to approve each separate CLI
|
||||
connection. Discovery (`Browser.getVersion`, `Target.getTargets`) defaults to
|
||||
a 10-second deadline and can be adjusted per call with `discovery_timeout_ms`
|
||||
(`--discovery-timeout-ms` on the CLI).
|
||||
- The browser identifier controls access to the socket. Evidence records the
|
||||
endpoint as `ws://127.0.0.1:9222/devtools/browser/[REDACTED]`.
|
||||
- `browser.revision` is the socket's `Browser.getVersion` value, such as
|
||||
@@ -598,13 +609,13 @@ an unknown size, comparison reports unknown rather than treating the observation
|
||||
as a resource addition or removal; complete inventory coverage still establishes
|
||||
when an entire group is absent.
|
||||
|
||||
CDP discovery has a 10-second response deadline. HTTP discovery documents
|
||||
use an 8 MiB budget. Browser-socket discovery (`Browser.getVersion`,
|
||||
`Target.getTargets`) uses the 64 MiB protocol message budget. Neither budget
|
||||
nor the discovery deadline has a runtime override. `list_browser_targets` accepts no
|
||||
`command_timeout_ms`: HTTP discovery and browser-socket discovery
|
||||
(`Browser.getVersion`, `Target.getTargets`) stay on that fixed deadline, and
|
||||
the socket closes without a later command. Other CDP tools use
|
||||
CDP discovery defaults to a 10-second response deadline, configurable per call
|
||||
on passive browser tools with `discovery_timeout_ms` (default 10000). HTTP
|
||||
discovery documents use an 8 MiB budget. Browser-socket discovery
|
||||
(`Browser.getVersion`, `Target.getTargets`) uses the 64 MiB protocol message
|
||||
budget. Neither byte budget has a runtime override. `list_browser_targets`
|
||||
accepts `discovery_timeout_ms` and no `command_timeout_ms`, because it performs
|
||||
only discovery without a post-discovery target command. Other CDP tools use
|
||||
`command_timeout_ms` (default 20000) for each WebSocket handshake and command
|
||||
response, separate from the caller-selected observation window, discovery, and
|
||||
the 5000 ms cleanup grace. A browser-level socket's handshake and the following
|
||||
File renamed without changes.
@@ -357,7 +357,11 @@ entire property and its sidecars; a `scope: "property-name"` redaction points
|
||||
to its actual parent. No substitute property name or child pointer is invented.
|
||||
Omitted subtrees are still validated, including canonical HAR base64. Explicitly sensitive artifact
|
||||
paths are empty in Evidence and omitted from locations, while the original
|
||||
SHA-256 and size remain available unless the digest itself is explicitly excluded. Failure messages, diagnostics and cleanup
|
||||
SHA-256 and size remain available unless the digest itself is explicitly excluded.
|
||||
CLI [caller-selected paths](../../reference/mcp-contracts.md#caller-selected-paths)
|
||||
are excluded independently: a sensitive capture spelling can be omitted while a
|
||||
safe `descriptor_set_path` remains, and a safe relative spelling can remain even
|
||||
when its resolved parent path is sensitive. Failure messages, diagnostics and cleanup
|
||||
resources follow the same explicit declarations without changing error types;
|
||||
sensitive issue pointers identify a real ancestor instead of a fabricated
|
||||
coordinate. Header/cookie authentication values and known
|
||||
@@ -599,7 +603,7 @@ selected response bodies or header values: each network transaction is then
|
||||
one record, in request order, and the result names
|
||||
`parent_operation: "capture_browser_scenario"` with an empty `artifact`, since
|
||||
a scenario records no file. See
|
||||
[agent environments](agent-environments.md#from-a-browser-scenario).
|
||||
[agent environments](../../agent-environments.md#from-a-browser-scenario).
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -1084,7 +1088,7 @@ capture with many read-only paths yields a correspondingly larger state result.
|
||||
The view performs no network activity and serves nothing; `rea environment-serve`
|
||||
derives it from the capture at startup, serves read tools and the served write
|
||||
plans from it and loads replacement states through the AgentEnv data plane, as
|
||||
[serve from the state](agent-environments.md#serve-from-the-state) describes.
|
||||
[serve from the state](../../agent-environments.md#serve-from-the-state) describes.
|
||||
|
||||
## Environment coverage
|
||||
|
||||
@@ -1105,7 +1109,7 @@ an environment whose served catalog exceeds the discovery budget, or whose
|
||||
state exceeds what `data/add` loads, serves replay, and `rea environment-build`
|
||||
then reports `coverage: null`; otherwise the build prints this summary as its
|
||||
`coverage`. See
|
||||
[Build a bundle in one step](agent-environments.md#build-a-bundle-in-one-step)
|
||||
[Build a bundle in one step](../../agent-environments.md#build-a-bundle-in-one-step)
|
||||
for the hint per reason.
|
||||
|
||||
## Resource and lifecycle boundaries
|
||||
@@ -1155,7 +1159,7 @@ host memory or `NODE_OPTIONS` does not raise the old-generation heap. Update
|
||||
`capture.decoder_old_generation_mib` through MCP, or set
|
||||
`REA_CAPTURE_DECODER_OLD_GENERATION_MIB` before starting a new REA process.
|
||||
Retry after owned cleanup completes; the update does not release resources.
|
||||
See the [settings design](design/limits-and-recovery.md#failure-and-retry).
|
||||
See the [settings design](../../design/limits-and-recovery.md#failure-and-retry).
|
||||
Record selection happens after complete decoding and does not reduce that
|
||||
workload. Use a smaller capture exported by its producer or another decoder
|
||||
with sufficient capacity, retaining the original for provenance. Subsets do
|
||||
File renamed without changes.
File renamed without changes.
@@ -91,7 +91,7 @@ launches it without one. On hosts that cannot provide one, such as root in a
|
||||
container, `REA_BROWSER_NO_SANDBOX=true` launches it without the sandbox; the
|
||||
variable does not enable an REA security boundary.
|
||||
|
||||
See [testing](testing.md) for the native loading oracle and CLI/MCP real lane.
|
||||
See [testing](../../development/testing.md) for the native loading oracle and CLI/MCP real lane.
|
||||
|
||||
The selected local source filename supplies the parser grammar. JavaScript files
|
||||
retain native dynamic imports even in relational expressions; TypeScript files
|
||||
File renamed without changes.
Loaded 100 of 1812 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user