mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 17:32:36 -10:00
Compare commits
99
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4a7c20e04 | ||
|
|
27edc5c83f | ||
|
|
c52a9b9d79 | ||
|
|
8dfc47b107 | ||
|
|
e9b6c87c1c | ||
|
|
387bcb795d | ||
|
|
e5ddbe8909 | ||
|
|
018f19d8c8 | ||
|
|
fe2985a0b4 | ||
|
|
26d81afedd | ||
|
|
d71e35a5ae | ||
|
|
240f08d406 | ||
|
|
61ab3f0c4f | ||
|
|
fd39977c32 | ||
|
|
012861ce1d | ||
|
|
0dcd0dfc20 | ||
|
|
35f1c3517f | ||
|
|
eb8ba20c35 | ||
|
|
bdf7cc3b1e | ||
|
|
3b2522bd3b | ||
|
|
8bc01b48b4 | ||
|
|
deae5fbe6d | ||
|
|
fa0fcf35ce | ||
|
|
217b6fdcdc | ||
|
|
78343052c2 | ||
|
|
b105dae7c6 | ||
|
|
7a1d89a801 | ||
|
|
759817ccbe | ||
|
|
da3bb5aa7b | ||
|
|
ec7d09176b | ||
|
|
bf1811bdbc | ||
|
|
74201434e7 | ||
|
|
769d92025d | ||
|
|
ca1674473c | ||
|
|
22f28644fe | ||
|
|
43f06eb1e8 | ||
|
|
f21fda0fc0 | ||
|
|
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 |
No files matched your search
@@ -2,7 +2,7 @@
|
||||
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, 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: "61"
|
||||
version: "62"
|
||||
---
|
||||
|
||||
# REA
|
||||
@@ -97,6 +97,12 @@ explicit path or endpoint and do not need it.
|
||||
- Bun `--compile` executable: `open_binary`, then `inspect_artifact`; the Bun
|
||||
module graph is the application layer. Extract stored modules and analyze the
|
||||
JavaScript. See [Bun standalone executables](https://github.com/morluto/rea/blob/main/docs/bun-standalone.md).
|
||||
- Deno `deno compile` executable: `open_binary`, then `inspect_artifact`; the
|
||||
embedded virtual filesystem is the application layer. Extract stored files and
|
||||
analyze compatible JavaScript. Environment-file values and CA certificate bytes
|
||||
are retained in local Evidence with their counts and byte lengths. The npm
|
||||
snapshot length is reported and not decoded, and the executable is not run. See
|
||||
[Deno compile executables](https://github.com/morluto/rea/blob/main/docs/deno-standalone.md).
|
||||
- Apple app plist, Interface Builder, asset catalog, or keyed archive resources:
|
||||
`open_bundle_resources`, then the selected resource tool. This does not
|
||||
require `CFBundleExecutable` or a deep provider. Resource sessions have no
|
||||
@@ -276,6 +282,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
|
||||
@@ -299,6 +313,23 @@ explicit path or endpoint and do not need it.
|
||||
build-id or ABI-tag fields. A missing table is observed absence of those
|
||||
declarations, not proof the image never carried notes. See the
|
||||
[ELF notes guide](https://github.com/morluto/rea/blob/main/docs/elf-notes.md).
|
||||
- Code that runs before `main` or at exit in ELF or Mach-O:
|
||||
`inspect_native_initializers` with the explicit local file (and
|
||||
`architecture` for a universal Mach-O). This built-in inspection requires no
|
||||
disassembler. Preserve slot and target addresses, the `resolution` of each
|
||||
entry, and its limitations. An `unresolved` slot is not a zero pointer, and a
|
||||
missing table is not proof that no constructor exists. See the
|
||||
[initializer guide](https://github.com/morluto/rea/blob/main/docs/guides/native/native-initializers.md).
|
||||
|
||||
- ELF unwind function ranges: `inspect_elf_unwind_ranges` with the explicit
|
||||
local ELF32/ELF64 file. This built-in target-free inspection requires no
|
||||
disassembler. Preserve FDE start, end, size, containing section, exact
|
||||
symbol name, CIE index, LSDA, and personality. Page with `offset` and
|
||||
`limit`. A missing `.eh_frame` is observed absence of that declaration,
|
||||
not proof the image has no functions. `.debug_frame` is reported present
|
||||
or absent and is not decoded. CFA instructions are counted and not
|
||||
evaluated. See the
|
||||
[ELF unwind ranges guide](https://github.com/morluto/rea/blob/main/docs/guides/native/elf-unwind-ranges.md).
|
||||
- Apple `.ips` crash reports: `inspect_apple_ips` with the explicit local
|
||||
file. This built-in target-free inspection requires no Xcode, atos, or
|
||||
pwntools. Preserve first-line metadata, `bug_type` as a string, process and
|
||||
@@ -317,6 +348,16 @@ explicit path or endpoint and do not need it.
|
||||
zstd containers are unsupported; decompress into a separate file with an
|
||||
external codec utility, then inspect the decompressed `ET_REL` image. See the
|
||||
[kernel module guide](https://github.com/morluto/rea/blob/main/docs/kernel-modules.md).
|
||||
- Linux kernel version and build config (`CONFIG_*` options such as
|
||||
`CONFIG_SECURITY_SELINUX`): `inspect_kernel_build_config` with the explicit
|
||||
local `vmlinux`, raw `Image`, x86 `bzImage`, or `configs.ko`. This built-in
|
||||
target-free inspection requires no Linux host or `extract-ikconfig`. Preserve
|
||||
the banner version, config SHA-256, option count, and value kinds; use `name`
|
||||
for one option. An `IKCFG_ST` string is a config only with a valid gzip member
|
||||
and `IKCFG_ED`. An absent config may mean the kernel was built without
|
||||
`CONFIG_IKCONFIG`. Non-gzip payloads are unsupported; decompress externally,
|
||||
then inspect the result. See the
|
||||
[kernel build config guide](https://github.com/morluto/rea/blob/main/docs/guides/native/kernel-build-config.md).
|
||||
- CPython 3.7–3.13 `.pyc` header, nested marshal code objects and bytecode
|
||||
identity: `inspect_python_pyc` with the explicit local file. This built-in
|
||||
target-free inspection requires no Python installation. Preserve magic,
|
||||
|
||||
@@ -5,14 +5,18 @@ 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.
|
||||
MCP-only and need a Linux host with Docker, agentenv and REA's packed
|
||||
runtime. When a start reports one missing, tell the person to run
|
||||
`rea doctor --provider desktop_build` and apply its fixes, or
|
||||
`rea setup --client <client> --desktop-build` and restart the client, 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.
|
||||
commands in the computer or write its files another way. The one command
|
||||
you write for the computer is a task's reader, which REA runs to check a
|
||||
file; it never makes the seed or the edit.
|
||||
- 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.
|
||||
@@ -22,7 +26,8 @@ For the whole build:
|
||||
## Ask once, upfront
|
||||
|
||||
In one message, ask only what the request leaves open, and keep the list for
|
||||
the report:
|
||||
the report. Skip each question the request answers; when it answers them all,
|
||||
start without asking:
|
||||
|
||||
1. The app and the task, if either is unclear: what changes, in which
|
||||
document.
|
||||
@@ -31,39 +36,83 @@ the report:
|
||||
and with which model.
|
||||
4. If so, whether they want to review the task before those runs.
|
||||
|
||||
When you cannot ask, as in a headless `claude -p` run, do not stop: take
|
||||
these defaults for whatever the request leaves open, say which you took in
|
||||
your first message and in the report, and go on. Install from the Ubuntu
|
||||
archive, make a synthetic seed, skip the review, and make 3 solver runs
|
||||
within $4 in all, with the model the request names or else the runner's
|
||||
default.
|
||||
|
||||
## 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;
|
||||
on your own; name it and where to read it, and go on only once the person
|
||||
says they accept it. Then record their words with `record_build_consent`,
|
||||
kind `licence`, and accept it on their behalf;
|
||||
- credentials: ask the person to write each secret, and nothing else, in a
|
||||
file named after a handle you choose, such as `keepassxc-master`, in
|
||||
`~/.config/rea/build-secrets/` on this host (under `$XDG_CONFIG_HOME` when
|
||||
it is set), readable only by them (`chmod 600`), and wait until they say it
|
||||
is there; then type it with `type_secret` (see Drive the app). Never ask
|
||||
for a password or key in chat, and never read, list or print that folder;
|
||||
- a signed-in state in the seed: by default the export withholds it (see
|
||||
Sign-in and licence state). Seed it only when the person says the bundle
|
||||
may hold it: record their words with `record_build_consent`, kind
|
||||
`seed_sign_in`, and export with `seed_sign_in: true`;
|
||||
- an install this flow cannot do, below.
|
||||
|
||||
Decide everything else yourself and note it in the report.
|
||||
|
||||
## Sign-in and licence state
|
||||
|
||||
What an app writes when someone signs in or activates a licence is withheld
|
||||
from the seed: the bundle's receiver supplies their own. Mark
|
||||
`pre-sign-in` with `mark_build_checkpoint` just before the sign-in or
|
||||
activation and `post-sign-in` just after, both before `seed`: every file
|
||||
under the owned paths that changed between them is withheld, and the draft
|
||||
leaves it out. A file the app writes at first launch, such as a trial's
|
||||
licence file, changes before you can mark anything: name it in
|
||||
`export_build_environment`'s `withhold`. The export lists each withheld file
|
||||
in `withheld_files` with the environment variable a deploy reads it from and
|
||||
the handle of the secret REA keeps its bytes in; a check may not name one.
|
||||
The export refuses a seed file holding a withheld file's exact bytes, such as
|
||||
a `.bak` copy, but a backup that differs from it is not caught: trash backups
|
||||
before `seed`.
|
||||
Explicitly withhold any other files the person identifies as sensitive;
|
||||
REA does not infer secrecy from a value's shape or a file name.
|
||||
|
||||
## 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"}` |
|
||||
| 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"}` |
|
||||
| AppImage by URL | `{"kind": "appimage", "url", "sha256", "architecture", "extra_packages"}` |
|
||||
| Tarball by URL | `{"kind": "tarball", "url", "sha256", "architecture", "program", "name", "extra_packages"}` |
|
||||
|
||||
- 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.
|
||||
- When the app exits at launch for want of a runtime piece its package does
|
||||
not install, start a new build computer with that package in
|
||||
`extra_packages`, up to 16 archive names; the export installs them too.
|
||||
MyPaint needs
|
||||
`{"kind": "archive", "package": "mypaint", "extra_packages": ["librsvg2-common"]}`
|
||||
for its SVG icons, and Freeplane `["openjdk-17-jre"]`, since its launcher
|
||||
refuses noble's Java 21. Name one up front, too, when a package the app
|
||||
only recommends holds its content, such as QElectroTech's element library
|
||||
`qelectrotech-data`, without which no component can be placed.
|
||||
- Take the `.deb` path only when the app is not in the archive at all, not
|
||||
to add a package. Ask the requester for its URL and SHA-256; do not fetch
|
||||
a vendor's download page yourself. List its `Depends` as `dependencies`,
|
||||
with any runtime piece it lacks: 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
|
||||
@@ -72,6 +121,13 @@ the first source that has the app:
|
||||
`/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
|
||||
|
||||
@@ -81,8 +137,10 @@ the first source that has the app:
|
||||
[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.
|
||||
lower `quality`. A screenshot with `region` does not capture the screen
|
||||
again; it crops the latest frame, so take a full screenshot, or a `wait`
|
||||
with `screenshot: true`, first. The crop then becomes the latest frame:
|
||||
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.
|
||||
@@ -95,25 +153,149 @@ the first source that has the app:
|
||||
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.
|
||||
- Type a secret with `{"action": "type_secret", "secret": "<handle>"}`,
|
||||
only into a field that masks what is typed: check in a screenshot that it
|
||||
is a password field, which shows dots. A screenshot shows any field that
|
||||
shows its text, such as many licence-key boxes, so never type a secret into
|
||||
one: say the app needs a secret the build cannot type unseen, and stop.
|
||||
`type_secret` takes no `screenshot`; look with a `wait` after it. A refusal
|
||||
names the secret's file and what is wrong with it: tell the person, never
|
||||
the value.
|
||||
- Prefer shortcuts and typing to long pointer paths: `key` takes `keys`, an
|
||||
array holding one chord's keys, such as
|
||||
`{"action": "key", "keys": ["ctrl", "s"]}`, and `type` turns `\n` into
|
||||
`{"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 opens in the home: click Documents in its sidebar and type only
|
||||
the file name. 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.
|
||||
- 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. When a GTK Save dialog ignores
|
||||
clicks or runs off the screen, type `~/Documents/<name>` in its Name field
|
||||
and press Return.
|
||||
- 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.
|
||||
- gLabels edits an object's text in Object properties → Text, not on the
|
||||
canvas.
|
||||
- In Grisbi's transaction form Return moves to the next field; only Return
|
||||
in the last field, Notes, records the transaction.
|
||||
- ghostwriter autosaves a new document as `~/Documents/untitled-1.md`: name
|
||||
it with File → Rename, not Save As; Ctrl+Shift+S does nothing, and Enter
|
||||
after a checklist item starts another `- [ ]` item.
|
||||
- KMyMoney's first launch opens the New File Setup wizard; Finish asks for a
|
||||
storage type (XML), then a Save As where typing `Documents/<name>.kmy`
|
||||
works. Its date field is a sectioned Qt editor: double-click the month and
|
||||
type each part, since Ctrl+A garbles it. A new transaction's payee comes
|
||||
prefilled and selected. Amounts are saved as reduced fractions, such as
|
||||
`-1749/20`, so compare them exactly. Untick Help → Tip of the Day → "Show
|
||||
tips on startup" before `seed`, or the tip appears at every boot.
|
||||
- QElectroTech: an element dropped from Collections follows the pointer until
|
||||
a click on the folio places it. Its title shows only the app, so it needs
|
||||
`state_paths`; its settings are in `~/.qet`.
|
||||
- Rosegarden: after a dialog its Transport window can take keyboard focus,
|
||||
so save with File → Save.
|
||||
- Pencil2D: the Tools dock is too narrow for its buttons, so use shortcuts
|
||||
(B for the brush); double-click a layer's name to rename it.
|
||||
- Umbrello: the title shows no unsaved mark, so confirm a save with a probe
|
||||
checkpoint. An Untitled document autosaves `~/autosave.xmi`: delete it
|
||||
before `seed`. Add attributes from the tree: right-click the class → New →
|
||||
Attribute.
|
||||
- Hydrogen: the computer has no audio device, so Hydrogen falls back to a
|
||||
null driver and its BPM field snaps back to 120 within about 100 ms.
|
||||
Before `seed`, set Preferences → Audio System → ALSA with device `null`
|
||||
and click "Apply and restart output", which `~/.hydrogen/hydrogen.conf`
|
||||
keeps for the seed; also set autosaves per hour to 0, and dismiss the
|
||||
development-version dialog with "Don't show again". `pulseaudio` as an
|
||||
extra package does not help.
|
||||
- Poedit cannot add entries by hand. Use File → New, pick the language and
|
||||
save to `Documents` first (Sources Paths stays locked until then), then
|
||||
Properties → Sources Paths → + → Add Files with a source such as
|
||||
`/usr/lib/python3.12/argparse.py`. It writes `fr.mo` beside the `.po`, and
|
||||
the language box's autocomplete popup takes the first OK click.
|
||||
- CherryTree: its first-run autosave "Choose Storage Type" dialog swallows
|
||||
keys, so save once early as `.ctd` and untick autosave.
|
||||
- VSCodium (its tarball, with `extra_packages: ["libnss3",
|
||||
"libasound2t64"]`) runs on outside REA's reach, so `stop_build_capture`
|
||||
fails to clean it up: after `end`, quit it with Ctrl+Q, then stop. Enter
|
||||
accepts its word suggestions, so press Escape after typing a line.
|
||||
- Glade: a new widget's id is empty until you set it, and a second save
|
||||
writes a `.glade~` backup, which shows in the draft as an unrelated
|
||||
change. A backup present at `seed` is seeded with the document, so trash
|
||||
it before `seed`. The draft names a button's `<child>` by the id
|
||||
its widget carries, `[name=child][>object@id=submit_button]`, which moving
|
||||
the button keeps; give the widget an id before `seed` so it can.
|
||||
- VYM: the title never names the map, so pass `Documents/<map>.vym` in
|
||||
`state_paths`. Its settings live in `.config/InSilmaril` and are written
|
||||
only at a clean exit. It writes `<map>.vym.lock` while a map is open, so
|
||||
close the map before `seed`. Press A only after clicking a branch on the
|
||||
canvas: keys typed in the tree editor run other shortcuts.
|
||||
- KmPlot: Create → Cartesian Plot, then edit the formula in the Function
|
||||
tab and press Return. It stores minus as U+2212 (`−`). Its file:// title
|
||||
still names the file.
|
||||
- RedNotebook keeps each month in `~/.rednotebook/data/YYYY-MM.txt`, YAML
|
||||
read as text, folded at about column 80: pick check phrases the fold keeps
|
||||
on one line.
|
||||
- Qt5 apps saving with QDom, such as KmPlot, write attributes in a random
|
||||
order in each process, so check their XML by element, never by whole line.
|
||||
- Gnumeric's desktop entry is `org.gnumeric.gnumeric`. Its Save As dialog
|
||||
runs off the 1280×800 screen: type `~/Documents/<name>` in Name and press
|
||||
Return. Rename a sheet with right-click on its tab, then Rename….
|
||||
- Parley's title shows the collection's title, so name the file in
|
||||
`state_paths`. File → New opens the new collection's Properties dialog:
|
||||
confirm it with OK, since Cancel keeps the old collection and its autosave
|
||||
lock open. A new collection starts with 15 blank entries: delete them.
|
||||
Pick languages from the dropdown; a typed name keeps the previous locale.
|
||||
While a document is open KDE keeps an autosave and its `.lock` in
|
||||
`~/.local/share/stalefiles/parley/`, and there is no File → Close: before
|
||||
`seed`, use File → New, then reopen the collection from Open Recent.
|
||||
- Sigil: pass `extra_packages: ["libqt5svg5"]`, or its SVG toolbar icons are
|
||||
blank. Its title names the book, so it needs no `state_paths`. It unpacks
|
||||
the open book into `.local/share/sigil-ebook/sigil/workspace/Sigil-XXXXXX/`
|
||||
and deletes it on exit, so never name the whole `sigil-ebook` folder: that
|
||||
seeds the stale copy.
|
||||
- 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.
|
||||
file rather than starting over. JabRef 3.8 writes `<file>.bak` and
|
||||
`<file>.sav` beside a `.bib` it saves; in the owned folder they are seeded
|
||||
and show in the draft as noise, so trash them before `seed` if they should
|
||||
not ship.
|
||||
- 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.
|
||||
- Some apps write their settings late: Freeplane writes
|
||||
`~/.config/freeplane/1.7.x/auto.properties` only once Preferences is
|
||||
confirmed, and a seed without it reopens its documentation map. Before
|
||||
`seed`, open the app's preferences and confirm them, then read a probe
|
||||
checkpoint's `changed_files` to see the settings file written.
|
||||
- Before `seed`, click into the document to clear any selection the app
|
||||
would save: Gnote saves its cursor and selection with the note.
|
||||
- An app whose state folder is named after it, such as
|
||||
`~/.local/share/gnote`, or after it and its version, such as TreeLine's
|
||||
`~/.treeline-3.1`, is found without `state_paths`.
|
||||
- TreeLine: File → New opens a template window. Book List's CATEGORY makes
|
||||
AUTHOR children by default; change it under Data → Configure Data Types →
|
||||
Default Child Type. A new child opens an inline rename showing "", so
|
||||
press Escape and fill its fields in the Data Edit tab. Ctrl+A adds a child
|
||||
node even while a field has focus. Clicking a node already selected starts
|
||||
an inline rename, so Ctrl+X then cuts its text: cut a node from its
|
||||
context menu. It saves nodes sorted by their
|
||||
generated uid1, so their order changes from run to run. The draft names a
|
||||
new node by its format and a field of its `data`,
|
||||
`/nodes/[format=BOOK][>data~1Title=The Silk Roads]`, and checks its other
|
||||
fields through that, so give each new node a title no other node has.
|
||||
- After an app crashes, capture again on a fresh computer, so the seed
|
||||
carries no crash-recovery state, such as MyPaint's "Recover interrupted
|
||||
work?".
|
||||
- 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
|
||||
@@ -121,17 +303,46 @@ the first source that has the app:
|
||||
`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`.
|
||||
- Freeplane's first launch opens a documentation map: close it with Ctrl+W.
|
||||
Its Ctrl+N asks for a template.
|
||||
- MyPaint 2.0.1 crashes on brush strokes on the build computer: build its
|
||||
seed with flood fill and layer operations.
|
||||
- GnuCash's Ctrl+S on a new book opens a Save dialog with no format choice:
|
||||
use File > Save As to pick XML. Close the book (File > New File) before
|
||||
`seed`, so its `.LCK` lock is not seeded.
|
||||
|
||||
## 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 can take minutes. A
|
||||
failed start returns the build's error: fix the request, or stop when the
|
||||
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.
|
||||
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 an icon loader or a Java
|
||||
runtime: close the computer and start a new one with that package in
|
||||
`extra_packages` (see Choose the install), 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. gLabels' title
|
||||
leaves out the file's extension and Grisbi's shows the entity's name,
|
||||
so both need it.
|
||||
- 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
|
||||
@@ -141,14 +352,71 @@ the first source that has the app:
|
||||
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 a window title
|
||||
named first, then those under `state_paths` and 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. Compression may be off by default: Dia's
|
||||
"Compress diagram files" is unticked, which REA reads as plain XML. 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. When the task is about the app's own binary
|
||||
format, such as GIMP's `.xcf` or Blender's `.blend`, keep it and check
|
||||
it through a reader (see Read a binary file with a reader).
|
||||
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), `draft.task.checks` (suggested checks) 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.
|
||||
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. If a declared secret was used,
|
||||
automatic drafting is withheld: write the task manually and export it.
|
||||
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`. When the app
|
||||
keeps the task's state only on screen, such as a calculator's result,
|
||||
judge the screen instead (see Judge the screen).
|
||||
- `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, or judge the screen (see Judge the screen).
|
||||
- `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. Name a record that keeps its fields as child
|
||||
elements by one of them, as Osmo's contact by
|
||||
`[name=contact][>first_name=Delphine]`, a JSON record by a field
|
||||
inside it, `[>data/Title=…]` (`~1` for the `/` inside a pointer), or
|
||||
an element by an id its child carries, `[>object@id=…]`; count records
|
||||
with `member_count`, `matching` `[name=contact]`; otherwise check an
|
||||
ancestor's text, or give the element an id in the app 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). For
|
||||
a binary file, read it with a reader (see Read a binary file with a
|
||||
reader).
|
||||
|
||||
## Write the task
|
||||
|
||||
@@ -156,20 +424,49 @@ 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." Never say how the file stores it, and never give the checks.
|
||||
starting with the app's name, naming the document as a user would and
|
||||
ending with saving it: "In Inkscape, change the poster's headline in
|
||||
Documents/poster.svg to Summer Bake Sale and save it." Name the app: the
|
||||
solving agent's own shell cannot see the computer's files, and the app's
|
||||
name sends it to the screen. 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` (an uncut scalar, or
|
||||
a preview cut at 600 characters) at the pointer a check names it by. Copy
|
||||
the pointer. Copy `after` into `value` only when it is an uncut scalar: a
|
||||
string without a trailing `…`, a number, or a boolean. Compact XML and a
|
||||
JSON array or object are preview strings, so a `value_equals` check needs
|
||||
the structured value from the file's view, and element text uses
|
||||
`text_equals` or `text_contains`.
|
||||
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 or id stands for, such as `category="44"`
|
||||
naming `<cat key="44" name="Groceries"/>`, or a new KMyMoney
|
||||
transaction's splits naming their account and payee; use it for the
|
||||
prompt's words. `alternatives` gives a changed value's pointer by the
|
||||
element's other names, such as a label beside an id, to pick another key
|
||||
without another export.
|
||||
Skip entries whose `note` is `by_position` (no check can use that
|
||||
pointer) or noise (`view_state`, `renumbered`, `volatile`,
|
||||
`timestamp`, `upkeep`, `layout`). `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 may suggest positional pointers; rewrite
|
||||
them. Only an element's text is read by position, as `children/0`.
|
||||
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
|
||||
@@ -178,15 +475,48 @@ Write `{"name", "prompt", "checks"}` from the draft and what you did.
|
||||
`{"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; to name an
|
||||
unchanged element, such as another paragraph's `xid`, use the app's usual
|
||||
numbering and let the export confirm it, or read it in the exported
|
||||
bundle's `envs/<env>/seed/`.
|
||||
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: the draft names it by its
|
||||
label cell, `[name=table:table-row][>table:table-cell=February]`. Where no
|
||||
cell names it alone, 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.
|
||||
- For a note placed by its own `x` and `y`, such as Xournal++'s `<text>`
|
||||
on a layer, the draft checks its text on the layer with `text_contains`,
|
||||
which passes wherever the user puts it, and guards each note it kept.
|
||||
- Some apps keep text in an attribute, one element per run, such as
|
||||
Scribus's `<ITEXT CH=...>`: add `"text_attribute": "CH"` to `text_equals`
|
||||
or `text_contains` on the frame,
|
||||
`/root/children/[name=DOCUMENT]/children/[name=PAGEOBJECT][@ANNAME=Headline]`,
|
||||
to read its runs' values joined.
|
||||
- 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. It is the one unchanged value
|
||||
worth checking; it passes on the seed too, which is fine, since the export
|
||||
needs only one check to fail there.
|
||||
- Give `value_equals` a `tolerance` for a number the app writes as text.
|
||||
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
|
||||
@@ -200,6 +530,124 @@ Write `{"name", "prompt", "checks"}` from the draft and what you did.
|
||||
The kinds and pointer rules are in
|
||||
[the desktop tasks section](environments.md#pick-the-checks).
|
||||
|
||||
### Read a binary file with a reader
|
||||
|
||||
When the draft notes `unreadable_view` on a binary document, add a reader to
|
||||
the task: the app's own headless command, which REA runs in the computer on a
|
||||
private copy of the file, and whose output a check reads instead of the file.
|
||||
Write it in the app's scripting mode, print each fact on a line starting
|
||||
with `REA ` (with the space), and name the copy `{file}`:
|
||||
|
||||
- GIMP `.xcf`, layer names, as `lines`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "layers",
|
||||
"file": "Documents/poster.xcf",
|
||||
"argv": ["gimp-console-2.10", "-i", "-d", "-f", "-b", "-"],
|
||||
"stdin": "(let ((image (car (gimp-file-load RUN-NONINTERACTIVE \"{file}\" \"{file}\")))) (for-each (lambda (layer) (display \"\\nREA layer \") (display (car (gimp-item-get-name layer)))) (vector->list (cadr (gimp-image-get-layers image)))) (newline))\n(gimp-quit 0)\n",
|
||||
"output": "lines"
|
||||
}
|
||||
```
|
||||
|
||||
checked with `{"kind": "lines_present", "file": "Documents/poster.xcf", "reader": "layers", "lines": ["layer Summer Sale"]}`.
|
||||
Script-Fu's prompt `ts> ` starts a line, so print a newline before each
|
||||
marked line, as `\nREA` does. A text layer's text is
|
||||
`(car (gimp-text-layer-get-text layer))`.
|
||||
|
||||
- Blender `.blend`, objects with their type and location, as `json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "objects",
|
||||
"file": "Documents/scene.blend",
|
||||
"argv": [
|
||||
"blender",
|
||||
"-b",
|
||||
"--factory-startup",
|
||||
"{file}",
|
||||
"--python-expr",
|
||||
"import bpy, json; print('REA ' + json.dumps({o.name: {'type': o.type, 'location': [round(v, 4) for v in o.location]} for o in bpy.data.objects}, sort_keys=True))"
|
||||
],
|
||||
"output": "json"
|
||||
}
|
||||
```
|
||||
|
||||
checked with `{"kind": "value_equals", "file": "Documents/scene.blend", "reader": "objects", "pointer": "/Crate/location/0", "value": 2, "tolerance": 0.001}`.
|
||||
Print every value a check compares as a number or string a check can
|
||||
name, rounded where the app stores floats.
|
||||
Blender 4 shows its Quick Setup splash at every launch until its
|
||||
preferences are saved: with `.config/blender` in `state_paths`, confirm
|
||||
Quick Setup with Continue, save the preferences (Edit → Preferences, then
|
||||
Save Preferences in the menu at its bottom left), and read a probe
|
||||
checkpoint's `changed_files` for `.config/blender/4.0/config/userpref.blend`
|
||||
before `seed`, so solves start on the scene. Blender often takes the first click on a
|
||||
menu or a dialog's button only to focus it: click again.
|
||||
|
||||
- A format LibreOffice opens but REA cannot read, such as a legacy `.xls`,
|
||||
converted with `--convert-to`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "cells",
|
||||
"file": "Documents/budget.xls",
|
||||
"argv": [
|
||||
"sh",
|
||||
"-c",
|
||||
"soffice --headless --convert-to csv --outdir out \"$1\" >/dev/null && sed 's/^/REA /' out/*.csv",
|
||||
"sh",
|
||||
"{file}"
|
||||
],
|
||||
"output": "lines",
|
||||
"timeout_s": 120
|
||||
}
|
||||
```
|
||||
|
||||
Pass `{file}` to `sh -c` as an argument, as here, rather than inside the
|
||||
script.
|
||||
|
||||
The reader runs without the display, in a fresh home with the app's default
|
||||
settings, so use the app's headless or batch mode; set `display: true` only
|
||||
for an app that has none. It must exit 0 within `timeout_s` (60 s by
|
||||
default, at most 300) and print at most 1 MiB. Pick facts the change sets and
|
||||
the near miss gets wrong, such as a name or a number, not the app's whole
|
||||
output.
|
||||
|
||||
Give the task the reader in `readers`, and each check through it `reader`
|
||||
and the reader's `file`. `json` readers serve `value_equals`, `value_absent`
|
||||
and `member_count`; `lines` readers `lines_present`, `lines_absent` and
|
||||
`line_count`. The export runs the reader in the build computer on the seed
|
||||
and the end: when a check through it fails on the end, the refusal shows
|
||||
what the reader printed, and a reader that fails shows its error and the end
|
||||
of its stderr. Fix the reader or the check from that and export again.
|
||||
|
||||
### Judge the screen
|
||||
|
||||
Only when no file shows the change, as when the draft notes `no_change`
|
||||
because the app keeps its state on screen, write the task's checks as
|
||||
screen judges: `{"id": "shown", "kind": "screen_judge", "question": "Does the
|
||||
calculator's display show 8.568?"}`. A model, the judge, answers the question
|
||||
on a screenshot three times, and the check passes when most answers are yes.
|
||||
|
||||
- REA keeps a screenshot at each checkpoint. Mark `seed` with the screen
|
||||
showing the state before the task, where the answer is no, and `end` with
|
||||
the change showing, where it is yes: the bundle ships both as the judge's
|
||||
examples.
|
||||
- Ask about what the change makes visible, with exact values, so the near
|
||||
miss is a no: a result, a label, a selected item. Avoid what a window
|
||||
moved or a cursor blinking can change.
|
||||
- The prompt asks to leave the result showing, since the judge sees only
|
||||
the screen when the agent stops.
|
||||
- A task with screen judges holds only screen judges and no readers. The
|
||||
export refuses one when a file shows the change, and checks none of its
|
||||
questions: the witness does, running the bundle's own judge with the
|
||||
runner's model endpoint (`LITELLM_BASE_URL` and `LITELLM_API_KEY`, or
|
||||
`[model]` in `.agentenv/config.toml`) on a fresh screenshot at each stage.
|
||||
Without an endpoint the witness's check fails: say what to set and stop.
|
||||
- The judge's model is `[model.roles] judge`, else `[model] default`, else
|
||||
`anthropic/claude-sonnet-5-5`. `agent-env run --judge-model` does not
|
||||
reach it. Each grade costs about $0.02.
|
||||
|
||||
## Export
|
||||
|
||||
`export_build_environment` with `task` and `directory`, the absolute path of
|
||||
@@ -211,10 +659,36 @@ 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
|
||||
is no longer empty. A refusal naming a secret's handle means a file of the
|
||||
bundle holds that secret, most often an app's sign-in or licence state in
|
||||
the seed: do not work around it, but report it and stop. 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>#`, GnuCash's `<book>.LCK` or Grisbi's `.<file>.lock`, are
|
||||
left out of the seed and listed after "Left out of the seed". An app can
|
||||
still start fine yet refuse every save when a lock was seeded, so close the
|
||||
document before `seed` where the app lets you (apps other than LibreOffice,
|
||||
such as Rosegarden, also write `.~lock.<name>#` and autosaves beside a
|
||||
document, and closing it covers them too), and treat "file is locked"
|
||||
on a save in the witness as a seeded lock: delete it from the bundle's seed
|
||||
and witness again in a new computer. In LibreOffice, own the profile
|
||||
(`state_paths: [".config/libreoffice"]`) for a clean boot, and close the
|
||||
document before `seed`, then reopen it from Recent Documents to make the
|
||||
change: the export also leaves out the recovery list LibreOffice writes while
|
||||
a document is open, which would start the bundle into document recovery. A
|
||||
limitation naming `~/.config/dconf/user` as unread means the app's dconf
|
||||
settings, such as a first-run tip you turned off, are not seeded: capture
|
||||
again on a new build computer. The limitations also name seeded WebKit,
|
||||
Chromium or QtWebEngine 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.
|
||||
|
||||
@@ -226,17 +700,27 @@ 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
|
||||
`{"source": {"kind": "bundle", "path": "<bundle>"}}`, adding
|
||||
`"settings": {"<variable>": "<handle>"}` for each of the export's
|
||||
`withheld_files`, or the deploy is refused for want of them, and agentenv
|
||||
keeps that bundle's build failed, so start from a fresh copy of it. 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.
|
||||
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.
|
||||
@@ -262,14 +746,17 @@ 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:
|
||||
Only if the requester asked for them, or by the headless default above. 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 `REA_AGENT_ENV_COMMAND`'s runner, or else `agent-env` on PATH:
|
||||
`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.
|
||||
The runner needs a model endpoint in your shell: `LITELLM_BASE_URL` and
|
||||
`LITELLM_API_KEY`, or `base_url` and `api_key` under `[model]` in
|
||||
`.agentenv/config.toml`. When a run says no model endpoint is set, tell the
|
||||
person what to set and stop. 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
|
||||
|
||||
@@ -281,12 +768,15 @@ 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 check, and why it proves the edit and fails the near miss, and each
|
||||
reader's command;
|
||||
- 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;
|
||||
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.
|
||||
|
||||
@@ -308,14 +308,27 @@ 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
|
||||
|
||||
Say what the user wants done, in their words and the app's terms: "Add buy
|
||||
milk to my to-do list and save it". Never say how the file stores it: no
|
||||
Say what the user wants done, in their words and the app's terms, naming the
|
||||
app: "In Mousepad, add buy milk to my to-do list and save it". A solving
|
||||
agent's own shell cannot see the computer's files; the app's name sends it to
|
||||
the screen. Never say how the file stores it: no
|
||||
paths the user would not name, line formats, XML, keys or SQL, and never the
|
||||
checks. Replace the draft's placeholder; the export refuses it.
|
||||
|
||||
@@ -346,13 +359,18 @@ 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
|
||||
text node: apps such as AbiWord and Writer split a paragraph into runs as they
|
||||
save, so its first text node holds only part of it; use `text_contains` for a
|
||||
value within a sentence, such as a time. The
|
||||
value within a sentence, such as a time. A binary document, such as GIMP's
|
||||
`.xcf`, has no view: give the task a `readers` entry, the app's own headless
|
||||
command printing `REA ` lines, and a check naming it in `reader`, as
|
||||
[desktop builds](desktop-build.md#read-a-binary-file-with-a-reader) shows. The
|
||||
[desktop application tasks](https://github.com/morluto/rea/blob/main/docs/desktop-application-tasks.md)
|
||||
guide has the exact rules.
|
||||
|
||||
@@ -374,5 +392,7 @@ user's to choose.
|
||||
|
||||
Tell the user the task's name, prompt and checks, and how to measure a solve
|
||||
rate: run `agent-env run DIRECTORY --task NAME --agent claude-code` with
|
||||
`--model MODEL` three times and count the runs reported `passed`. Do not run
|
||||
`--model MODEL` three times and count the runs reported `passed`. The runs
|
||||
need a model endpoint: `LITELLM_BASE_URL` and `LITELLM_API_KEY`, or
|
||||
`base_url` and `api_key` under `[model]` in `.agentenv/config.toml`. Do not run
|
||||
agents unless asked. The bundle's seed is the user's real data: keep it local.
|
||||
@@ -149,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
|
||||
@@ -185,6 +199,36 @@ absence of those declarations, not proof the image never carried notes in
|
||||
another container. See
|
||||
[ELF note tables](https://github.com/morluto/rea/blob/main/docs/elf-notes.md).
|
||||
|
||||
## ELF and Mach-O initializer functions
|
||||
|
||||
Use `inspect_native_initializers` for an explicit local ELF or Mach-O image
|
||||
when the question is which functions run before `main` or at exit: ELF
|
||||
`DT_PREINIT_ARRAY`, `DT_INIT`, `DT_INIT_ARRAY`, `DT_FINI`, `DT_FINI_ARRAY` and
|
||||
legacy `.ctors`/`.dtors`, or Mach-O `__mod_init_func`, `__init_offsets` and
|
||||
`__mod_term_func`. Pass `architecture` for a universal Mach-O. The CLI
|
||||
equivalent is `inspect-native-initializers PATH`. PIE slots are resolved
|
||||
through RELATIVE, RELR and section relocations, and Mach-O slots through
|
||||
chained fixups. Keep each entry's `resolution`: `unresolved` means the value was
|
||||
not established, and `unresolved_import` names an external symbol. Page with
|
||||
`offset` and `limit`. See
|
||||
[ELF and Mach-O initializer functions](https://github.com/morluto/rea/blob/main/docs/guides/native/native-initializers.md).
|
||||
|
||||
## ELF unwind function ranges
|
||||
|
||||
Use `inspect_elf_unwind_ranges` for an explicit local ELF32/ELF64 image when
|
||||
the question concerns function starts and lengths that survive `strip`, which
|
||||
functions have an LSDA, or which ranges have no exact symbol. No
|
||||
`open_binary` or target execution is required. The CLI equivalent is
|
||||
`inspect-elf-unwind-ranges PATH`. Preserve artifact SHA-256, FDE start and
|
||||
end, containing section, exact symbol name, CIE index, LSDA, and personality.
|
||||
Page later ranges with `offset` and `limit`. A missing `.eh_frame` is
|
||||
observed absence of that declaration and of `PT_GNU_EH_FRAME`, not proof the
|
||||
image has no functions. Header disagreement is a limitation and does not drop
|
||||
decoded ranges. `.debug_frame` is reported present or absent and is not
|
||||
decoded. CFA instructions are counted and not evaluated. Indirect EH pointers
|
||||
are not dereferenced. See
|
||||
[ELF unwind function ranges](https://github.com/morluto/rea/blob/main/docs/guides/native/elf-unwind-ranges.md).
|
||||
|
||||
## Apple IPS crash reports
|
||||
|
||||
Use `inspect_apple_ips` for an explicit local Apple `.ips` file when the
|
||||
@@ -216,6 +260,27 @@ container. gzip, xz, and zstd whole-file containers are unsupported and name
|
||||
decompress into a separate file, then call `inspect_kernel_module` on that file. See
|
||||
[Linux kernel modules](https://github.com/morluto/rea/blob/main/docs/kernel-modules.md).
|
||||
|
||||
## Linux kernel build config
|
||||
|
||||
Use `inspect_kernel_build_config` for an explicit local kernel image (`vmlinux`
|
||||
ELF, raw arm64 `Image`, x86 `bzImage`/`zImage`, or `configs.ko`) when the
|
||||
question is which kernel version it is or how it was configured. No
|
||||
`open_binary`, Linux host, or `extract-ikconfig` is required. The CLI
|
||||
equivalent is `inspect-kernel-build-config PATH`; pass `name` for one exact
|
||||
`CONFIG_*` option and `offset`/`limit` to page the rest. Preserve the banner
|
||||
version, builder, and compiler, the config SHA-256 and option count, and each
|
||||
entry's value kind (`y`, `m`, `string`, `number`, `not_set`). A config is
|
||||
accepted only when `IKCFG_ST` is immediately followed by a valid gzip member
|
||||
and `IKCFG_ED`, so an ordinary `IKCFG_ST` string is not a config. Offsets with
|
||||
`space: "inflated_payload"` are positions in an inflated bzImage payload, not
|
||||
file offsets. An absent config describes only the searched bytes; the kernel
|
||||
may have been built without `CONFIG_IKCONFIG` or with it as a module. Truncated
|
||||
payloads are incomplete, not absent. A framed blob that does not decode, has a
|
||||
bad CRC, or holds non-config text is `malformed`, not absent. xz, lz4, lzma, zstd, bzip2, and lzo
|
||||
payloads are unsupported and name `external_decompression`: decompress with an
|
||||
external utility, then call `inspect_kernel_build_config` on the result. See
|
||||
[Linux kernel build config](https://github.com/morluto/rea/blob/main/docs/guides/native/kernel-build-config.md).
|
||||
|
||||
## CPython pyc files
|
||||
|
||||
Use `inspect_python_pyc` for an explicit local CPython 3.7–3.13 `.pyc` when the
|
||||
@@ -843,3 +908,24 @@ Layout labels describe record shapes, not a detected compiler version; unknown
|
||||
or ambiguous layouts are unsupported. Bytecode is retained, not decoded, and the
|
||||
executable is never run. See
|
||||
[Bun standalone executables](https://github.com/morluto/rea/blob/main/docs/bun-standalone.md).
|
||||
|
||||
## Deno compile executables
|
||||
|
||||
A `deno compile` executable stores its application in a Mach-O `__SUI,d3n0l4nd`
|
||||
section, an Intel Mach-O `<~sui-data~>` trailer, an ELF `SUI` note of type
|
||||
`0x53554901`, or a PE `RT_RCDATA` resource named `D3N0L4ND`.
|
||||
`open_binary` then `inspect_artifact` reports root format `deno-standalone`
|
||||
with the carrier, entry point, recorded options, and one occurrence per virtual
|
||||
file, including size and SHA-256. Transpiled output, CJS export analysis, and
|
||||
source maps are separate occurrences with the file's `index` and their own
|
||||
`role`. They normally use a `.deno-*` suffix on the file path and move to an
|
||||
indexed path on a collision, so use the reported `logical_path`. Symlink targets
|
||||
stay recorded path parts. A virtual filesystem that cannot be listed leaves
|
||||
coverage unknown.
|
||||
Environment-file values and CA certificate bytes are retained in local Evidence
|
||||
with their counts and byte lengths. The npm snapshot length is reported and not
|
||||
decoded. `extract-artifact` writes
|
||||
stored files through the safe output tree; route extracted JavaScript to
|
||||
`analyze_javascript_application`. Other layouts are unsupported, and the
|
||||
executable is never run. See
|
||||
[Deno compile executables](https://github.com/morluto/rea/blob/main/docs/deno-standalone.md).
|
||||
@@ -41,6 +41,12 @@ 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.
|
||||
|
||||
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/guides/runtime/process-capture.md),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -130,6 +130,19 @@ status checks alongside its existing checks. Deploy the workflow to each
|
||||
protected target branch before requiring it there. The workflow reads PR
|
||||
metadata using trusted default-branch code and writes only a commit status.
|
||||
|
||||
When an open PR may overlap another open change or a recently landed fix, note
|
||||
the related PR, issue, or commit in the description or a comment as soon as the
|
||||
overlap is known. Prefer one clear pointer over repeated status updates.
|
||||
|
||||
If an overlapping change merges while a PR awaits review, link that commit on
|
||||
the open PR and state what remains useful. Rebase or otherwise align with the
|
||||
current base when the remaining work is still wanted, narrow the PR to the
|
||||
uncovered portion, or close it when the change is fully superseded. Keep the
|
||||
description and validation current after that update. Maintainers may also note
|
||||
the expected disposition (rebase, narrow, or close) when they land or recognize
|
||||
an overlapping fix. Readiness still does not grant merge permission or a review
|
||||
date.
|
||||
|
||||
Maintainers may return a PR to the author or close it when the problem is
|
||||
unsupported, validation is missing, or the owner cannot explain the change.
|
||||
Contributors are responsible for completing this work before requesting review.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
**English** · [简体中文](docs/readme/README_zh.md) · [繁體中文](docs/readme/README_zh-TW.md) · [日本語](docs/readme/README_ja.md) · [한국어](docs/readme/README_ko.md) · [Türkçe](docs/readme/README_tr.md) · [Русский](docs/readme/README_ru.md) · [Tiếng Việt](docs/readme/README_vi.md) · [ไทย](docs/readme/README_th.md) · [Deutsch](docs/readme/README_de.md) · [Español](docs/readme/README_es.md) · [Français](docs/readme/README_fr.md) · [Українська](docs/readme/README_uk.md) · [Polski](docs/readme/README_pl.md) · [Português (Brasil)](docs/readme/README_pt-BR.md) · [العربية](docs/readme/README_ar.md) · [فارسی](docs/readme/README_fa.md) · [Bahasa Indonesia](docs/readme/README_id.md) · [Italiano](docs/readme/README_it.md)
|
||||
· [Ελληνικά](docs/readme/README_el.md) · [മലയാളം](docs/readme/README_ml.md) · [Roman Urdu](docs/readme/README_ur-Latn.md) · [Română](docs/readme/README_ro.md)
|
||||
· [Ελληνικά](docs/readme/README_el.md) · [മലയാളം](docs/readme/README_ml.md) · [Roman Urdu](docs/readme/README_ur-Latn.md) · [Română](docs/readme/README_ro.md) · [Български](docs/readme/README_bg.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -204,6 +204,7 @@ Additional tools and host support depend on the target:
|
||||
| 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) |
|
||||
@@ -230,6 +231,7 @@ Additional tools and host support depend on the target:
|
||||
| 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) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | None (static only); [Deno compile executables](docs/deno-standalone.md) |
|
||||
|
||||
Static JavaScript and .NET inspection read the supplied files without running
|
||||
the application. Runtime capture runs or interacts with the selected target
|
||||
@@ -335,6 +337,12 @@ REA exports a runnable environment with a basic test to check that it starts and
|
||||
[Environment reference](docs/agent-environments.md) ·
|
||||
[Watch the demo on X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Desktop app environments
|
||||
|
||||
REA can also build an environment of a Linux desktop app, which an agent uses through screenshots, the mouse and the keyboard. From a one-line request, such as "Build me a Gnote environment where the agent adds olive oil to the shopping list note", your agent installs the app on a local build computer, writes the task, exports the environment and checks the task in a fresh computer. The machine that builds it needs Linux on amd64 or arm64, Docker and the agentenv framework version the guide pins.
|
||||
|
||||
[Set up desktop app environments](docs/desktop-build-computer.md)
|
||||
|
||||
## FAQ
|
||||
|
||||
<details>
|
||||
|
||||
+255
-12
@@ -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,20 +184,38 @@ 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.
|
||||
reader = os.open(control, os.O_RDWR)
|
||||
process = None
|
||||
try:
|
||||
with open(os.path.join(capture, "capture.out"), "wb") as out, \
|
||||
open(os.path.join(capture, "progress.log"), "wb") as progress:
|
||||
process = subprocess.Popen(
|
||||
["sh", "-c", 'done=$1; shift; "$@"; code=$?; printf "%s" "$code" > "$done.tmp" && mv "$done.tmp" "$done"',
|
||||
"sh", os.path.join(capture, "exit"), *argv],
|
||||
cwd=os.path.expanduser("~"), env=_environment(work), stdin=reader, stdout=out, stderr=progress,
|
||||
start_new_session=True)
|
||||
try:
|
||||
with open(os.path.join(capture, "capture.out"), "wb") as out, \
|
||||
open(os.path.join(capture, "progress.log"), "wb") as progress:
|
||||
process = subprocess.Popen(
|
||||
["sh", "-c", 'done=$1; shift; "$@"; code=$?; printf "%s" "$code" > "$done.tmp" && mv "$done.tmp" "$done"',
|
||||
"sh", os.path.join(capture, "exit"), *argv],
|
||||
cwd=os.path.expanduser("~"), env=_environment(work), stdin=reader, stdout=out, stderr=progress,
|
||||
start_new_session=True)
|
||||
except Exception as cause:
|
||||
# Nothing will write exit. Record one and drop the FIFO, so stop does not wait on it.
|
||||
try:
|
||||
with open(os.path.join(capture, "exit"), "w", encoding="utf-8") as handle:
|
||||
handle.write("1")
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
os.unlink(control)
|
||||
except OSError:
|
||||
pass
|
||||
return _say({"error": f"the capture did not start: {cause}"})
|
||||
finally:
|
||||
os.close(reader)
|
||||
if process is None:
|
||||
return _say({"error": "the capture did not start"})
|
||||
waited = _wait(capture, 0, {"window_open"}, None, arguments.get("timeout_s", 120))
|
||||
return _say({"pid": process.pid, "apt": apt, **waited})
|
||||
|
||||
@@ -175,11 +234,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:
|
||||
@@ -229,6 +290,187 @@ def run(arguments: dict) -> int:
|
||||
"stderr": done.stderr[-TAIL_BYTES:].decode("utf-8", "replace")})
|
||||
|
||||
|
||||
# The controller is sent with python -c, so a detached supervisor needs its
|
||||
# own source. It alone holds the child process handle and signals its group.
|
||||
LONG_RUN = r'''
|
||||
import json, os, signal, subprocess, sys, threading, time
|
||||
job = sys.argv[1]
|
||||
result = {}
|
||||
child = None
|
||||
drainer = None
|
||||
stderr_tail, stderr_errors = bytearray(), []
|
||||
|
||||
def drain(stream):
|
||||
try:
|
||||
while chunk := stream.read1(65536):
|
||||
stderr_tail.extend(chunk)
|
||||
del stderr_tail[:-4096]
|
||||
except OSError as error:
|
||||
stderr_errors.append(str(error))
|
||||
finally:
|
||||
try:
|
||||
stream.close()
|
||||
except OSError as error:
|
||||
stderr_errors.append(str(error))
|
||||
|
||||
def timed_out_marker():
|
||||
try:
|
||||
open(os.path.join(job, "timed_out"), "x").close()
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
try:
|
||||
request = json.loads("".join(sys.argv[2:]))
|
||||
if os.path.exists(os.path.join(job, "cancel")):
|
||||
result = {"absent": True}
|
||||
else:
|
||||
with open(request["stdout"], "wb") as out:
|
||||
child = subprocess.Popen(request["argv"], cwd=request["home"], stdin=subprocess.DEVNULL,
|
||||
stdout=out, stderr=subprocess.PIPE, start_new_session=True)
|
||||
drainer = threading.Thread(target=drain, args=(child.stderr,), daemon=True)
|
||||
drainer.start()
|
||||
deadline = time.monotonic() + request["timeout_s"]
|
||||
interrupted = False
|
||||
timed_out = False
|
||||
while child.poll() is None:
|
||||
timed_out = timed_out or time.monotonic() >= deadline
|
||||
if not interrupted and (timed_out or os.path.exists(os.path.join(job, "cancel"))):
|
||||
interrupted = True
|
||||
if timed_out:
|
||||
timed_out_marker()
|
||||
try:
|
||||
os.killpg(child.pid, signal.SIGINT)
|
||||
except OSError:
|
||||
pass
|
||||
time.sleep(0.2)
|
||||
# A descendant can still hold stderr after the leader exits. Do
|
||||
# not publish completion until that stream has actually closed.
|
||||
while drainer.is_alive():
|
||||
drainer.join(0.2)
|
||||
if time.monotonic() >= deadline:
|
||||
timed_out = True
|
||||
timed_out_marker()
|
||||
result = {"exit_code": child.returncode, "stdout_bytes": os.path.getsize(request["stdout"]),
|
||||
"timed_out": timed_out, "cancelled": interrupted and not timed_out,
|
||||
"stderr": bytes(stderr_tail).decode("utf-8", "replace")}
|
||||
if stderr_errors:
|
||||
result["error"] = f"The REA command's stderr could not be read: {stderr_errors[0]}"
|
||||
except Exception as error:
|
||||
result["error"] = f"The REA command supervisor failed: {error}"
|
||||
# Keep the child handle until it exits, including when cancellation arrives
|
||||
# after an unexpected supervisor error.
|
||||
while child is not None and child.poll() is None:
|
||||
if os.path.exists(os.path.join(job, "cancel")):
|
||||
try:
|
||||
os.killpg(child.pid, signal.SIGINT)
|
||||
except OSError:
|
||||
pass
|
||||
time.sleep(0.2)
|
||||
if drainer is not None and drainer.ident is not None:
|
||||
drainer.join()
|
||||
if child is not None:
|
||||
result.setdefault("exit_code", child.returncode)
|
||||
result.setdefault("stderr", bytes(stderr_tail).decode("utf-8", "replace"))
|
||||
try:
|
||||
result.setdefault("stdout_bytes", os.path.getsize(request["stdout"]))
|
||||
except OSError:
|
||||
pass
|
||||
if child is None or child.poll() is not None:
|
||||
temporary = os.path.join(job, "result.tmp")
|
||||
with open(temporary, "w", encoding="utf-8") as out:
|
||||
json.dump(result, out)
|
||||
os.replace(temporary, os.path.join(job, "result.json"))
|
||||
'''
|
||||
|
||||
|
||||
def run_begin(arguments: dict) -> int:
|
||||
"""Start one long REA command in its own capture-owned job folder."""
|
||||
rea = shutil.which("rea")
|
||||
if rea is None:
|
||||
return _say({"error": "REA is not installed in this computer"})
|
||||
job = os.path.abspath(arguments["job"])
|
||||
os.makedirs(os.path.dirname(job), exist_ok=True)
|
||||
try:
|
||||
os.mkdir(job, 0o700)
|
||||
except FileExistsError:
|
||||
return _say({"refused": "the command job folder is already used"})
|
||||
process = None
|
||||
try:
|
||||
with open(os.path.join(job, "owner"), "x", encoding="ascii") as out:
|
||||
out.write(arguments["token"])
|
||||
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:
|
||||
handle.write(text)
|
||||
os.makedirs(os.path.dirname(arguments["stdout"]), exist_ok=True)
|
||||
request = json.dumps({"argv": [rea, *arguments["argv"]], "stdout": arguments["stdout"],
|
||||
"home": os.path.expanduser("~"), "timeout_s": arguments["timeout_s"]})
|
||||
chunks = [request[i:i + 60000] for i in range(0, len(request), 60000)]
|
||||
with open(os.path.join(job, "supervisor.log"), "wb") as log:
|
||||
process = subprocess.Popen([sys.executable, "-I", "-c", LONG_RUN, job, *chunks], cwd=os.path.expanduser("~"),
|
||||
env=_environment(os.path.abspath(arguments["work"])), stdin=subprocess.DEVNULL,
|
||||
stdout=log, stderr=log, start_new_session=True)
|
||||
except (OSError, ValueError) as error:
|
||||
stage = "did not start" if process is None else "started but its setup did not finish"
|
||||
result = {"error": f"The REA command supervisor {stage}: {error}"}
|
||||
if process is None:
|
||||
temporary = os.path.join(job, "result.tmp")
|
||||
with open(temporary, "w", encoding="utf-8") as out:
|
||||
json.dump(result, out)
|
||||
os.replace(temporary, os.path.join(job, "result.json"))
|
||||
return _say(result)
|
||||
return _say({"started": True})
|
||||
|
||||
|
||||
def _run_result(job: str):
|
||||
try:
|
||||
with open(os.path.join(job, "result.json"), encoding="utf-8") as source:
|
||||
return json.load(source)
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
|
||||
|
||||
def _owns_run(job: str, token: str) -> bool:
|
||||
try:
|
||||
with open(os.path.join(job, "owner"), encoding="ascii") as owner:
|
||||
return owner.read() == token
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def run_poll(arguments: dict) -> int:
|
||||
job = os.path.abspath(arguments["job"])
|
||||
if not _owns_run(job, arguments["token"]):
|
||||
return _say({"error": "the command job ownership is not confirmed"})
|
||||
deadline = time.monotonic() + arguments.get("timeout_s", 30)
|
||||
while (result := _run_result(job)) is None and time.monotonic() < deadline:
|
||||
time.sleep(POLL_S)
|
||||
if result is None:
|
||||
pending = {"pending": True, "timed_out": os.path.exists(os.path.join(job, "timed_out"))}
|
||||
progress = _tail(os.path.join(job, "supervisor.log"))
|
||||
return _say({**pending, **({"progress": progress} if progress else {})})
|
||||
return _say({"finished": True, **result})
|
||||
|
||||
|
||||
def run_cancel(arguments: dict) -> int:
|
||||
job = os.path.abspath(arguments["job"])
|
||||
os.makedirs(os.path.dirname(job), exist_ok=True)
|
||||
try:
|
||||
os.mkdir(job, 0o700)
|
||||
except FileExistsError:
|
||||
pass
|
||||
else:
|
||||
# A late begin cannot launch into a folder cancellation claimed.
|
||||
with open(os.path.join(job, "owner"), "x", encoding="ascii") as owner:
|
||||
owner.write(arguments["token"])
|
||||
return _say({"absent": True})
|
||||
if not _owns_run(job, arguments["token"]):
|
||||
return _say({"error": "the command job ownership is not confirmed"})
|
||||
with open(os.path.join(job, "cancel"), "a", encoding="utf-8"):
|
||||
pass
|
||||
return run_poll(arguments)
|
||||
|
||||
|
||||
def listing(arguments: dict) -> int:
|
||||
"""Every regular file under a folder, by its path relative to the home, with its size and SHA-256.
|
||||
|
||||
@@ -267,7 +509,8 @@ def listing(arguments: dict) -> int:
|
||||
return _say({"listing_bytes": os.path.getsize(output)})
|
||||
|
||||
|
||||
COMMANDS = {"start": start, "mark": mark, "stop": stop, "run": run, "list": listing}
|
||||
COMMANDS = {"start": start, "mark": mark, "stop": stop, "run": run, "list": listing,
|
||||
"run-begin": run_begin, "run-poll": run_poll, "run-cancel": run_cancel}
|
||||
|
||||
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:]))))
|
||||
@@ -1,12 +1,17 @@
|
||||
"""Exercise the capture controller's filesystem inventory boundary."""
|
||||
|
||||
import json
|
||||
import io
|
||||
from contextlib import redirect_stdout
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from bridge.agentenv import capture
|
||||
|
||||
|
||||
CONTROLLER = Path(__file__).with_name("capture.py")
|
||||
@@ -60,5 +65,168 @@ class CaptureListingTest(unittest.TestCase):
|
||||
self.assertFalse(output.exists())
|
||||
|
||||
|
||||
@unittest.skipIf(sys.platform == "win32", "desktop build computers use Linux")
|
||||
class LongRunTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.tmp.cleanup)
|
||||
self.root = Path(self.tmp.name)
|
||||
self.bin = self.root / "bin"
|
||||
self.bin.mkdir()
|
||||
rea = self.bin / "rea"
|
||||
rea.write_text(
|
||||
f"#!{sys.executable}\n"
|
||||
"import os, signal, subprocess, sys, time\n"
|
||||
"signal.signal(signal.SIGINT, lambda *_: sys.exit(130))\n"
|
||||
"if len(sys.argv) > 1 and sys.argv[1] == 'wait':\n"
|
||||
" open(sys.argv[2], 'w').close()\n"
|
||||
" time.sleep(30)\n"
|
||||
"if len(sys.argv) > 1 and sys.argv[1] == 'ignore':\n"
|
||||
" signal.signal(signal.SIGINT, signal.SIG_IGN)\n"
|
||||
" open(sys.argv[2], 'w').close()\n"
|
||||
" while not os.path.exists(sys.argv[3]): time.sleep(0.02)\n"
|
||||
"if len(sys.argv) > 1 and sys.argv[1] == 'stderr':\n"
|
||||
" sys.stderr.write('x' * 100000 + 'TAIL')\n"
|
||||
"if len(sys.argv) > 1 and sys.argv[1] == 'hold':\n"
|
||||
" subprocess.Popen([sys.executable, '-c', 'import os,sys,time\\nwhile not os.path.exists(sys.argv[1]): time.sleep(0.02)', sys.argv[2]], stdout=subprocess.DEVNULL, stderr=sys.stderr, start_new_session=True)\n"
|
||||
" sys.exit(0)\n"
|
||||
"print(os.environ.get('AGENTENV_CONTROL_TOKEN', 'no token'))\n"
|
||||
)
|
||||
rea.chmod(0o755)
|
||||
self.environment = {**os.environ, "HOME": str(self.root), "PATH": f"{self.bin}{os.pathsep}{os.environ.get('PATH', '')}",
|
||||
"AGENTENV_CONTROL_TOKEN": "not-for-the-child"}
|
||||
self.job = self.root / "job"
|
||||
self.output = self.root / "out.json"
|
||||
|
||||
def command(self, name, **values):
|
||||
result = subprocess.run([sys.executable, str(CONTROLLER), name, json.dumps(values)],
|
||||
env=self.environment, text=True, capture_output=True, timeout=10, check=True)
|
||||
return json.loads(result.stdout)
|
||||
|
||||
def begin(self, argv, timeout=60):
|
||||
return self.command("run-begin", job=str(self.job), work=str(self.root), stdout=str(self.output),
|
||||
token="owner-token", argv=argv, files={}, timeout_s=timeout)
|
||||
|
||||
def test_runs_and_reports_its_output(self):
|
||||
self.assertEqual(self.begin([]), {"started": True})
|
||||
result = self.command("run-poll", job=str(self.job), token="owner-token", timeout_s=5)
|
||||
self.assertEqual(result["exit_code"], 0)
|
||||
self.assertEqual(self.output.read_text().strip(), "no token")
|
||||
|
||||
def test_passes_large_command_without_persisting_its_arguments(self):
|
||||
self.assertEqual(self.begin(["done", *("x" * 4000 for _ in range(20))]), {"started": True})
|
||||
result = self.command("run-poll", job=str(self.job), token="owner-token", timeout_s=5)
|
||||
self.assertEqual(result["exit_code"], 0)
|
||||
self.assertFalse((self.job / "request.json").exists())
|
||||
|
||||
def test_keeps_only_a_bounded_stderr_tail(self):
|
||||
self.assertEqual(self.begin(["stderr"]), {"started": True})
|
||||
result = self.command("run-poll", job=str(self.job), token="owner-token", timeout_s=5)
|
||||
self.assertEqual(len(result["stderr"]), 4096)
|
||||
self.assertTrue(result["stderr"].endswith("TAIL"))
|
||||
|
||||
def test_cancels_a_running_child_and_confirms_exit(self):
|
||||
ready = self.root / "ready"
|
||||
self.assertEqual(self.begin(["wait", str(ready)]), {"started": True})
|
||||
import time
|
||||
deadline = time.monotonic() + 5
|
||||
while not ready.exists() and time.monotonic() < deadline:
|
||||
time.sleep(0.02)
|
||||
self.assertTrue(ready.exists())
|
||||
result = self.command("run-cancel", job=str(self.job), token="owner-token", timeout_s=5)
|
||||
self.assertTrue(result["cancelled"])
|
||||
self.assertEqual(result["exit_code"], 130)
|
||||
|
||||
def test_cancel_before_late_start_claims_the_job(self):
|
||||
self.assertEqual(self.command("run-cancel", job=str(self.job), token="owner-token", timeout_s=1), {"absent": True})
|
||||
self.assertIn("already used", self.begin([])["refused"])
|
||||
self.assertFalse(self.output.exists())
|
||||
|
||||
def test_cancel_refuses_a_folder_without_the_matching_owner(self):
|
||||
self.job.mkdir()
|
||||
(self.job / "owner").write_text("someone-else")
|
||||
result = self.command("run-cancel", job=str(self.job), token="owner-token", timeout_s=1)
|
||||
self.assertIn("ownership is not confirmed", result["error"])
|
||||
self.assertFalse((self.job / "cancel").exists())
|
||||
|
||||
def test_reports_supervisor_output_if_completion_is_unconfirmed(self):
|
||||
self.job.mkdir()
|
||||
(self.job / "owner").write_text("owner-token")
|
||||
(self.job / "supervisor.log").write_text("supervisor failed")
|
||||
result = self.command("run-poll", job=str(self.job), token="owner-token", timeout_s=0)
|
||||
self.assertEqual(result["progress"], "supervisor failed")
|
||||
self.assertTrue(result["pending"])
|
||||
|
||||
def test_reports_a_timed_out_child_that_has_not_stopped(self):
|
||||
ready, release = self.root / "ready", self.root / "release"
|
||||
self.assertEqual(self.begin(["ignore", str(ready), str(release)], timeout=3), {"started": True})
|
||||
try:
|
||||
result = self.command("run-poll", job=str(self.job), token="owner-token", timeout_s=4)
|
||||
self.assertTrue(result["pending"])
|
||||
self.assertTrue(result["timed_out"])
|
||||
self.assertTrue(ready.exists())
|
||||
finally:
|
||||
release.touch()
|
||||
self.command("run-poll", job=str(self.job), token="owner-token", timeout_s=5)
|
||||
|
||||
def test_waits_for_an_inherited_stderr_pipe_after_the_child_exits(self):
|
||||
release = self.root / "release"
|
||||
self.assertEqual(self.begin(["hold", str(release)], timeout=3), {"started": True})
|
||||
try:
|
||||
result = self.command("run-poll", job=str(self.job), token="owner-token", timeout_s=4)
|
||||
self.assertTrue(result["pending"])
|
||||
self.assertTrue(result["timed_out"])
|
||||
finally:
|
||||
release.touch()
|
||||
result = self.command("run-poll", job=str(self.job), token="owner-token", timeout_s=5)
|
||||
self.assertTrue(result["finished"])
|
||||
|
||||
def test_failure_closing_supervisor_log_after_launch_does_not_claim_exit(self):
|
||||
ready = self.root / "ready"
|
||||
original_open = open
|
||||
original_popen = subprocess.Popen
|
||||
supervisors = []
|
||||
|
||||
class FailingClose:
|
||||
def __init__(self, file):
|
||||
self.file = file
|
||||
|
||||
def __enter__(self):
|
||||
return self.file
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.file.close()
|
||||
raise OSError("log close failed")
|
||||
|
||||
def opening(path, *args, **kwargs):
|
||||
file = original_open(path, *args, **kwargs)
|
||||
return FailingClose(file) if str(path).endswith("supervisor.log") else file
|
||||
|
||||
def spawning(*args, **kwargs):
|
||||
process = original_popen(*args, **kwargs)
|
||||
supervisors.append(process)
|
||||
def cleanup():
|
||||
if process.poll() is None:
|
||||
(self.job / "cancel").touch()
|
||||
process.wait(timeout=5)
|
||||
self.addCleanup(cleanup)
|
||||
return process
|
||||
|
||||
arguments = {"job": str(self.job), "work": str(self.root), "stdout": str(self.output),
|
||||
"token": "owner-token", "argv": ["wait", str(ready)], "files": {}, "timeout_s": 60}
|
||||
with patch.dict(os.environ, self.environment, clear=True), patch("builtins.open", side_effect=opening), patch.object(capture.subprocess, "Popen", side_effect=spawning), redirect_stdout(io.StringIO()) as output:
|
||||
capture.run_begin(arguments)
|
||||
self.assertIn("started but its setup did not finish", json.loads(output.getvalue())["error"])
|
||||
import time
|
||||
deadline = time.monotonic() + 5
|
||||
while not ready.exists() and time.monotonic() < deadline:
|
||||
time.sleep(0.02)
|
||||
self.assertTrue(ready.exists())
|
||||
self.assertFalse((self.job / "result.json").exists())
|
||||
result = self.command("run-cancel", job=str(self.job), token="owner-token", timeout_s=5)
|
||||
self.assertTrue(result["cancelled"])
|
||||
supervisors[0].wait(timeout=5)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -3753,6 +3753,20 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
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");
|
||||
@@ -3771,10 +3785,10 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
||||
}
|
||||
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");
|
||||
@@ -3824,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());
|
||||
@@ -3858,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;
|
||||
@@ -3872,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 {
|
||||
@@ -5320,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,
|
||||
|
||||
@@ -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)")
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -43,11 +43,31 @@ export const documentationSections = [
|
||||
source: "guides/native/binary-diagnostics.md",
|
||||
route: "/binary-diagnostics",
|
||||
},
|
||||
{
|
||||
text: "ELF and Mach-O initializer functions",
|
||||
source: "guides/native/native-initializers.md",
|
||||
route: "/native-initializers",
|
||||
},
|
||||
{
|
||||
text: "ELF unwind function ranges",
|
||||
source: "guides/native/elf-unwind-ranges.md",
|
||||
route: "/elf-unwind-ranges",
|
||||
},
|
||||
{
|
||||
text: "Linux kernel build config",
|
||||
source: "guides/native/kernel-build-config.md",
|
||||
route: "/kernel-build-config",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -88,6 +108,11 @@ export const documentationSections = [
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -398,6 +423,11 @@ export const documentationSections = [
|
||||
source: "bun-standalone.md",
|
||||
route: "/bun-standalone",
|
||||
},
|
||||
{
|
||||
text: "Deno compile executables",
|
||||
source: "deno-standalone.md",
|
||||
route: "/deno-standalone",
|
||||
},
|
||||
{
|
||||
text: "Capability composition and ownership",
|
||||
source: "capability-composition.md",
|
||||
|
||||
@@ -16,7 +16,11 @@ product pages. The VitePress documentation source is this `docs/` tree.
|
||||
- [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)
|
||||
- [ELF and Mach-O initializer functions](guides/native/native-initializers.md)
|
||||
- [ELF unwind function ranges](guides/native/elf-unwind-ranges.md)
|
||||
- [Linux kernel build config](guides/native/kernel-build-config.md)
|
||||
- [Recorded crash evidence](guides/native/recorded-crashes.md)
|
||||
- [Windows Shell Link shortcuts](guides/native/windows-shortcut.md)
|
||||
|
||||
## JavaScript and Electron
|
||||
|
||||
@@ -27,6 +31,7 @@ product pages. The VitePress documentation source is this `docs/` tree.
|
||||
- [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
|
||||
|
||||
@@ -143,6 +148,7 @@ the exact commit messages and references from the release they describe.
|
||||
|
||||
- [Offline API contract inventory](api-contracts.md)
|
||||
- [Bun standalone executables](bun-standalone.md)
|
||||
- [Deno compile executables](deno-standalone.md)
|
||||
- [Capability composition and ownership](capability-composition.md)
|
||||
- [.NET single-file bundles](dotnet-bundles.md)
|
||||
- [ESP flash images](esp-flash-image.md)
|
||||
|
||||
@@ -107,7 +107,10 @@ refusal names its stage: `environment-build` for the build's own checks,
|
||||
`inspect_web_network_capture` and `inspect_analysis_view` for inspection and
|
||||
projection, `environment-export` for the bundle. SIGINT cancels the build
|
||||
(`cancelled`); before the bundle stage nothing is written, and a cancellation
|
||||
during the write names the bundle it wrote. Stage progress is logged to stderr
|
||||
after publication preserves the bundle receipt. Before publication, a failed
|
||||
write attempts to remove partial output and reports cleanup failures. See
|
||||
[bundle publication and recovery](getting-started/cli.md#export-an-environment-bundle).
|
||||
Stage progress is logged to stderr
|
||||
at info level; the report is the only output on stdout:
|
||||
|
||||
```json
|
||||
@@ -209,9 +212,9 @@ warning does not establish that these bodies were checked. A browser scenario's
|
||||
saved values (`save` and `save_response`) named like credentials but not marked
|
||||
`secret: true` are recorded unredacted; `credential-named-saved-values` lists up
|
||||
to 20 of them by parameter pointer. Names do not establish sensitivity,
|
||||
so the build never refuses on them. Capture
|
||||
so the build never refuses on them.
|
||||
|
||||
Evidence also records the capture file's absolute path (`subject.local_path`,
|
||||
Capture Evidence also records the capture file's absolute path (`subject.local_path`,
|
||||
`parameters.capture_path`, `locations`, `artifact.path`), and the bundle
|
||||
carries it: build from a neutral folder when that path should not ship.
|
||||
|
||||
@@ -332,9 +335,12 @@ scenario is written and cannot use a value an earlier response returned, so an
|
||||
id must be known before the run: one the caller chooses, such as a `uid` in the
|
||||
create body, or one an earlier scenario created. When the server assigns ids,
|
||||
read the list after each create (the create's response or the list shows the
|
||||
new entity), and record updates and deletes in a second scenario that reads
|
||||
the first one's objects by id before editing them, or make them through the
|
||||
UI. The environment coverage view names each
|
||||
new entity). A second scenario can record updates and deletes using those
|
||||
known ids, but produces a separate environment: recordings are not combined.
|
||||
That scenario must include its own before/after reads and every action the
|
||||
environment should support; it does not inherit the first scenario's create
|
||||
evidence. To capture create and subsequent edits together, make them through
|
||||
the UI in one scenario. The environment coverage view names each
|
||||
write it withholds and what to record next. A scenario with write requests
|
||||
changes the application's data: record against an instance whose data may
|
||||
change.
|
||||
|
||||
+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](guides/native/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.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Deno compile executables
|
||||
|
||||
`inspect-artifact` inventories a `deno compile` executable. `extract-artifact` writes the embedded virtual files through the existing safe output tree. Neither operation runs the executable or the Deno runtime.
|
||||
|
||||
```sh
|
||||
rea inspect-artifact ./app --json
|
||||
rea extract-artifact ./app --json
|
||||
```
|
||||
|
||||
In MCP, open the executable with `open_binary`, then call `inspect_artifact`. Use `detail: "summary"` for a large virtual filesystem and `inspect_analysis_view` to page retained Evidence.
|
||||
|
||||
The recognized carriers are a Mach-O `__SUI` section named `d3n0l4nd`, an Intel Mach-O `<~sui-data~>` trailer, an ELF `PT_NOTE` or `SHT_NOTE` owned by `SUI` with type `0x53554901` and descriptor name `d3n0l4nd`, and a PE `RT_RCDATA` resource named `D3N0L4ND`. These are structural layouts. The metadata JSON has no Deno version field, so the compiler version stays unknown unless another record establishes it. Other layouts, including older eszip trailers, are unsupported.
|
||||
|
||||
Root metadata reports the carrier, entry point, argv, V8 flags, permission options, unstable configuration, application name, self-extracting marker, virtual-filesystem case sensitivity, and the npm snapshot byte length. The npm snapshot is not decoded. Each virtual file is one occurrence with its logical path, size, and SHA-256. Transpiled output, CJS export analysis, and source maps are separate occurrences beside that file. Each has the same `index` as the file and its own `role`. A region normally has the logical path of the file plus a `.deno-*` suffix. When that path belongs to another stored file, the region moves to an indexed path such as `deno-vfs/0.vfs-transpiled`, so read the reported `logical_path` instead of building it from the file name. They are not linked by `parent_occurrence_id`, which follows directories and expanded containers. Symlink targets stay recorded path parts and are never followed.
|
||||
|
||||
`Metadata.env_vars_from_env_file` holds values from a compile-time `--env-file`, and `ca_data` holds certificate bytes. Inventory retains the variable names and values, certificate bytes, counts, and byte lengths in local Evidence, so sharing that Evidence shares them. Extraction does not write them as files.
|
||||
|
||||
A virtual filesystem that cannot be listed reports `vfs_listing` as `unsupported` and leaves inventory and extraction coverage unknown, because its files are not examined.
|
||||
|
||||
Remote modules, redirects, and specifiers contribute counts and logical paths when their stored form is unambiguous. When it is not, they stay present with a byte length and an `unsupported` member listing. A module whose specifier is missing uses an indexed `deno-remote/<index>` path, which still exposes its stored bytes, and modules with resolved specifiers keep their paths. Colons, backslashes, and control characters in a specifier are percent-encoded in the logical path, so `http://localhost:8000/mod.ts` becomes `deno-remote/localhost%3A8000/mod.ts`. Percent escapes in a logical path use uppercase hex, and a specifier that reaches a path already taken uses an indexed path. `source_path` keeps the original specifier. A remote specifier is indexed the same way when a path component exceeds 255 UTF-8 bytes or the logical path exceeds 512 UTF-8 bytes, counting the `.deno-*` suffix of its stored regions. Unsafe, deep, or over-long virtual names use `deno-vfs/<index>` under the same rule and retain the original spelling when it fits the name allowance. A descendant does not present its own name as a complete source path when an ancestor spelling was dropped.
|
||||
|
||||
A length that overruns the section, or a closing marker that does not match, is malformed. An opening marker that is absent is unsupported. A confirmed section that cannot be parsed fails closed and does not fall through to a plain native inventory. An Intel Mach-O sentinel inside a confirmed trailer payload is data of that payload, so an Intel Deno executable stored as a virtual file does not replace the app that stores it. Trailers side by side with different bytes fail closed. A file is confirmed only by its carrier name, so an unrelated native file with malformed tables keeps its native inventory. That inventory does not establish that the file holds no Deno section.
|
||||
|
||||
See [limits and recovery](design/limits-and-recovery.md) for the named allowances. Synthetic tests cover the carriers and malformed declarations. Run `npm run verify:deno:standalone` for a local Deno compile of the host and, when the compiler can produce them, Linux, Windows, and Intel macOS targets. Deno is a fixture producer only and is not installed by REA. The produced executable is not run.
|
||||
|
||||
Layout reference: Deno `cli/lib/standalone/binary.rs` and `cli/lib/standalone/virtual_fs.rs` at 2.9.8, with libsui 0.16.4 section placement.
|
||||
@@ -430,3 +430,58 @@ artifact expansion budget also bounds the sum of referenced member lengths. Refu
|
||||
There is no runtime override; additional host memory or `NODE_OPTIONS` does not
|
||||
raise these ceilings. Use a smaller producer fixture or a separately reviewed
|
||||
reader for larger graphs. No partial extraction is claimed on admission failure.
|
||||
|
||||
## Deno compile sections
|
||||
|
||||
`MAX_DENO_METADATA_JSON_BYTES` admits at most 8 MiB of metadata JSON.
|
||||
`MAX_DENO_VFS_HEADER_JSON_BYTES` admits at most 32 MiB of virtual-filesystem
|
||||
header JSON. Specifier, redirect, and remote tables each admit at most 100,000
|
||||
records. Specifier text admits at most 8 MiB, and remote module bodies admit at
|
||||
most 256 MiB. The virtual filesystem admits at most 100,000 directory, file,
|
||||
and symlink records and at most 512 nested levels (`MAX_DENO_VFS_DEPTH`). A
|
||||
name longer than 4,096 UTF-16 code units is indexed and is not retained.
|
||||
`MAX_DENO_VFS_RETAINED_UNITS` admits at most 32 million UTF-16 code units across
|
||||
the source path built for every entry, directories included, and retained
|
||||
symlink parts. A logical path deeper than 256 parts, a name that is not a safe
|
||||
relative path, a path component longer than 255 UTF-8 bytes
|
||||
(`MAX_DENO_PATH_COMPONENT_BYTES`, POSIX `NAME_MAX`), or a logical path longer
|
||||
than 512 UTF-8 bytes (`MAX_DENO_LOGICAL_PATH_BYTES`, half of the Darwin
|
||||
`PATH_MAX`) uses an indexed path and keeps the original spelling when that
|
||||
spelling is within the name allowance. Component and path lengths include the
|
||||
`.deno-*` suffix of the stored regions a member has. A descendant has no source
|
||||
path when an ancestor spelling was not retained. Cancellation is checked before
|
||||
the virtual-filesystem walk. The walk does not yield, so it does not observe a
|
||||
cancellation that arrives while it is running; the retained allowance bounds its
|
||||
work. The combined logical path tree admits at most 250,000 distinct prefixes.
|
||||
`MAX_DENO_RETAINED_BYTES` admits at most 256 MiB of retained header and entry
|
||||
metadata. The shared artifact expansion budget also bounds the sum of referenced
|
||||
member lengths, with a 256 MiB floor.
|
||||
|
||||
Carrier location claims a file only after it confirms the carrier name: a
|
||||
Mach-O `__SUI` segment, a `SUI` ELF note descriptor named `d3n0l4nd`, a PE
|
||||
`D3N0L4ND` resource, or an Intel trailer opening with `d3n0l4nd`. Before that,
|
||||
malformed tables and exhausted search budgets leave the file with native
|
||||
inventory, and that inventory makes no claim that the file holds no Deno
|
||||
section. ELF location reads ELF and note headers, not the whole image, and does
|
||||
not hash note descriptors. An ELF larger than 512 MiB is still located when
|
||||
those headers fit. Program and section tables are read at their canonical record
|
||||
size, so the 16-bit header count bounds each read at 65,535 records. A table
|
||||
that cannot be read, or that uses extended program numbering, is skipped and
|
||||
another table can still hold the note. At most 256 notes are examined
|
||||
(`MAX_INSPECT_ELF_NOTE_ENTRIES`). A damaged table or the note ceiling is a
|
||||
refusal only when a `SUI` note was also confirmed. Intel Mach-O trailer search
|
||||
reads each scanned byte at most once and examines at most 64 `<~sui-data~>`
|
||||
sentinels (`MAX_DENO_INTEL_TRAILER_SENTINELS`). The search continues past a
|
||||
confirmed trailer, because an enclosing trailer can hold it as a stored file, so
|
||||
reaching that allowance after a confirmation is a refusal. PE location walks the resource directories to the named payload and
|
||||
does not read the image whole, so a PE of any size is located when the
|
||||
`D3N0L4ND` payload is within the 512 MiB resource reader ceiling. A larger
|
||||
payload, or a confirmed resource that cannot be resolved, is a named refusal.
|
||||
Refusals name the boundary. There is no runtime override; additional host memory
|
||||
or `NODE_OPTIONS` does not raise these ceilings. Duplicate-section verification
|
||||
rejects unequal lengths before hashing, stops at the first digest mismatch,
|
||||
and reads at most the carrier file size in aggregate
|
||||
payload bytes. Overlapping copies that exceed that allowance are refused.
|
||||
Environment-file values and CA certificate bytes are retained in local Evidence
|
||||
with their counts and byte lengths. The npm snapshot length is retained and its
|
||||
bytes are not decoded.
|
||||
@@ -47,6 +47,17 @@ 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.
|
||||
|
||||
A nested desktop file uses a dashed ID: `vendor/app.desktop` has ID
|
||||
`vendor-app`. REA checks path spellings that can encode that ID within each
|
||||
XDG root before trying the next root. Unrelated directories do not affect
|
||||
selection. If an applicable path cannot be examined or the bounded search
|
||||
cannot establish absence, capture reports an incomplete desktop-entry search
|
||||
rather than selecting a different application from a later root.
|
||||
|
||||
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
|
||||
@@ -56,6 +67,9 @@ environment, and reads commands from stdin, one per line. The application gets
|
||||
REA's environment without the `AGENTENV_*` variables an agent environment sets,
|
||||
such as its control token: an app the exported computer launches never has
|
||||
them, and an app captured inside a computer must not hold a credential to it.
|
||||
It also gets `LIBC_FATAL_STDERR_=1`, so glibc writes a fatal error, such as
|
||||
an abort's reason, to the app's stderr rather than its terminal, and an app
|
||||
that exits at launch reports it.
|
||||
|
||||
| Line | Effect |
|
||||
| ------------------------------------------- | ----------------------------------------------------------- |
|
||||
@@ -90,12 +104,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
|
||||
@@ -107,7 +129,11 @@ remain. Interrupting the command (Ctrl-C) ends the session the same way
|
||||
without a further checkpoint; the capture is still written with end reason
|
||||
`cancelled`, and the command exits with status 130. Interrupted before the
|
||||
application is launched, the command writes no capture and removes the
|
||||
content it had retained.
|
||||
content it had retained. If cancellation arrives during publication or final
|
||||
cleanup, the already-written capture can instead retain its earlier end
|
||||
reason. Inspect `capture.json` and the error's `details.partial_observation`
|
||||
for the retained capture Evidence. Cleanup failures also report resources
|
||||
that could not be released.
|
||||
|
||||
If the capture fails for any other reason before `capture.json` is written,
|
||||
the application is closed the same way and the content already retained is
|
||||
@@ -302,20 +328,29 @@ dot-folder named after the package, the executable, the desktop entry's full
|
||||
id and its last part, and the entry's name, with whether each existed at the
|
||||
start. A folder in those places whose name is one of these in another letter
|
||||
case joins them, such as GIMP's `~/.config/GIMP` for the `gimp` package; only
|
||||
the whole name is compared, so `~/.config/GIMPshop` does not. Dotfiles in the
|
||||
the whole name is compared, so `~/.config/GIMPshop` does not. A file under a
|
||||
folder the application creates during the capture beside one of them, with
|
||||
the same name in another letter case or with a version added (`-3.1` or
|
||||
`3`), as TreeLine's `~/.treeline-3.1`, is its state too. 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.
|
||||
@@ -341,7 +376,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,
|
||||
@@ -370,7 +407,11 @@ 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. A lock file
|
||||
the application held open, such as Poedit's `~/poedit.lock` or Lucene's
|
||||
`write.lock`, makes no folder such a directory, since it holds nothing to
|
||||
retain.
|
||||
|
||||
**Limitations.** What the capture could not establish, such as a truncated
|
||||
walk or a missing window.
|
||||
|
||||
@@ -15,13 +15,28 @@ agent-env run ./mousepad-bundle --dry-run
|
||||
|
||||
The export reads the capture and its [state view](desktop-application-state.md);
|
||||
it does not run the application. `--name` sets the environment name; otherwise
|
||||
it comes from the desktop entry id or the program, with an `app-` prefix when
|
||||
it comes from the desktop entry id or the program: a reverse-DNS id's last
|
||||
part (`org.xfce.mousepad` gives `mousepad`), or else the whole id without a
|
||||
trailing version (`glabels-3.0` gives `glabels`), with an `app-` prefix when
|
||||
that name would not be a portable bundle name (for example all digits). The
|
||||
output directory must be new or empty. `--task` adds a task an agent wrote for
|
||||
the capture, once REA has validated it against the capture; see
|
||||
[desktop application tasks](desktop-application-tasks.md). `--package-url`
|
||||
says where the computer downloads the package of an application installed from
|
||||
a `.deb` file; see [Applications from a .deb file](#applications-from-a-deb-file).
|
||||
`--download-install FILE` says which AppImage or tarball a build computer
|
||||
unpacked the application from; see
|
||||
[Applications from an AppImage or tarball](#applications-from-an-appimage-or-tarball).
|
||||
`--extra-package NAME`, repeatable, installs another Ubuntu 24.04 archive
|
||||
package beside the application, such as a runtime piece its package does not
|
||||
install; a [build computer](desktop-build-witness.md) passes its request's
|
||||
`extra_packages`, or a `.deb` request's `dependencies`, this way. A name that
|
||||
is not a Debian package name is refused (`extra_package`). Names the bundle
|
||||
installs anyway, the application's own package and the dependencies it names
|
||||
for a package installed from its `.deb` file, are not repeated; the rest are
|
||||
listed in the limitations and the README. A package the captured `.deb` lists
|
||||
as one alternative, such as `openjdk-17-jre | java-runtime`, is kept when apt
|
||||
installs the application by name, since apt may satisfy it with another.
|
||||
`--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).
|
||||
@@ -33,8 +48,10 @@ 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
|
||||
@@ -42,17 +59,19 @@ Evidence; the bundle itself is complete.
|
||||
|
||||
## The bundle
|
||||
|
||||
| Path | Contents |
|
||||
| -------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `envs/<name>/env.toml` | `type = "computer_app"`, the module and class, `computer = "ubuntu-24.04"`, `driver = "reference"` |
|
||||
| `envs/<name>/<file>.py` | The `ComputerAppEnvironment` class |
|
||||
| `envs/<name>/SKILL.md` | What the app is, its window class and where its files live |
|
||||
| `envs/<name>/seed/` | The application's files at the seed checkpoint, by home-relative path |
|
||||
| `envs/<name>/apt-keys/` | The signing key of each vendor apt repository the app installs from |
|
||||
| `envs/<name>/install-package.sh` | With `--package-url`: the run script that installs the downloaded package with dpkg |
|
||||
| `tasks/smoke.json` | A task that deploys the app |
|
||||
| `tasks/<task>.json` | With `--task`: the agent's task, its verifier in `artifacts/` and the eval in `evals/` |
|
||||
| `README.md` | What was exported, from which capture, and what to keep in mind |
|
||||
| Path | Contents |
|
||||
| --------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `envs/<name>/env.toml` | `type = "computer_app"`, the module and class, `computer = "ubuntu-24.04"`, `driver = "reference"` |
|
||||
| `envs/<name>/<file>.py` | The `ComputerAppEnvironment` class |
|
||||
| `envs/<name>/SKILL.md` | What the app is, its window class and where its files live |
|
||||
| `envs/<name>/seed/` | The application's files at the seed checkpoint, by home-relative path |
|
||||
| `envs/<name>/apt-keys/` | The signing key of each vendor apt repository the app installs from |
|
||||
| `envs/<name>/install-package.sh` | With `--package-url`: the run script that installs the downloaded package with dpkg |
|
||||
| `envs/<name>/install-download.sh` | With `--download-install`: the run script that unpacks the downloaded AppImage or tarball |
|
||||
| `envs/<name>/applications/` | With a tarball's `--download-install`: the desktop entry REA wrote for its program |
|
||||
| `tasks/smoke.json` | A task that deploys the app |
|
||||
| `tasks/<task>.json` | With `--task`: the agent's task, its verifier in `artifacts/` and the eval in `evals/` |
|
||||
| `README.md` | What was exported, from which capture, and what to keep in mind |
|
||||
|
||||
The class file is `<name>_app.py` with hyphens as underscores, for example
|
||||
`mousepad_app.py`: agentenv imports it under its stem, so a plain `<name>.py`
|
||||
@@ -62,9 +81,10 @@ an `App` suffix.
|
||||
|
||||
The class declares:
|
||||
|
||||
- `Packages(apt=[...])` with the package the capture found. A vendor package
|
||||
is named `<package>/<release>`, its repository's release (the Suite apt
|
||||
reports as `a=`, or else its Codename), so apt takes it from that repository
|
||||
- `Packages(apt=[...])` with the package the capture found, then the
|
||||
`--extra-package` names. A vendor package is named `<package>/<release>`,
|
||||
its repository's release (the Suite apt reports as `a=`, or else its
|
||||
Codename), so apt takes it from that repository
|
||||
even when the Ubuntu archive offers a higher version or epoch, as noble's
|
||||
transitional `firefox` does over packages.mozilla.org's; it is named alone
|
||||
when the release names neither, or when the capture was written before
|
||||
@@ -104,7 +124,8 @@ The class declares:
|
||||
reason (a capture
|
||||
written before restrictions were recorded counts as unrestricted); when
|
||||
another usable repository lists the same version it is left out instead,
|
||||
with a limitation. The export also refuses snaps, flatpaks, AppImages, and a
|
||||
with a limitation. The export also refuses snaps, flatpaks, an AppImage or
|
||||
tarball not named with `--download-install`, and a
|
||||
package no recorded repository lists unless it was installed from a `.deb`
|
||||
file the capture recorded and `--package-url` is given, since the computer
|
||||
could not install them by name, and a capture written before credentials
|
||||
@@ -145,7 +166,8 @@ The class declares:
|
||||
README and the result's limitations say the sandbox is off.
|
||||
- `paths`: the state directories holding the application's state files and the
|
||||
folders holding its documents, nested folders collapsed. A folder beside a
|
||||
state directory whose name differs from it only in letter case is owned
|
||||
state directory whose name differs from it only in letter case, or that
|
||||
adds a version, as TreeLine's `~/.treeline-3.1` beside `~/.treeline`, is owned
|
||||
whole in the files' spelling, so a `~/.config/GIMP` profile GIMP created
|
||||
during the capture beside the candidate `~/.config/gimp` is owned as
|
||||
`.config/GIMP`, not as the folder of its first file. The home itself and
|
||||
@@ -154,9 +176,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`
|
||||
@@ -169,10 +193,76 @@ 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`,
|
||||
`SingletonLock` and Lucene's index lock `write.lock` anywhere, as Poedit's
|
||||
translation memory holds, LibreOffice's document lock `.~lock.<name>#`, a
|
||||
`<file>.lck`, `.<file>.lock`, `.<file>.lck` or `<file>.<ext>.lock` beside a
|
||||
file the capture recorded in the same folder, such as GnuCash's
|
||||
`household.gnucash.LCK`, Grisbi's empty `.household.gsb.lock`, which made it
|
||||
refuse every save, and VYM's `plan.vym.lock` (a project's `Gemfile.lock`
|
||||
beside its `Gemfile` has no extension to its file, so it is seeded), and
|
||||
`*.lock` or `*.lck` directly in the home, as wxWidgets' single-instance
|
||||
`~/poedit.lock`, or directly in one of the application's state directories;
|
||||
a lone `notes.lck` or `.notes.lock` elsewhere is seeded. A lock
|
||||
never makes a path the application's own, so `~/poedit.lock` is neither owned
|
||||
nor named among the folders the bundle does not own.
|
||||
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.
|
||||
|
||||
A seed file keeps the permission bits it had at the seed when the capture saw
|
||||
it change, such as a `0600` file an app checks: the class module lists those
|
||||
other than `0644` in `SEED_MODES`, and the first boot sets them when it copies
|
||||
the seed. A file the capture never saw change has no recorded mode and is
|
||||
written `0644`.
|
||||
|
||||
Files in app state are retained regardless of a `.log` extension or `log.<n>`
|
||||
name. They can hold conversation history or database writes as well as
|
||||
diagnostics. The normal host-identity scrub applies to retained text; filenames
|
||||
alone do not identify disposable diagnostics. Locks beside these files follow
|
||||
the lock rules above.
|
||||
|
||||
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`, `Visited Links`,
|
||||
`Platform Notifications/`, and a whole `QtWebEngine/`
|
||||
profile), 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. A seeded LibreOffice profile's
|
||||
`registrymodifications.xcu` ships without its `RecoveryList` items, which
|
||||
LibreOffice writes for the documents it has open and which would start the
|
||||
bundle into document recovery instead of its window; a limitation and the
|
||||
README name the file. REA finds the items with its XML parser, as `item`
|
||||
elements whose `oor:path` is `/org.openoffice.Office.Recovery/RecoveryList`
|
||||
however the tags are spelled, and cuts exactly those elements, so text in a
|
||||
comment or CDATA and every other byte stay as captured. A registry that is
|
||||
not well-formed XML ships unchanged.
|
||||
|
||||
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
|
||||
@@ -182,7 +272,14 @@ 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`. When a dconf database changed by the
|
||||
seed checkpoint but its version there could not be read, as without
|
||||
`dconf-cli`, the export seeds no keys from it and a limitation names it with
|
||||
the read error.
|
||||
|
||||
## The seed checkpoint
|
||||
|
||||
@@ -209,6 +306,39 @@ 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`.
|
||||
|
||||
## Withheld sign-in state
|
||||
|
||||
`--withhold-from <checkpoint> --withhold-to <checkpoint>` withholds every file
|
||||
under the owned paths that changed after the first checkpoint up to the
|
||||
second, as the capture recorded its changes; `--withhold-path <file>` adds a
|
||||
home-relative file, such as one written at first launch. The draft
|
||||
(`describe-desktop-application-task`) takes the same options, leaves those
|
||||
files out and lists them as `withheld_files`; the export refuses a check that
|
||||
names one. Each withheld file present at the seed is left out of
|
||||
`envs/<name>/seed/` and becomes a secret setting:
|
||||
|
||||
- the class declares `Settings` with a `SecretStr` field per file, and
|
||||
`WITHHELD`, each field's home path;
|
||||
- `env.toml` sets each field to `env:REA_<APP>_<FILE>`, so agentenv refuses
|
||||
the deploy, naming the variable, until it is set;
|
||||
- at first boot, before keeping the initial state, the class writes each file
|
||||
from its setting, the file's bytes in base64, mode `0600`, so `data/reset`
|
||||
restores it, and `data/get` serves it neither as a part nor in the views;
|
||||
- the README names each variable, with
|
||||
`export REA_<APP>_<FILE>="$(base64 -w0 < ~/<file>)"` from the receiver's
|
||||
own signed-in copy of the app.
|
||||
|
||||
A withheld file larger than 48 KiB is refused, since its base64 must fit one
|
||||
environment variable. `--withheld-copy <folder>` copies the withheld files,
|
||||
as captured, into a new or empty folder outside the bundle. The result lists
|
||||
them as `withheld_files`, each with its `setting`, `variable` and `handle`.
|
||||
|
||||
`--consent <file>` ships the person's consents, a `consent.json` that
|
||||
`record_build_consent` records, as the bundle's own `consent.json`.
|
||||
`--seed-withheld` seeds the withheld files after all, refused unless that
|
||||
file holds a `seed_sign_in` consent; the result lists them as
|
||||
`consented_files`, and the README says they are there with consent.
|
||||
|
||||
## Host name and user
|
||||
|
||||
A seed can hold the capture host's name and the user's: Geany saved its mail
|
||||
@@ -252,6 +382,28 @@ 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 within the scrub limit ships as captured, its bytes searched.
|
||||
A document the state view did not read can still be decompressed and
|
||||
recompressed under the separate 256 MiB scrub limit; its content is searched
|
||||
even when its format cannot be scrubbed. 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
|
||||
@@ -318,6 +470,73 @@ 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`.
|
||||
|
||||
## Applications from an AppImage or tarball
|
||||
|
||||
A [build computer](desktop-build-computer.md) can install an application from
|
||||
its project's AppImage or tarball, pinned by URL and SHA-256, under
|
||||
`/opt/rea-apps/<desktop entry>`. Neither holds a Debian package, so the
|
||||
capture records the package as `unknown`, and the export takes the install
|
||||
from `--download-install`, a JSON file the build computer writes from its
|
||||
request:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "appimage",
|
||||
"desktop_entry": "org.freecad.FreeCAD",
|
||||
"url": "https://github.com/FreeCAD/FreeCAD/releases/download/1.1.4/FreeCAD_1.1.4-Linux-aarch64-py311.AppImage",
|
||||
"sha256": "675d1a4295b2183e0e1d816a4b5557dcb63aeced4e60aaa28d6c3686f4c71dc9",
|
||||
"architecture": "arm64"
|
||||
}
|
||||
```
|
||||
|
||||
A tarball's adds `program`, its path inside the archive, and optionally
|
||||
`name`. The class then declares
|
||||
`downloads=[Download(url=..., sha256=..., to="vendor/app.AppImage", arch=...)]`
|
||||
(`vendor/app.tar` for a tarball) and `run=[RunScript(script="install-download.sh")]`,
|
||||
the same script the build computer ran, with no apt package for the app. The
|
||||
bundle does not contain the application and supports only the download's
|
||||
architecture; the URL must keep serving those bytes, and the application's
|
||||
licence is the operator's to check.
|
||||
|
||||
The export refuses the file (`download_install`) unless it names an
|
||||
`appimage` or `tarball` with an `http://` or `https://` URL and a SHA-256,
|
||||
the capture launched its `desktop_entry`, the captured program lies under its
|
||||
folder in `/opt/rea-apps`, and the capture ran on its architecture; it
|
||||
refuses `--package-url` beside it.
|
||||
|
||||
## 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
|
||||
@@ -332,7 +551,10 @@ 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 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
|
||||
@@ -363,5 +585,5 @@ when a DOCTYPE names a DTD. Known differences remain:
|
||||
|
||||
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
|
||||
The class was checked against agentenv-framework 0.9.1464 with
|
||||
`python -m agentenv_protocol.computer._declare` and `agent-env run --dry-run`.
|
||||
@@ -25,7 +25,7 @@ changed later. Each path records the evidence the capture holds about it:
|
||||
| ------------------------ | ------------------------------------------------------------------------- |
|
||||
| `state_directory` | It lies in one of the application's state directories, in either spelling |
|
||||
| `opened_by_application` | An application process held it open during a sample |
|
||||
| `named_in_window_title` | An application window title spelled its name or `~/` path on its own |
|
||||
| `named_in_window_title` | An application window title spelled its name, `~/` or absolute path whole |
|
||||
| `selected_path` | It lies under a `--state-path` or absolute `--argument` of the capture |
|
||||
| `dconf_application_keys` | It is a dconf database holding groups whose path names the application |
|
||||
| `desktop_service` | It lies where desktop services and toolkits keep shared files, or caches |
|
||||
@@ -40,11 +40,26 @@ 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
|
||||
`today.txt - Notes`.
|
||||
`today.txt - Notes`, and never by a folder of a path the title shows: in
|
||||
CherryTree's `home-notebook.ctd - /home/user/Documents - CherryTree 1.1.2`,
|
||||
`user` names no file. A name without an extension, such as `Makefile`, must
|
||||
also stand on its own rather than end a longer path, as in
|
||||
`Makefile - Editor`. A file under `~/.cache` or `~/.config/dconf` is never
|
||||
named by a title. The capture's checkpoint acknowledgements rank files by the
|
||||
same rule.
|
||||
|
||||
Application names, which select dconf groups, come from the package, the
|
||||
executable, the desktop entry's id and `StartupWMClass`, and the window match.
|
||||
@@ -70,11 +85,21 @@ whether the file was present, the SHA-256 of its retained bytes, and a view:
|
||||
| `dconf` | The `GVariant` header | Groups whose path names the application, plus the names of the other groups |
|
||||
| `zip` | A zip local file header, `PK\x03\x04`, whatever the name | Its file entries in archive order, each with its own format and view |
|
||||
| `json` | A `.json` name or a leading `{` or `[` that parses | The parsed value, from files up to 4 MiB nested up to 500 levels |
|
||||
| `xml` | An XML name or declaration that parses | An element tree (`name`, `attributes`, `children`); text kept exactly, DTDs never read |
|
||||
| `xml` | An XML name, a declaration or a leading element that parses | An element tree (`name`, `attributes`, `children`); text kept exactly, DTDs never read |
|
||||
| `keyfile` | Only `[group]`, `key=value` and comment lines, with at least one group | Groups of `key` → string value, from files up to 4 MiB |
|
||||
| `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).
|
||||
|
||||
Text that opens with an element, such as a Freeplane map's
|
||||
`<map version="freeplane 1.7.0">` with no declaration, or with a DOCTYPE that
|
||||
has no internal subset and then an element, such as a KmPlot plot's
|
||||
`<!DOCTYPE kmpdoc>` before `<kmpdoc version="4">`, is XML when the whole text
|
||||
is well formed, whatever the file is called, a `.txt` file included;
|
||||
otherwise it stays text. The exported verifier makes the same choice.
|
||||
|
||||
A JSON value holding a number JavaScript would round, such as an integer above
|
||||
2^53, is not read rather than shown rounded.
|
||||
|
||||
@@ -193,6 +218,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,35 +42,457 @@ 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`, `upkeep` or `layout` (see `task`). A record of
|
||||
text fields added to a list of its kind, as GnuCash's
|
||||
`<gnc:transaction>`, is listed field by field, and a field that lists
|
||||
records, as its `<trn:splits>`, record by record, so the cut never hides
|
||||
one. `refers_to` names up to
|
||||
five other elements a value equals the `key` or `id` (`xmi:id` among them)
|
||||
of, outside a view the app keeps of the document, as Umbrello's
|
||||
`listview` mirroring its model by id, with the
|
||||
`attribute` holding it, as HomeBank's `category="44"` names
|
||||
`<cat key="44" name="Groceries"/>`, or the id a child element holds, as a
|
||||
GnuCash split's `<split:account>` names the account whose `<act:id>` it
|
||||
is, shown with its name, `<gnc:account …><act:name>Groceries</act:name>…`;
|
||||
an element added whole lists those of the records of attributes it nests
|
||||
too, as a KMyMoney transaction's splits name their `<ACCOUNT>` and
|
||||
`<PAYEE>`, each once. Where several elements share that key, the one
|
||||
whose tag shares the attribute's stem, as `payee` and `<pay>`, and of
|
||||
those the one named for the attribute, as `account` an `<ACCOUNT>` before
|
||||
an `<ACCOUNTID>`. A plain number names an element only through an
|
||||
attribute so named or ending in `id`, `ref` or `key`, so a list's
|
||||
`count="5"` names no `<FIXVERSION id="5"/>`. A value that changed lists,
|
||||
in `alternatives`, its pointer naming the element by each other identifier
|
||||
or name-like attribute it holds alone among its tag's members, up to
|
||||
three, as an Inkscape text's `[@inkscape:label=Headline]` beside its
|
||||
`[@id=text12]`, for a check to name it by instead; an element its tag
|
||||
alone names inside the first one a condition names, as an EPUB chapter's
|
||||
`h1`, by its `[@id=chapter-two]`. What a check can
|
||||
name comes first, text an edit changed before the rest, so no cut drops
|
||||
the edit, 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.
|
||||
role `document`, or of the app's own state files when no document changed,
|
||||
excluding locks the export leaves out of the seed. App state files ending
|
||||
in `.log` remain eligible for checks.
|
||||
A text file gains `lines_present` for its new lines and `lines_absent` for
|
||||
lines it lost (when either is at most ten), and `line_count` for each line
|
||||
holding a letter whose count changed; JSON and key files gain
|
||||
`value_equals` and `value_absent` by pointer; SQLite tables gain rows added,
|
||||
holding a letter whose count changed; a new line holding an XML attribute
|
||||
REA recognizes as generated, such as a named epoch time or `ID_329023692`, gets a
|
||||
`line_count` of the lines `contains` its text up to that value, as
|
||||
`<node TEXT="Water filter" ID="`, at the end's number, where both views
|
||||
hold the whole file, instead of a `lines_present` another save would
|
||||
fail, or a `volatile_lines` note when no text comes before it. UUID-shaped
|
||||
text stays exact because its shape alone does not show that it was generated;
|
||||
JSON and key files gain
|
||||
`value_equals` and `value_absent` by pointer, a JSON array's records named
|
||||
by an id field each holds alone at both ends (`id`, `uid`, `uuid`, `guid`,
|
||||
`key` or a name ending in `_id` or `Id`), as `/lists/[id=chores]`,
|
||||
whatever order the app saves them in; where the app generated that id, a
|
||||
record both ends hold is named by its kind field and its first name-like
|
||||
string field (a key ending in `name`, `title`, `label` or `caption`),
|
||||
nearest first and up to three keys deep, that holds the same string at
|
||||
both ends and names it alone at each, as TreeLine's category by
|
||||
`/nodes/[format=CATEGORY][>data~1NAME=Science]`, and by its id where none
|
||||
does, as `/nodes/[uid=7584d494d9f511f1a873edd4f1920549]` once its name
|
||||
changed; and a record only one end holds is named by such a field that
|
||||
names it alone at its end and nothing at the other, as TreeLine's new book by
|
||||
`/nodes/[format=BOOK][>data~1Title=The Silk Roads]`, its other fields
|
||||
checked through that selector and the fields the selector reads not, nor
|
||||
a field holding what every like record (one of its kind) at the end holds
|
||||
there, as the empty `children` of every book; and
|
||||
by position only where nothing names a record, as a new book whose title
|
||||
another book holds, with a `by_position` note listing those checks;
|
||||
never a value that is a uid the app generates (a
|
||||
GUID, or 32 hex digits as TreeLine's uuid1), nor a check the seed already
|
||||
passes, as a new record's `format` where another record of that kind held
|
||||
its place; a removed record is checked gone by its own pointer, as
|
||||
`/lists/[id=chores]`, and only where the end holds nothing there, so a
|
||||
record only position reached, whose place another took, is left to the
|
||||
count; `member_count` checks of the
|
||||
arrays whose members were added or removed, of the members' kind where
|
||||
records share a `type`, `kind`, `format` or `category` field, as `/nodes`
|
||||
matching `[format=BOOK]`, and a count guard of the innermost array an edit
|
||||
went through, as for XML; SQLite tables gain rows added,
|
||||
changed and removed, by primary key, and their new row count. An XML file,
|
||||
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]`, then by a coordinate, a long
|
||||
number, a length with its unit, as `svg:height="2.629cm"`, an `xml:id`
|
||||
or `draw:id` of the form `id2` that LibreOffice numbers anew as it saves,
|
||||
so a Draw shape is named by its `draw:name`, or a token,
|
||||
such as `XPOS` or `ItemID`, or an id of random case, as Umbrello's
|
||||
`ubcgF2AWfBmHh` (`u` and twelve letters and digits), an automatic style name an app numbers as it
|
||||
saves and renumbers on reload, as LibreOffice's
|
||||
`presentation:style-name="pr1"` (`P1`, `T1`, `MT1`, `L2` on a
|
||||
`*:style-name`), so a slide's frames are named by `presentation:class`,
|
||||
or an attribute naming
|
||||
view state, such as which layer is `selected`, and last by a child
|
||||
element's text, `[>CHILD=VALUE]`, a name-like tag first, as Osmo's
|
||||
record by `[>first_name=Delphine]`, MuseScore's `<Text>` by
|
||||
`[>style=Title]`, a spreadsheet row by its label cell, or GnuCash's
|
||||
transaction by `[>trn:description=Greenleaf Market]`: text of at most 64
|
||||
characters, never a time or a token or id a program generates; then by
|
||||
an identifier a child carries, `[>CHILD@ATTR=VALUE]`, as a GtkBuilder
|
||||
`<child>` by `[>object@id=submit_button]`, never one an app generates or
|
||||
numbers anew as it saves; and then by text a child joins from elements
|
||||
of its own, as Glade's `[>packing=TrueTrue1]` from a widget's packing
|
||||
properties, which moving the widget changes. A pair
|
||||
counts every member holding both its values, whichever attributes that
|
||||
member ranks first. An element with identifiers is named by those alone;
|
||||
an id the app generates, as Freeplane's `ID_329023692`, or a GUID in
|
||||
any attribute, braced or not, as VYM's `uuid="{18eadb5d-…}"`, ranks
|
||||
last, after a child's text, so a new node is named by its `TEXT` and a
|
||||
new VYM branch by `[>heading=Sunset boat tour]`, while a member
|
||||
both versions hold pairs by such an id first, so records that keep their
|
||||
UUIDs and swap titles read as two title edits. A value that stands for
|
||||
none, as Grisbi's `Id="(null)"` on every transaction, names nothing, so a
|
||||
new transaction is named by its `Nb`. A child's text is
|
||||
counted on every sibling, one an identifier names included, so a title
|
||||
two records share names neither. The selector must name the
|
||||
member alone at both ends, with the same values; a child's text names a
|
||||
member that is in one version only when the list's length changed, so a
|
||||
row whose one cell an edit changed stays that row. 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 `Layer` to `Sun`: it is paired by its first
|
||||
other attribute naming it alone at both ends, as
|
||||
`[@src=data/sun.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. Where that attribute's values number
|
||||
the members in document order, as MyPaint 2 writes `src` as
|
||||
`data/layer-00.png`, `data/layer-01.png` and on along the stack and
|
||||
renumbers them when a layer moves, each version is named by its own
|
||||
value of the renamed identifier instead, `[@name=Sun]` and
|
||||
`[@name=Layer]`.
|
||||
- A child of the document's root that its tag alone names, and that holds
|
||||
a list (two or more elements of one tag and no text of its own) and has
|
||||
an identifier, also gets a condition that keeps it named if the app adds
|
||||
a sibling of its tag, as Dia adds an empty `Background` layer each time
|
||||
it reopens and saves a diagram: an id other than `name` both ends hold,
|
||||
as Inkscape's `[name=g][@id=layer1]`, which a new sibling would not
|
||||
share; else the text of a child both ends hold, as Dia's
|
||||
`[name=dia:layer][>dia:object=#Receive order#]`, which an empty sibling
|
||||
lacks; else its `name`, which a new one may repeat. Deeper, a member of
|
||||
a list named for its tag, as Gnumeric's `gnm:Sheet` in `gnm:Sheets`,
|
||||
holding elements and its tag alone naming it, gets an id, else a
|
||||
name-like child's text, `[name=gnm:Sheet][>gnm:Name=Budget]`, else its
|
||||
`name`. Other steps, and elements with neither, stay as they are.
|
||||
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. An
|
||||
identifier numbering the members 0..N-1 in document order at both ends,
|
||||
where members came or went, as Parley numbers its `<entry id="6">` by
|
||||
where it saves it, ranks after a child's text where a member has one, so
|
||||
a new entry is `[>translation=library]` and its kept neighbours are named
|
||||
alike; Tellico's ids, which count from 1, Tiled's and Rosegarden's,
|
||||
whose members hold no text, stay identity. An element a change added that
|
||||
holds nothing but the id of a record it added elsewhere, as Parley's
|
||||
lesson membership `<entry id="6"/>`, is `upkeep`, listed with `refers_to`
|
||||
on that record, never a check or a count.
|
||||
- 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`, unless it is a field its tag names in a
|
||||
record of two or more fields holding text, as QElectroTech's `<text>`
|
||||
beside `<info_name>` in a `<dynamic_elmt_text>`, or KmPlot's
|
||||
`<equation-0>` beside `<arg-min>`, which is checked itself rather than
|
||||
the record whose text joins its fields; one line of text the app lays
|
||||
out between line breaks, as KmPlot's formula before the next element, is
|
||||
checked, and its siblings guarded, with `normalize_whitespace: true`,
|
||||
and text whose whitespace alone changed, as a formula the app moved to
|
||||
an indented line of its own, gets no check; 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. Text an app keeps in an attribute, one element per run, as Scribus's
|
||||
`<StoryText><ITEXT CH="Spring "/><ITEXT CH="Fair"/>`, gets a `text_equals`
|
||||
with `text_attribute` on the nearest ancestor an attribute names, as
|
||||
`[name=PAGEOBJECT][@ANNAME=Headline]` with `"text_attribute": "CH"`, where
|
||||
that ancestor holds no text nodes and the attribute's holders are runs,
|
||||
none inside another and none carrying an identifier or a name-like
|
||||
attribute beside it, as Umbrello's `<ownedAttribute xmi:id="…"
|
||||
name="email" visibility="private"/>`, a record whose attributes are
|
||||
checked one by one, two or more or one holding words with a space: an
|
||||
element's own attribute, as a Freeplane node's `TEXT` beside the nodes in
|
||||
it, or a lone value, as `<Bool value="false"/>`, is checked where it is.
|
||||
The check covers that attribute and the runs holding it; another change
|
||||
in the frame, as a run's `FONT`, keeps its own check. 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`), one inside such an
|
||||
element, as Word's `<w:r>` run in its `<w:p>`, one whose elements are all
|
||||
inline formatting (`b`, `i`, `u`, `em`, `strong`, `bold`, `italic`, a
|
||||
`span`, `a`, `code`, `sub`, `sup` and the like, Gnote's `size:` and
|
||||
`link:` runs), as `<list-item><bold>olive oil</bold></list-item>`, 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, view state and values standing for none, as HomeBank's
|
||||
new `<ope>` gets its `amount`, `category` and `payee`; a value two or
|
||||
more like siblings all hold, as Grisbi's `Cu="1"`, comes after those
|
||||
that vary, as its `Pa`, `Ca`, `Dt` and `Am`. Records of attributes
|
||||
alone that it nests, as a KMyMoney `<TRANSACTION>` its `<SPLITS>` of
|
||||
`<SPLIT>`, get a `value_equals` of each attribute whose values vary among
|
||||
the like records, its own and those under its like siblings, at most
|
||||
three a record and six in all, as each split's `value` and `payee`, but
|
||||
not one every split holds alike, as `price="1/1"`, nor one each holds
|
||||
equal to an earlier one, as `shares` repeats `value`. Each record is
|
||||
named by an identifier that the app neither generates nor numbers anew
|
||||
in every record holding such a list, as KMyMoney's `S0001` in every
|
||||
transaction, else by its best ranked attribute short of a coordinate or
|
||||
an amount, as `[name=SPLIT][@account=A000001]`. 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; of those copied, an attribute naming an element the seed
|
||||
holds by an id that is no plain number, as an Umbrello attribute's
|
||||
`type` its data type, is the user's choice and keeps its check. A record added to a list that a selector names, as
|
||||
Tellico's `<entry id="4">` or Osmo's `<record>` by its first name, 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, the field its selector names it by unless it is
|
||||
the only one left, as a new VYM branch's `<heading>`, a value every
|
||||
like record holds in that field, as Osmo's `<group>None</group>`, noise,
|
||||
a field holding ids of its own, a date the app stamps in parts, and blank
|
||||
text or times; a field that lists records, as GnuCash's `<trn:splits>`,
|
||||
gets its records' fields instead, each record by its own selector. An
|
||||
attribute every like record holds alike, as GnuCash's `version`, is the
|
||||
format's and gets no check. A record only position names 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.
|
||||
- Where members of a list were added or removed, a `member_count` of the
|
||||
list's members of their tag, and of their kind where they share one
|
||||
(`type`, `kind` or `shape`, as `[name=dia:object][@type=Flowchart - Box]`),
|
||||
unless every member of the tag holds a value of its own, as Tiled's
|
||||
objects a free-form `type` (`well`, `door`, `gate`), which labels each
|
||||
rather than grouping them,
|
||||
equal to the end's number, which differs from the seed's: at most two a
|
||||
file, the shallowest lists first, after the other checks. None for a
|
||||
list of one member at both ends, as a style an app adds for a run, for
|
||||
members of an element a text check reads, which are runs of its text,
|
||||
for an element in mixed content, or for noise.
|
||||
- A decimal written as text, such as `146.83`, is suggested as a number
|
||||
with `tolerance: 0.001`, unless the seed's value, read as the evaluator
|
||||
reads a number (`10` and `1e1` included), is that close too. A
|
||||
`value_equals` that would pass on the seed's value is not suggested.
|
||||
- An element placed by its own position, holding numeric `x` and `y` as a
|
||||
like sibling does, as Xournal++ places each `<text>` note on a layer, is
|
||||
an item of its own, never a run of the others' text: one added whole
|
||||
gets a `text_contains` of its text on the element holding the items,
|
||||
which passes wherever it is placed, and that list's `member_count`.
|
||||
- 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, as VYM's
|
||||
`<select>`, the layer, frame,
|
||||
view or colour the app has current, as Pencil2D's `currentLayer`,
|
||||
scrolling, zoom, the viewport, windows, splitters, a list or tree view
|
||||
mirroring the document, as Umbrello's `listview`, 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, and a preview or thumbnail the app renders, as
|
||||
Xournal++'s `<preview>`), 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]`, or a settings path ending in how a
|
||||
panel shows (`visible`, `hidden`, `expanded`, `geometry`, `size` and the
|
||||
like), as VYM's `<setting key="/treeeditor/visible">`; an identifier the
|
||||
app numbers by position. An `Id` suffix alone does not show that an
|
||||
attribute is generated, so relationship fields such as `accountId` are
|
||||
retained; other save-generated IDs may need manual review; volatile
|
||||
values, UUIDs and epoch times, binary data encoded as base64 (a PNG's
|
||||
`iVBORw0KGgo`, or 256 or more base64 characters mixing cases and
|
||||
digits), an id counter (`uniqueid`, `nextobjectid`), a value equal to an
|
||||
id the change gave a new element where a counter or that element holds
|
||||
it, as Umbrello's `lastobject` holds the new attribute's `xmi:id`, but
|
||||
never a reference on an element both ends hold, as a KMyMoney split
|
||||
moved to a new account, 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`,
|
||||
`entered`), or written whole under such a tag, as GnuCash's
|
||||
`<trn:date-entered><ts:date>2026-11-06 08:53:08 +0000`,
|
||||
which no check ever reads, while a date a user enters in parts, as a
|
||||
birthday, is an edit like any other; an id the app assigns, an `id`
|
||||
element with `type="guid"`, as GnuCash's `<trn:id>`, and text of control
|
||||
characters, as its unset options hold; `upkeep`, a change inside an
|
||||
app's `slots`, as GnuCash's `book:slots`, which it adds to and fills on
|
||||
reopening a book, a count an app keeps of its members, an attribute
|
||||
whose key ends in `count` or an element whose tag names a count, whose
|
||||
integer changed and at each end equals how many elements of one tag it,
|
||||
or the element holding the text, holds there, the counter left out, as
|
||||
VYM's root `branchCount`, KMyMoney's `<TRANSACTIONS count="5">` or
|
||||
GnuCash's `<gnc:count-data>`, or, for a counter the change added, how
|
||||
many of one tag, more than one, it holds as children, as FreeCAD's
|
||||
`<ObjectDeps Count="2">`, while a count a user enters, as an item's
|
||||
`<count>`, is an edit, and the `loext:tab-stop-distance` attributes
|
||||
LibreOffice fills in `styles.xml` while another entry holds the edit,
|
||||
and, while a change outside them is the edit, any
|
||||
change in `styles.xml`, in a document's style containers or its master,
|
||||
handout and notes pages, or to an attribute naming an automatic style
|
||||
(`P1`, `MT1`) at both ends, as Impress after a reload wraps its master pages' fields in a new `MT1` style and
|
||||
rewrites list style `L2`, and a text showing another field that changed
|
||||
alike, its element beside a field naming that one's key, as
|
||||
QElectroTech's `<dynamic_elmt_text>` shows a component's label in its
|
||||
`<text>` beside `<info_name>label</info_name>`; and `layout`, attributes holding a list of
|
||||
numbers, as Dia's `obj_bb` `6.3225,6.15;12.5775,8.15`, or a number a
|
||||
name on its way calls layout (a position, point, box, corner, width,
|
||||
height, side or offset, as `elem_width`), that changed in an element up
|
||||
to three levels below one whose text changed, below the root's own
|
||||
children, while their own element's text did not, as Dia moves and
|
||||
resizes a box around its new text, or below an element whose tag names a
|
||||
diagram, widget, canvas or scene while the model change is elsewhere, as
|
||||
Umbrello grows a class's `classwidget` `height` when an attribute is
|
||||
added; an order's `<amount value="12"/>` beside its new description is
|
||||
content. Geometry that changed with
|
||||
no text beside it, as a CAD sketch's, is content. 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 an XML list, or a
|
||||
`value_equals` through a JSON record added whole, as TreeLine's new book's
|
||||
`data/Author` gives
|
||||
`/nodes/[format=BOOK][>data~1Title=Small Engines of Life]/data/Author`
|
||||
(its like records are those of its kind, named as both ends pair them,
|
||||
and it reads only the check's own field), a field on up to
|
||||
two like siblings, those sharing most of the attributes its selector
|
||||
names it by and its type, as a cell's `Row` or `Col` and `ValueType`,
|
||||
then the nearest first, at its seed value, which the end holds
|
||||
too, trying at most the 16 nearest, so a guard costs the same among
|
||||
thousands of siblings; for a member named as a field, by a name-like attribute alone, as
|
||||
QElectroTech's `elementInformation[@name=label]`, the like siblings of
|
||||
the nearest record out that hold that field too come first, so the other
|
||||
components' labels guard a component's label rather than its other
|
||||
fields: 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, but not one numbering the
|
||||
members in order, as MyPaint's `src`; never through a sibling only
|
||||
position pairs. A guard never selects its sibling by
|
||||
what it reads: a sibling its selector names by the attribute the guard
|
||||
checks, or by a value that is or holds the text it reads, as Glade's
|
||||
`[>object=CancelTrueTrueTrue]` for a button's `Cancel` label, is named by
|
||||
another identifier, name-like attribute or child's text it holds alone
|
||||
at both ends instead, as Tiled's objects by `[@id=2]` rather than the
|
||||
`name` the guard reads, or Glade's button by `[>packing=TrueTrue0]`, or
|
||||
else the guard reads another field, or there is none. A `text_equals` with `text_attribute`
|
||||
reads its siblings the same way. A text file gets a `lines_present` of the
|
||||
nearest two unchanged lines of its first new line's kind, list items with the same
|
||||
marker, as Zim's other `[ ]` action items, or lines the same command
|
||||
opens, as the other headings after LyX's `\begin_layout Section`, or lines
|
||||
of the same keyword or `key:` in other records, as a gettext catalogue's
|
||||
other `msgstr` lines rather than the edited entry's own `msgid`, or else
|
||||
its nearest lines with words in them; each text both ends hold once, never
|
||||
a line with no text of its own, a command such as `\end_layout`, tags
|
||||
alone such as `<fonts>` or `</node>`, or a key alone such as a RedNotebook
|
||||
day's `24:`, nor a line that repeats; an item placed by its own position
|
||||
that an edit added, a `text_contains` of each of up to four kept items'
|
||||
text, nearest first. Where members were only edited, a
|
||||
`member_count` of the innermost list holding the edited element that an
|
||||
edit goes through by a member with like siblings, a record rather than a
|
||||
field of one (a member named by a name-like attribute alone that the
|
||||
record's like siblings hold too), of the edited member's tag and kind, at
|
||||
the seed's number, as Dia's boxes in their layer, MyPaint's layers in
|
||||
their stack or Glade's buttons in their button box: no member of the kind
|
||||
added or removed; never of runs in an element a text check reads, and
|
||||
only where the end holds the same number. A guard of a coordinate comes
|
||||
after those of text. At most four a file besides the count guard, which
|
||||
sits outside that cap, so sibling guards never squeeze it out. 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; `unreadable_view` when no
|
||||
check can read it, as a document REA reads as binary;
|
||||
`volatile_lines` when a text file gained lines holding a value the app
|
||||
generates with no text before it to count them by; `generated_reference`
|
||||
when an array references a newly generated record ID that cannot be checked
|
||||
exactly across runs, with up to five affected `pointers`; and `read_as_text`
|
||||
when a text file opens like XML, with a declaration, a DOCTYPE or an
|
||||
element, but reads as text because its DOCTYPE has an internal subset or
|
||||
it is not well formed, so its checks compare lines that hold attributes in
|
||||
the order the app wrote them.
|
||||
|
||||
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.
|
||||
@@ -80,7 +502,7 @@ and `CIRCLE`, and only `CIRCLE` going from 5 to 9 is the user's change.
|
||||
```json
|
||||
{
|
||||
"name": "add-milk",
|
||||
"prompt": "Add buy milk to my to-do list in Mousepad and save it.",
|
||||
"prompt": "In Mousepad, add buy milk to my to-do list and save it.",
|
||||
"checks": [
|
||||
{
|
||||
"id": "milk",
|
||||
@@ -93,31 +515,35 @@ and `CIRCLE`, and only `CIRCLE` going from 5 to 9 is the user's change.
|
||||
```
|
||||
|
||||
`name` is a portable bundle name other than `smoke` (lowercase letters, digits
|
||||
and hyphens); `prompt` is what the user asks for; `checks` holds 1 to 32
|
||||
and hyphens); `prompt` is what the user asks for, naming the app, since a
|
||||
solving agent's own shell cannot see the computer's files and the app's name
|
||||
sends it to the screen; `checks` holds 1 to 32
|
||||
checks. Each check has a `kind`, a `file` given as a path under the home such as
|
||||
`Documents/todo.txt`, and an optional `id` (`check-1`, `check-2` and so on by
|
||||
position otherwise). A check reads the typed view `data/get` returns for that
|
||||
file, in the shapes of the state view.
|
||||
|
||||
| Kind | Fields | Passes when |
|
||||
| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------ |
|
||||
| `file_present` | | The file exists |
|
||||
| `file_absent` | | The file does not exist |
|
||||
| `lines_present` | `lines` | Every listed line is a whole line of the text view |
|
||||
| `lines_absent` | `lines` | None of the listed lines is |
|
||||
| `line_count` | `exact` or `contains`; `equals`, `at_least` or `at_most` | The number of lines equal to `exact`, or holding `contains`, compares so |
|
||||
| `value_equals` | `pointer`, `value`; optional `tolerance` | The pointer names a value equal to `value`, or within `tolerance` of it |
|
||||
| `value_absent` | `pointer` | The pointer names no value |
|
||||
| `text_equals` | `pointer`, `value`; optional `normalize_whitespace` | The XML element's [whole text](#whole-text) equals `value` |
|
||||
| `text_contains` | `pointer`, `value`; optional `normalize_whitespace` | The XML element's whole text holds `value` |
|
||||
| `row_present` | `table`, `where` | A row of the SQLite table has every column in `where` equal |
|
||||
| `row_absent` | `table`, `where` | No row does |
|
||||
| `row_count` | `table`; optional `where`; `equals`, `at_least` or `at_most` | The number of rows, or of rows matching `where`, compares so |
|
||||
| Kind | Fields | Passes when |
|
||||
| --------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `file_present` | | The file exists |
|
||||
| `file_absent` | | The file does not exist |
|
||||
| `lines_present` | `lines` | Every listed line is a whole line of the text view |
|
||||
| `lines_absent` | `lines` | None of the listed lines is |
|
||||
| `line_count` | `exact` or `contains`; `equals`, `at_least` or `at_most` | The number of lines equal to `exact`, or holding `contains`, compares so |
|
||||
| `value_equals` | `pointer`, `value`; optional `tolerance` | The pointer names a value equal to `value`, or within `tolerance` of it |
|
||||
| `value_absent` | `pointer` | The pointer names no value |
|
||||
| `text_equals` | `pointer`, `value`; optional `normalize_whitespace`, `text_attribute` | The XML element's [whole text](#whole-text) equals `value` |
|
||||
| `text_contains` | `pointer`, `value`; optional `normalize_whitespace`, `text_attribute` | The XML element's whole text holds `value` |
|
||||
| `member_count` | `pointer`; optional `matching`; `equals`, `at_least` or `at_most` | The number of [members of the array](#counting-members), or of those `matching` names, compares so |
|
||||
| `row_present` | `table`, `where` | A row of the SQLite table has every column in `where` equal |
|
||||
| `row_absent` | `table`, `where` | No row does |
|
||||
| `row_count` | `table`; optional `where`; `equals`, `at_least` or `at_most` | The number of rows, or of rows matching `where`, compares so |
|
||||
|
||||
The rules both evaluators follow:
|
||||
|
||||
- An absent file reads as empty: no lines, values or rows. So `lines_absent`,
|
||||
`value_absent` and `row_absent` pass on it and a count is 0.
|
||||
`value_absent` and `row_absent` pass on it and a count of lines or rows is
|
||||
0; `member_count` fails, since its pointer names no array.
|
||||
- A file that has no view (binary, over the read limit, or unreadable) fails
|
||||
every check but `file_present` and `file_absent`. Line checks need a text
|
||||
view, row checks a SQLite view and text checks an XML view, in a file or an
|
||||
@@ -129,7 +555,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`.
|
||||
@@ -149,12 +577,15 @@ The rules both evaluators follow:
|
||||
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
|
||||
at the seed, as the bundle ships it, or at the end checkpoint, the empty
|
||||
pointer (the whole file), a value that names the captured home, or the
|
||||
pointer (the whole file) except in `member_count`, a `matching` that is no
|
||||
selector, a value that names the captured home, or the
|
||||
capture host's name or `user@host` anywhere (which the
|
||||
[export removes from the seed](desktop-application-export.md#host-name-and-user)), a
|
||||
`tolerance` with a value that is not a number, an empty `text_contains`
|
||||
value, or one of only whitespace with `normalize_whitespace`, and a value that
|
||||
looks like a date and time, in ISO 8601 or `asctime`'s form. Other volatile
|
||||
value, or one of only whitespace with `normalize_whitespace`, an empty
|
||||
`text_attribute`, a count without exactly one of `equals`, `at_least` and
|
||||
`at_most`, and a value that looks like a date and time, in ISO 8601 or
|
||||
`asctime`'s form. Other volatile
|
||||
content, such as a
|
||||
counter the app bumps on every save, is for the author to leave out.
|
||||
|
||||
@@ -171,9 +602,31 @@ rather than by its position:
|
||||
`[name=Object]`.
|
||||
- `[@KEY=VALUE]` names the member whose `attributes` hold `KEY="VALUE"`, as
|
||||
the XML view keeps an element's attributes.
|
||||
- `[>PATH=VALUE]` names the member that holds `VALUE` at a path of one to
|
||||
three `/`-separated steps inside it. `>` reads XML and JSON differently:
|
||||
|
||||
| Form | In an XML element | In a JSON record |
|
||||
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
|
||||
| `[>CHILD=VALUE]` | a child element `CHILD` whose text, every text node in it with each run of whitespace collapsed to one space and none at either end, is `VALUE` | the string field `CHILD`, compared whole |
|
||||
| `[>A/B=VALUE]`, up to `[>A/B/C=VALUE]` | a child `A` with a child `B` of that text | the string at `member.A.B`, compared whole |
|
||||
| `[>A@ATTR=VALUE]`, `[>A/B@ATTR=VALUE]` | a child `A` (or its child `B`) whose attribute `ATTR` is `VALUE` | the field named `A@ATTR`: `@` is part of a JSON key |
|
||||
|
||||
Records that keep their fields as elements are named by a child's text:
|
||||
Osmo's `<contact><first_name>Delphine</first_name>…` is
|
||||
`[name=contact][>first_name=Delphine]`. A GtkBuilder `<child>` is named by
|
||||
the id its widget carries, `[name=child][>object@id=submit_button]`, and a
|
||||
TreeLine node by a field of its `data`,
|
||||
`[format=BOOK][>data/Title=The Silk Roads]`. Any element on the way will
|
||||
do; a path with more than three steps, or an empty one, is no selector;
|
||||
and a missing step, or a value at its end that is not a string, matches
|
||||
nothing.
|
||||
|
||||
- Conditions can follow one another, `[name=Object][@name=Hole]`, and all must
|
||||
hold. They compare strings only, the selector is escaped like any pointer
|
||||
segment (`~1` for `/`), and a value cannot hold `][`.
|
||||
segment, so a path's `/` is `~1` inside a pointer,
|
||||
`/nodes/[format=BOOK][>data~1Title=The Silk Roads]`, and a `/` in a key
|
||||
cannot be a step; a value cannot hold `][`. A JSON field whose key begins
|
||||
with `@` or `>` is selected through a path, `[>@type=Book]`.
|
||||
|
||||
A selector must name exactly one member. When several match, or none does
|
||||
before the last segment, the check fails and says which selector matched what.
|
||||
@@ -187,7 +640,7 @@ FreeCAD 0.21 and 1.0 alike:
|
||||
```json
|
||||
{
|
||||
"name": "cut-hole",
|
||||
"prompt": "Cut a 10 mm hole through the middle of the plate and save it.",
|
||||
"prompt": "In FreeCAD, cut a 10 mm hole through the middle of the plate and save it.",
|
||||
"checks": [
|
||||
{
|
||||
"id": "cut",
|
||||
@@ -294,6 +747,51 @@ read the element's whole text instead:
|
||||
and trims both ends before comparing, as XPath's `normalize-space()` does,
|
||||
for an app that reflows text or a value written across lines. A no-break
|
||||
space is not whitespace there.
|
||||
- `text_attribute` reads text an app keeps in an attribute: the element's
|
||||
text is then that attribute's values on it and its descendants, joined in
|
||||
document order, and its text nodes are left out. Scribus keeps a text
|
||||
frame's text as `<StoryText><ITEXT CH="Spring "/><ITEXT CH="Fair"/></StoryText>`,
|
||||
one `ITEXT` per run of formatting, so the check below reads `Spring Fair`
|
||||
however the runs are split. The pointer must name an element; a text node
|
||||
or attribute value fails.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "headline",
|
||||
"kind": "text_equals",
|
||||
"file": "Documents/flyer.sla",
|
||||
"pointer": "/root/children/[name=DOCUMENT]/children/[name=PAGEOBJECT][@ANNAME=Headline]",
|
||||
"value": "Spring Fair",
|
||||
"text_attribute": "CH"
|
||||
}
|
||||
```
|
||||
|
||||
## Counting members
|
||||
|
||||
`member_count` counts the members of the array its pointer names: a JSON
|
||||
array, or an XML element's `children`. `matching`, a selector of one or more
|
||||
conditions as [above](#pointers-and-selectors), `[>PATH=VALUE]` included,
|
||||
counts only the members it matches, however many; without it every member
|
||||
counts. An element's children hold its text nodes too, so give `matching`
|
||||
for XML, such as `[name=entry]`. A Tellico task that adds one book to a
|
||||
collection of 12:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "one-more-book",
|
||||
"kind": "member_count",
|
||||
"file": "Documents/books.tc",
|
||||
"pointer": "/entries/[name=tellico.xml]/view/root/children/[name=collection]/children",
|
||||
"matching": "[name=entry]",
|
||||
"equals": 13
|
||||
}
|
||||
```
|
||||
|
||||
It takes exactly one of `equals`, `at_least` and `at_most`. The empty
|
||||
pointer `""` names the whole file, for a JSON file whose top level is an
|
||||
array. A pointer that names no array, an absent file's included, fails and
|
||||
says what it found there. Like the other counts, it is undecided on a view
|
||||
that may hold only part of the array.
|
||||
|
||||
## Validation and export
|
||||
|
||||
@@ -322,7 +820,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.
|
||||
|
||||
@@ -339,7 +840,10 @@ done
|
||||
```
|
||||
|
||||
The agent defaults to Claude Code and the model is the caller's choice (Claude
|
||||
Sonnet 5.5 is a reasonable reference). A run reported as `scored below 1`
|
||||
Sonnet 5.5 is a reasonable reference). The agent calls a model endpoint, and
|
||||
agentenv refuses the run without one: set `LITELLM_BASE_URL` and
|
||||
`LITELLM_API_KEY` where the runs start, or `base_url` and `api_key` under
|
||||
`[model]` in `.agentenv/config.toml`. A run reported as `scored below 1`
|
||||
failed the checks and counts as a miss; one reported as `failed` did not finish,
|
||||
as when the computer or the app could not be reached, and is run again rather
|
||||
than counted. Each run's instance keeps the verifier's results per check under
|
||||
|
||||
+163
-26
@@ -18,13 +18,66 @@ app, exporting its bundle and witnessing the task on such a computer are in
|
||||
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).
|
||||
|
||||
## Set up a build host
|
||||
|
||||
On a Linux host with Node.js and Docker, from a REA
|
||||
[checkout](getting-started/installation.md#run-rea-from-a-checkout):
|
||||
|
||||
```bash
|
||||
rea setup --client claude_code --desktop-build --install-agentenv
|
||||
rea doctor --provider desktop_build --client claude_code
|
||||
```
|
||||
|
||||
Setup shows its plan and asks before it changes anything; `--dry-run` only
|
||||
prints it and `--yes` approves it. It packs REA's runtime archive into
|
||||
`~/.cache/rea/build-computer/rea-<version>.tar.xz` (under `$XDG_CACHE_HOME`
|
||||
when set, `~/Library/Caches` on macOS), and packs again once REA's version
|
||||
changes; an archive `REA_BUILD_COMPUTER_REA_ARCHIVE` already names is
|
||||
recorded instead. It records `REA_AGENT_ENV_COMMAND`, `REA_DOCKER_COMMAND` and
|
||||
`REA_BUILD_COMPUTER_REA_ARCHIVE` as absolute paths in that client's REA
|
||||
registration, keeping a value the registration already has other than an
|
||||
archive setup packed for an earlier REA version, and refreshes the skill.
|
||||
`--install-agentenv` runs `uv tool install agentenv-framework==0.9.1464`
|
||||
when `uv` is on `PATH`, and otherwise prints the command. Setup never
|
||||
installs Docker or Node.js and never runs `sudo`. Restart the client
|
||||
afterwards.
|
||||
|
||||
Doctor is read-only and checks, in order: a Linux amd64 or arm64 host,
|
||||
Node.js, procps `ps`, the Docker CLI, a Docker daemon reachable without
|
||||
`sudo`, 20 GB free where Docker keeps images, agentenv-framework 0.9.1464,
|
||||
the runtime archive of this REA version, the build settings in the
|
||||
registration or the environment, and the skill. Each failure names its fix.
|
||||
It also reports, without counting them against `healthy`, whether a model
|
||||
endpoint for solver runs is configured and which agentenv containers
|
||||
earlier builds left. Pass `--json` for the full report.
|
||||
|
||||
When a setting is unset where the server starts, REA uses `agent-env` and
|
||||
`docker` on `PATH` and the archive setup packed for this REA version. The
|
||||
rest of this page is the same setup by hand.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Docker, and an agentenv-framework install whose `agent-env` program is named
|
||||
by the absolute `REA_AGENT_ENV_COMMAND`. Bundles target agentenv
|
||||
0.9.1431. REA runs its helper, `bridge/agentenv/computer.py`, with that
|
||||
runner's Python: the interpreter on the program's `#!` line, or the
|
||||
`python3` beside it in its virtual environment.
|
||||
- A Linux host on amd64 or arm64 with about 20 GB of free disk for the
|
||||
images agentenv builds and pulls. amd64 and arm64 hosts both build
|
||||
natively; a host builds only its own architecture.
|
||||
- Node.js at the version in `.nvmrc`, installed with
|
||||
[nvm](https://github.com/nvm-sh/nvm) or from
|
||||
[nodejs.org](https://nodejs.org/en/download), and REA
|
||||
[run from a checkout](getting-started/installation.md#run-rea-from-a-checkout).
|
||||
- [Docker Engine](https://docs.docker.com/engine/install/) and its
|
||||
[post-install steps](https://docs.docker.com/engine/install/linux-postinstall/):
|
||||
add yourself to the `docker` group, then log in again.
|
||||
- agentenv-framework 0.9.1464, the version bundles target. Install
|
||||
[uv](https://docs.astral.sh/uv/getting-started/installation/) first, then
|
||||
run `uv tool install agentenv-framework==0.9.1464`. Set
|
||||
`REA_AGENT_ENV_COMMAND` to the absolute path of the resulting `agent-env`
|
||||
program, normally `$HOME/.local/bin/agent-env`; `command -v agent-env`
|
||||
shows the path when its install directory is on your `PATH`. Installing it
|
||||
with pip into a virtual environment instead needs `python3.12-venv` on
|
||||
stock Ubuntu. REA runs its
|
||||
helper, `bridge/agentenv/computer.py`, with that runner's Python: the
|
||||
interpreter on the program's `#!` line, or the `python3` beside it in its
|
||||
virtual environment.
|
||||
- `REA_DOCKER_COMMAND`, the absolute path of the Docker CLI, lets REA remove a
|
||||
computer whose agentenv teardown was not confirmed. Without it, REA names the
|
||||
command to run instead.
|
||||
@@ -34,20 +87,83 @@ skill for doing all of it from a request is
|
||||
checkout, `npm run pack:build-computer-runtime -- /path/to/rea-prod.tar.xz`
|
||||
writes one: `npm pack`, its package folder as
|
||||
`rea-prod` with the lockfile, `npm ci --omit=dev --omit=optional`, then
|
||||
`rea-prod` as `.tar.xz`.
|
||||
`rea-prod` as `.tar.xz`. The archive is a copy of the checkout: pack it
|
||||
again after `git pull` and a rebuild.
|
||||
|
||||
Set these where the MCP server starts; a shell export does not reach a server
|
||||
that is already running.
|
||||
|
||||
## Claude Code
|
||||
|
||||
Without `--desktop-build`, `rea setup --client claude_code` registers REA
|
||||
without these variables. Either
|
||||
export them in the shell that starts `claude`, which starts REA's server with
|
||||
its environment:
|
||||
|
||||
```bash
|
||||
export REA_AGENT_ENV_COMMAND="$HOME/.local/bin/agent-env"
|
||||
export REA_DOCKER_COMMAND="$(command -v docker)"
|
||||
export REA_BUILD_COMPUTER_REA_ARCHIVE="$HOME/rea-runtime/rea-prod.tar.xz"
|
||||
claude
|
||||
```
|
||||
|
||||
or set them, as absolute paths, in the `env` of the `mcpServers.rea` entry
|
||||
setup wrote, such as in `~/.claude.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"rea": {
|
||||
"command": "/absolute/path/to/node",
|
||||
"args": ["/absolute/path/to/rea/scripts/rea.mjs", "mcp"],
|
||||
"env": {
|
||||
"REA_AGENT_ENV_COMMAND": "/home/ada/.local/bin/agent-env",
|
||||
"REA_DOCKER_COMMAND": "/usr/bin/docker",
|
||||
"REA_BUILD_COMPUTER_REA_ARCHIVE": "/home/ada/rea-runtime/rea-prod.tar.xz"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Solver runs are `agent-env run` commands the agent runs in its shell, and
|
||||
agentenv refuses them without a model endpoint: export `LITELLM_BASE_URL` and
|
||||
`LITELLM_API_KEY` in the shell that starts `claude`, whose Bash tool inherits
|
||||
them, or set `base_url` and `api_key` under `[model]` in
|
||||
`.agentenv/config.toml`.
|
||||
|
||||
Claude Code asks before each MCP tool call its permission settings do not
|
||||
allow, and a build makes dozens of `act_on_build_computer` calls. You can
|
||||
allow REA's tools in those settings' `permissions.allow` list:
|
||||
`mcp__rea__act_on_build_computer` allows that tool, and `mcp__rea` allows all
|
||||
of REA's.
|
||||
|
||||
A headless run, `claude -p`, ends when the skill asks its upfront questions,
|
||||
and refuses the tool calls its permission settings do not allow. Put the
|
||||
answers in the request: the install source when the app is not in the Ubuntu
|
||||
archive, a synthetic seed or the file to start from, whether to review the
|
||||
task before solver runs, and the solver runs' count, model and budget, or
|
||||
none:
|
||||
|
||||
```bash
|
||||
claude -p 'Build me a Gnote environment where the agent adds olive oil to the
|
||||
shopping list note. Make a synthetic note. Then make 2 solver runs with
|
||||
<model>, at most $4 in all, without a review first.'
|
||||
```
|
||||
|
||||
## Start a computer
|
||||
|
||||
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. The name is the desktop entry's last part when it
|
||||
is reverse-DNS (`com.github.xournalpp.xournalpp` gives `xournalpp`), or else
|
||||
the whole entry without a trailing version (`glabels-3.0` gives `glabels`).
|
||||
|
||||
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`
|
||||
@@ -71,16 +187,28 @@ Applications menu entry can open the app.
|
||||
|
||||
| `kind` | Installs |
|
||||
| ---------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| `archive` | `package` from the Ubuntu 24.04 archive, on amd64 and arm64 |
|
||||
| `archive` | `package` from the Ubuntu 24.04 archive, on amd64 and arm64, with its optional `extra_packages` beside it |
|
||||
| `apt_repository` | `package` from the repository at `uri` with `suite` and `components`, trusting the key file `key_file` |
|
||||
| `package_file` | The `.deb` at `url`, checked against `sha256`, for one `architecture`, after its apt `dependencies` are in |
|
||||
|
||||
Build steps run with the network off, so a `.deb`'s dependencies must be
|
||||
listed. The bundle adds REA in a build-only layer: Node.js
|
||||
listed. `extra_packages` names up to 16 more archive packages, by the same
|
||||
name rules as `package`, for a runtime piece the app needs that its package
|
||||
does not install: apt here skips Recommends, so MyPaint 2.0.1 exits at launch
|
||||
without `librsvg2-common`, GTK's SVG icon loader, and Freeplane 1.7.10 needs
|
||||
`openjdk-17-jre`, since its launcher refuses noble's default Java 21. The
|
||||
export installs them beside the app too, as it does a `.deb`'s
|
||||
`dependencies` when apt offers the `.deb`'s package; see
|
||||
[build and witness](desktop-build-witness.md).
|
||||
|
||||
The bundle adds REA in a build-only layer: Node.js
|
||||
24.22.1, downloaded per architecture and checked against its release checksum,
|
||||
and REA from `REA_BUILD_COMPUTER_REA_ARCHIVE`, both unpacked into `/opt/rea` by
|
||||
a root build step, with `node` and `rea` on `PATH`. An exported bundle carries
|
||||
none of it.
|
||||
a root build step, with `node` and `rea` on `PATH`. It also installs
|
||||
`libgtk-3-bin`, for `gtk-launch`, and `dconf-cli`, so the capture reads the
|
||||
app's settings in dconf, such as GnuCash's "Show tips at startup", and the
|
||||
seed keeps them. An exported bundle carries none of it but `dconf-cli`, which
|
||||
it installs when it loads the app's dconf keys.
|
||||
|
||||
From a bundle folder, such as one `export-desktop-application` wrote, REA
|
||||
starts that bundle's `tasks/smoke.json` as it is:
|
||||
@@ -96,6 +224,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
|
||||
@@ -105,9 +237,12 @@ while it is one colour throughout. The retries share 10 s, each given only
|
||||
what is left of it, and when that runs out REA returns the latest frame;
|
||||
progress notifications continue meanwhile. Given `screenshot` with a
|
||||
`region`, `format` or `quality`, REA then takes one with them, a `region`
|
||||
cropping that frame. The result holds
|
||||
cropping that frame rather than capturing the screen again. The result holds
|
||||
`computer_id`, agentenv's `sandbox_id`, the environment name or bundle folder,
|
||||
and the screenshot's frame as structured content beside its image.
|
||||
`extra_packages`, what the request named beside the app for the export to
|
||||
install too (an archive install's `extra_packages` or a `.deb`'s
|
||||
`dependencies`, empty otherwise), and the screenshot's frame as structured
|
||||
content beside its image.
|
||||
|
||||
A failed start returns the last 16 KiB of the helper's stderr, where a failing
|
||||
build prints its error, and its exit status; a cancelled one stops the helper,
|
||||
@@ -121,16 +256,16 @@ progress and waits for them before closing every computer.
|
||||
`act_on_build_computer` takes `computer_id`, an `action` and the driver's own
|
||||
arguments for `computer_<action>`, which REA passes through:
|
||||
|
||||
| `action` | Arguments |
|
||||
| ------------ | --------------------------------------------------------------- |
|
||||
| `screenshot` | `region`, `format` (`png` or `jpeg`), `quality` |
|
||||
| `click` | `x`, `y`, `button`, `count` (2 double-clicks), `modifiers` |
|
||||
| `drag` | `path` of `[x, y]` points, `button`, `duration_ms`, `modifiers` |
|
||||
| `scroll` | `direction`, `x`, `y`, `amount`, `modifiers` |
|
||||
| `type` | `text`, where `\n` presses Enter and `\t` Tab |
|
||||
| `key` | `keys`, one chord pressed in order, and `repeat` |
|
||||
| `wait` | `ms` |
|
||||
| `reset` | `screenshot` |
|
||||
| `action` | Arguments |
|
||||
| ------------ | ----------------------------------------------------------------------- |
|
||||
| `screenshot` | `region`, `format` (`png` or `jpeg`), `quality` |
|
||||
| `click` | `x`, `y`, `button`, `count` (2 double-clicks), `modifiers` |
|
||||
| `drag` | `path` of 2 to 50 `[x, y]` points, `button`, `duration_ms`, `modifiers` |
|
||||
| `scroll` | `direction`, `x`, `y`, `amount`, `modifiers` |
|
||||
| `type` | `text`, where `\n` presses Enter and `\t` Tab |
|
||||
| `key` | `keys`, one chord pressed in order, and `repeat` |
|
||||
| `wait` | `ms` |
|
||||
| `reset` | `screenshot` |
|
||||
|
||||
`reset` is not a driver tool: REA calls the app's `data/reset`, which restores
|
||||
the bundle's seed and relaunches the app, then waits until the computer's
|
||||
@@ -154,7 +289,9 @@ The result carries the driver's content unchanged, its text and images, after
|
||||
REA's own JSON: `action_index` and the driver's structured result. A refusal,
|
||||
such as a stale frame, is an error carrying the computer's message. A response
|
||||
larger than the MCP budget is refused with how to ask for a smaller image: a
|
||||
`region`, or `jpeg` with a lower `quality`. That error keeps REA's own result,
|
||||
`region`, or `jpeg` with a lower `quality`. A screenshot with `region` does not
|
||||
capture the screen again; it crops the latest frame, so take a full
|
||||
screenshot, or a `wait` with `screenshot: true`, first. That error keeps REA's own result,
|
||||
`computer_id` included, as `details.result`, since the action or start has
|
||||
happened.
|
||||
|
||||
|
||||
+137
-27
@@ -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 |
|
||||
@@ -41,6 +41,34 @@ See [desktop builds](https://github.com/morluto/rea/blob/main/.agents/skills/rev
|
||||
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`.
|
||||
@@ -48,37 +76,96 @@ See [desktop builds](https://github.com/morluto/rea/blob/main/.agents/skills/rev
|
||||
`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.
|
||||
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.
|
||||
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: like siblings' fields, each line kept beside new text, and
|
||||
the count of a list whose members were only edited. 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, is `unreadable_changes`, not an empty key list);
|
||||
`unreadable_changes` when a dconf database changed but REA could not read
|
||||
it, such as without `dconf-cli` or when a present version's bytes were
|
||||
not retained, 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`, `unreadable_view`,
|
||||
`volatile_lines`, `generated_reference` or `read_as_text`.
|
||||
6. Write the task: its name, the prompt in the user's own words naming the
|
||||
app (a solving agent's own shell cannot see the computer's files, and the
|
||||
export's limitations say when a prompt names neither the app's title,
|
||||
environment nor package), and checks
|
||||
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. 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`. 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>#`, GnuCash's
|
||||
`<book>.LCK` or Grisbi's `.<file>.lock` beside its file, are left out of
|
||||
the seed, since a copied one can keep the app from starting or saving. The
|
||||
limitations and 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`, and app
|
||||
logs that are not locks are seeded. The limitations 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
|
||||
through `data/get`, since a large bundle's list outgrows a command's
|
||||
output; it then brings the files back through the driver's
|
||||
`data/get` in answers of at most 8 MiB, and checks and writes each answer
|
||||
into the folder before asking for the next, so one answer at a time is
|
||||
held; a failure leaves no partial folder.
|
||||
the request's URL with `--package-url`; one apt offers installs from apt.
|
||||
Either way the request's `dependencies` reach the export as
|
||||
`--extra-package`, as an archive request's `extra_packages` do, so a
|
||||
runtime piece the agent named, such as MyPaint's `librsvg2-common`, is
|
||||
installed beside the app; the limitations and the README list them,
|
||||
except the app itself and dependencies the bundle already names for a
|
||||
`.deb` it installs from the file. REA lists the bundle's files
|
||||
with their sizes and SHA-256 in the computer, into a file beside the
|
||||
bundle that it reads through `data/get`, since a large bundle's list
|
||||
outgrows a command's output; it then brings the files back through the
|
||||
driver's `data/get` in answers of at most 8 MiB, and checks and writes
|
||||
each answer into the folder before asking for the next, so one answer at
|
||||
a time is held; a failure leaves no partial folder.
|
||||
8. `close_build_computer`.
|
||||
|
||||
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 an app window's title has named so far
|
||||
come first, as a document saved and no longer held open is in Gnumeric, LyX
|
||||
or Tiled; then files named themselves in `state_paths`; then those the app
|
||||
holds open, those under a selected folder and those in its state
|
||||
directories; then the rest; and caches and WebKit, Chromium or QtWebEngine
|
||||
storage last, even under a selected folder such as `.config/libreoffice`
|
||||
with its icon cache, 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:
|
||||
|
||||
@@ -102,7 +189,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
|
||||
@@ -116,7 +205,11 @@ cancels the call in progress on it and refuses the calls still waiting.
|
||||
|
||||
Start a fresh computer from the exported folder with `start_build_computer`
|
||||
and `{"kind": "bundle", "path": ...}`; agentenv boots the app with the seed,
|
||||
on the seed's document when the export opens one.
|
||||
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 |
|
||||
@@ -129,13 +222,29 @@ 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. Once the files settle it runs the task's
|
||||
[readers](desktop-application-tasks.md#readers) in the computer through
|
||||
`computer-exec/v1`, as the verifier does, and a check through a reader reads
|
||||
that reader's view. A task of [screen judges](desktop-application-tasks.md#screen-judges)
|
||||
reads no files: REA takes a screenshot and runs the bundle's own judge on it
|
||||
with the agentenv runner's Python and model endpoint. 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
|
||||
recording under the same id, which the computer answers with the recording
|
||||
it already began. The stages come in order. The edit and the near miss each
|
||||
need an applied click, drag, scroll, type or key since the stage before, with
|
||||
need an applied click, drag, scroll, type, typed secret or key since the stage before, with
|
||||
no reset after the last of them, since a reset puts the seed back rather than
|
||||
changing the app; `after_reset` needs the reset as the last change, and a
|
||||
reset that leaves any check unlike on the seed fails the witness, its
|
||||
@@ -171,13 +280,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
|
||||
|
||||
@@ -181,7 +181,8 @@ When choosing the manual path, leave the automatic main release PR unmerged.
|
||||
Select the application commit from main, create the frozen branch, and prepare
|
||||
its own release PR using the steps below. Merging the main release PR starts
|
||||
automatic publication instead. Close the superseded main PR after the manual
|
||||
release has published and its metadata has been synchronized back to main.
|
||||
release has published, before merging the metadata synchronization PR back
|
||||
to main.
|
||||
|
||||
`release/VERSION` also sets the expected version for the workflow. Use an exact
|
||||
SemVer such as `release/6.1.0` or `release/6.1.0-rc.1`, without build metadata.
|
||||
|
||||
+16
-10
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -182,7 +166,7 @@ does not establish another instance.
|
||||
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`.
|
||||
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
|
||||
@@ -348,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
|
||||
@@ -373,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,
|
||||
|
||||
+17
-1
@@ -44,6 +44,22 @@ 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.
|
||||
|
||||
For Android `NT_ANDROID_TYPE_IDENT` (`.note.android.ident`, owner `Android`,
|
||||
type `1`) notes, `android.android_api` is decoded from both legacy 4-byte
|
||||
descriptors (where `ndk_version` and `ndk_build_number` remain null) and modern
|
||||
132-byte or extended NDK descriptors, which also populate `android.ndk_version`
|
||||
and `ndk_build_number` when their 64-byte slots hold NUL-padded
|
||||
printable ASCII. Truncated or non-ASCII Android descriptors degrade `android`
|
||||
to null while preserving the raw descriptor digest and preview, and other
|
||||
owners keep `android` null.
|
||||
|
||||
`PT_NOTE` and `SHT_NOTE` are examined independently. The same file range may
|
||||
appear twice when both tables declare it.
|
||||
|
||||
@@ -54,7 +70,7 @@ the image never carried notes in another container or overlay.
|
||||
|
||||
The selected file is limited to 64 MiB by default (512 MiB maximum). At most
|
||||
32 note entries are examined by default across every table. Retained note
|
||||
names, section names, GNU descriptor text, and core dump string representations share a scan budget based on
|
||||
names, section names, GNU descriptor text, core dump string representations, and Android ident strings share a scan budget based on
|
||||
the source bytes plus any decoded section-name table, capped at
|
||||
`max_file_bytes`. The raw source and decoded table must also fit together
|
||||
within that ceiling. If admission fails, the error reports the required
|
||||
|
||||
+7
-5
@@ -22,9 +22,10 @@ use the current projection identity; there is no pre-coverage FIT summary varian
|
||||
A FIT is a flattened devicetree (FDT v16 or v17) with a top-level `/images`
|
||||
node. Recognition walks the structure block within the first 4 KiB of the file
|
||||
only; the file name does not matter. A devicetree whose `/images` node begins
|
||||
after 4 KiB, a devicetree without `/images`, and any other FDT version stay on
|
||||
the plain devicetree route: `open_binary` refuses them and
|
||||
[`inspect_devicetree`](devicetree.md) still parses them. A U-Boot control DTB
|
||||
after 4 KiB or a devicetree without `/images` stays on the plain devicetree
|
||||
route: `open_binary` refuses it and [`inspect_devicetree`](devicetree.md)
|
||||
can parse it when its FDT version is 16 or 17. Other FDT versions are not
|
||||
recognized as FIT and are also unsupported by `inspect_devicetree`. A U-Boot control DTB
|
||||
that contains `/images` is treated as a FIT. The container format is `fit`.
|
||||
|
||||
Recognition is a probe. The complete devicetree parse decides, so a file whose
|
||||
@@ -124,8 +125,9 @@ Failures apply to the whole file and return no partial inventory.
|
||||
|
||||
The devicetree, including any embedded image data, must be at most 16 MiB; a
|
||||
larger `totalsize` fails as a memory limit. Store large images externally
|
||||
(`mkimage -E`): external data of any size is streamed from the file and never
|
||||
loaded into memory. A FIT may declare at most 1,024 images and 1,024
|
||||
(`mkimage -E`): external image bytes are streamed from the file within their declared
|
||||
32-bit sizes and the resource bounds below, without loading the whole image
|
||||
into memory. A FIT may declare at most 1,024 images and 1,024
|
||||
configurations, and an image at most 8 hash nodes; the devicetree parser's
|
||||
node, property and depth bounds also apply. The sum of declared image sizes
|
||||
is bounded by the shared archive expansion budget. These are fixed resource
|
||||
|
||||
+98
-65
@@ -439,6 +439,19 @@ 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).
|
||||
|
||||
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:
|
||||
|
||||
```bash
|
||||
@@ -449,6 +462,32 @@ 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).
|
||||
|
||||
List ELF and Mach-O initializer and finalizer functions without executing the
|
||||
image:
|
||||
|
||||
```bash
|
||||
rea inspect-native-initializers /absolute/path/to/program --json
|
||||
```
|
||||
|
||||
The workflow reports `DT_INIT`, init/fini arrays, legacy `.ctors`/`.dtors`, and
|
||||
Mach-O `__mod_init_func`, `__init_offsets` and `__mod_term_func` entries with
|
||||
their resolved targets. Universal Mach-O files need `--architecture`. See
|
||||
[ELF and Mach-O initializer functions](../guides/native/native-initializers.md).
|
||||
|
||||
Inspect ELF unwind function ranges without executing the image:
|
||||
|
||||
```bash
|
||||
rea inspect-elf-unwind-ranges /absolute/path/to/program --json
|
||||
```
|
||||
|
||||
The workflow reports FDE start, end, and size, the containing section, an exact
|
||||
symbol name when one exists, CIE identity, LSDA, and personality. Coverage
|
||||
counts ranges that match a symbol, ranges without a symbol, and whether the
|
||||
`.eh_frame_hdr` search table agrees with the decoded FDEs. `.debug_frame` is
|
||||
reported present, absent, or incomplete and is not decoded. A missing unwind table is
|
||||
observed absence of those declarations. See
|
||||
[ELF unwind function ranges](../guides/native/elf-unwind-ranges.md).
|
||||
|
||||
Inspect an Apple `.ips` crash report without executing a target:
|
||||
|
||||
```bash
|
||||
@@ -476,6 +515,22 @@ applicable. gzip, xz, and zstd containers are unsupported and name
|
||||
utility, then inspect the decompressed file. See
|
||||
[Linux kernel modules](../kernel-modules.md).
|
||||
|
||||
Read a Linux kernel image's version banner and embedded `CONFIG_IKCONFIG`
|
||||
build config without executing it:
|
||||
|
||||
```bash
|
||||
rea inspect-kernel-build-config /absolute/path/to/vmlinux --json
|
||||
rea inspect-kernel-build-config /absolute/path/to/bzImage --name CONFIG_MODULE_SIG --json
|
||||
```
|
||||
|
||||
The workflow reports the banner version, builder, and compiler, the config
|
||||
option count, and paged `CONFIG_*` entries (`y`, `m`, strings, numbers, and
|
||||
`not_set`). An `IKCFG_ST` string counts as a config only when a valid gzip
|
||||
member follows it and `IKCFG_ED` follows that member. A gzip bzImage payload
|
||||
is inflated and searched; other payload codecs are unsupported and name
|
||||
`external_decompression` as the next probe. See
|
||||
[Linux kernel build config](../guides/native/kernel-build-config.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)
|
||||
without executing bytecode or installing Python:
|
||||
@@ -596,10 +651,11 @@ be verified. See [MCP contracts](../reference/mcp-contracts.md) for session life
|
||||
[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 +684,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.
|
||||
@@ -1139,6 +1193,23 @@ of the serve command's stopped document. See
|
||||
[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> ...]`
|
||||
@@ -1330,62 +1401,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
|
||||
@@ -1461,3 +1487,10 @@ 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.
|
||||
|
||||
Deno compile executables use the same commands to inventory and materialize the
|
||||
embedded virtual filesystem, remote modules, and recorded options. Inventory retains
|
||||
embedded environment-file values and certificate bytes in local Evidence with their
|
||||
counts and byte lengths, and extraction does not write them as files. The npm snapshot
|
||||
length is reported and not decoded, and the executable is not run. See
|
||||
[Deno compile executables](../deno-standalone.md).
|
||||
@@ -7,6 +7,7 @@ Setup previews configuration changes and asks for approval before applying them.
|
||||
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| 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) |
|
||||
| Run unreleased code | [Run REA from a checkout](#run-rea-from-a-checkout) |
|
||||
| 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) |
|
||||
@@ -384,14 +385,22 @@ Select the part you want to check:
|
||||
| One analysis engine | `rea doctor --provider ghidra --json` (or `hopper`, `ida`, `jadx`, `kuna`) |
|
||||
| One agent registration | `rea doctor --client codex --json` (see [client IDs](#supported-agents)) |
|
||||
| Installed workflow instructions | `rea doctor --skill --json` |
|
||||
| Desktop app environment builds | `rea doctor --provider desktop_build --client claude_code --json` |
|
||||
|
||||
A scoped report has `scope.mode: "explicit"`. Its `scope_checks` determine
|
||||
`healthy` and the exit status. Other checks appear in `informational_checks`;
|
||||
`environment_healthy` summarizes the full audit. `--target` adds a target check,
|
||||
but the report remains audit-wide unless a scope option is also supplied.
|
||||
|
||||
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
|
||||
@@ -595,6 +604,36 @@ feature selection. The same package version string in a development checkout
|
||||
does not establish that its bytes match the npm tarball. Update a registration
|
||||
through a reviewed, scoped setup plan, then restart/reconnect the agent.
|
||||
|
||||
### Run REA from a checkout
|
||||
|
||||
To run code that is not released yet, build a checkout with the Node.js
|
||||
version in `.nvmrc`:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/morluto/rea.git
|
||||
cd rea
|
||||
npm ci
|
||||
npm run build:cached
|
||||
```
|
||||
|
||||
Then run `npm link` once in the checkout to put its `rea` on your `PATH`, or,
|
||||
wherever these docs say `rea …`, run
|
||||
`node /absolute/path/to/rea/scripts/rea.mjs …`. Setup run this way registers
|
||||
the checkout's `scripts/rea.mjs` with your agents.
|
||||
|
||||
After `git pull`, run `npm ci` and `npm run build:cached` again. If the
|
||||
checkout's skill changed, refresh each installed copy before restarting its
|
||||
agent. For example, preview and review the Claude Code skill changes:
|
||||
|
||||
```bash
|
||||
rea setup --skill-client claude_code --dry-run --json
|
||||
```
|
||||
|
||||
Then apply the reviewed changes with `rea setup --skill-client claude_code --yes --json`.
|
||||
Substitute the relevant skill client; use the checkout's
|
||||
`node /absolute/path/to/rea/scripts/rea.mjs` form if `rea` is not linked. For desktop builds, also pack the [build computer's runtime
|
||||
archive](../desktop-build-computer.md#requirements) again.
|
||||
|
||||
## Skill-only installation
|
||||
|
||||
```bash
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# GameCube DOL analysis through Ghidra
|
||||
|
||||
This lane imports 32-bit big-endian PowerPC GameCube/Wii DOL images through
|
||||
Ghidra. It does not execute the image. DOL is a headerless format with no magic
|
||||
Ghidra. It does not execute the image. DOL has a section and entry-point header but no magic
|
||||
number, so REA never detects it: the caller must select it explicitly.
|
||||
|
||||
Only the cached MEM1 window `0x80000000..0x81800000` is admitted. Wii MEM2
|
||||
@@ -29,7 +29,7 @@ MCP, with the existing `open_binary` tool:
|
||||
}
|
||||
```
|
||||
|
||||
The architecture comes from the DOL header (`powerpc`). Do not pass
|
||||
Selecting the DOL format supplies the architecture (`powerpc`). Do not pass
|
||||
`architecture` with `gamecube-dol`; it is rejected. `entry_point` is optional,
|
||||
and if given it must equal the header entry.
|
||||
|
||||
|
||||
@@ -113,8 +113,8 @@ existing analysis families directly, for example
|
||||
| `push_adb_file` | **mutates device** | One local file to a device path (e.g. pushing tools into `/data/local/tmp`); checks for existing targets and refuses them without explicit overwrite (the check is not atomic); compares digests when device `sha256sum` is available |
|
||||
| `install_adb_package` | **mutates device** | Local APK via `adb install [-r]`; preserves its Success/Failure verdict, records `replace_requested`, and leaves actual replacement `null` because prior package state is not observed |
|
||||
| `uninstall_adb_package` | **mutates device** | Requests package removal for user 0 via `adb shell pm uninstall --user 0`, without data retention |
|
||||
| `start_adb_app` | **mutates device** | Resolves the package's launcher activity (`cmd package resolve-activity --brief`) and starts it (`am start -n`) |
|
||||
| `start_adb_activity` | **mutates device** | Starts an intent (`am start -a` with optional URI, component, and up to 16 typed extras); preserves the activity manager's verdict |
|
||||
| `start_adb_app` | **mutates device** | Resolves the package's launcher activity (`cmd package resolve-activity --brief`) and starts it (`am start -W -n`) |
|
||||
| `start_adb_activity` | **mutates device** | Starts an intent (`am start -W -a` with optional URI, component, and up to 16 typed extras); preserves the activity manager's verdict |
|
||||
| `stop_adb_app` | **mutates device** | Force-stops every process of a package, ending a dynamic-analysis run |
|
||||
|
||||
Screen capture validates the PNG signature, IHDR framing, dimensions, and IHDR
|
||||
@@ -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.
|
||||
|
||||
@@ -545,7 +545,8 @@ and each upstream request and reply collected before the failure. Failed replies
|
||||
remain available even when their payload cannot be interpreted. Cancellation
|
||||
also stops target hashing before provider admission.
|
||||
|
||||
These operations do not execute the APK or provide split APK/AAB handling,
|
||||
The JADX package, class, method and reference operations do not execute the APK
|
||||
or provide split APK/AAB handling,
|
||||
signature validation, full resource-table semantics, native-library analysis or
|
||||
Android runtime capture. An `.aab` suffix is a ZIP archive, not an APK, so
|
||||
Android tools and the application graph do not treat it as a standalone APK.
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -223,6 +226,12 @@ registrations/removals and dispatch, Node timers and cancellation handles, async
|
||||
`node:child_process` creation and ownership, configuration sources and direct
|
||||
defaults, request construction and response consumers, parse/coercion/
|
||||
validation boundaries, and built-in resource acquisition/release.
|
||||
For `fs/promises.open`, a binding receiving the Promise is distinct from one
|
||||
receiving the awaited FileHandle. Awaiting the Promise later does not replace
|
||||
the original binding, but `h = await h` can replace it with the FileHandle.
|
||||
Receiver writes can therefore retain a candidate release and its ownership
|
||||
ambiguity; a still-known Promise has no direct FileHandle release. Acquisitions
|
||||
remain retained, and unknown loader authority keeps its existing candidate tag.
|
||||
Reassignments connect retained right-hand reads to the binding or property
|
||||
write. Compound assignments also retain the previous-value input; logical
|
||||
assignments keep conditional inputs as candidates. These edges describe
|
||||
|
||||
@@ -22,7 +22,9 @@ rea analyze-javascript-application /absolute/path/to/apps/app.asar \
|
||||
|
||||
Generic `rea analyze` selects this static provider for directories and `.asar`
|
||||
paths when neither `--provider` nor `--snapshot` is supplied. The dedicated
|
||||
command and the generic route return their complete results inline. Native
|
||||
command and the generic route return complete results inline by default.
|
||||
Summary and route-view delivery export the full Evidence to `--evidence_output`
|
||||
and return a projection; see [route delivery](../../javascript-route-inventory.md). Native
|
||||
targets, single JavaScript files, `.app` bundles, and explicit deep-provider or
|
||||
snapshot requests retain the native deep-analysis route.
|
||||
|
||||
@@ -86,6 +88,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:
|
||||
|
||||
@@ -181,7 +188,9 @@ coverage, limitations, and `normalized_result.parent_evidence_id`. Pass that ID
|
||||
to `inspect_analysis_view` for module pages or items, or to the application
|
||||
workflows as a retained reference. The summary does not repeat or truncate the
|
||||
analysis; a server without session retention refuses summary detail with
|
||||
`capability_unavailable`. CLI output is unchanged and always complete.
|
||||
`capability_unavailable`. On the CLI, `--detail summary --evidence_output PATH`
|
||||
exports the full Evidence and returns its summary; the default remains complete
|
||||
inline delivery.
|
||||
|
||||
With a connected MCP `client` and the caller-selected absolute `inputPath`, this
|
||||
recipe analyzes once and pages module identities using the returned ID:
|
||||
@@ -323,6 +332,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 +530,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
|
||||
|
||||
@@ -141,7 +141,7 @@ variants of one file remain separate observations. Older Evidence may omit
|
||||
|
||||
## Node and Electron roles
|
||||
|
||||
The caller declares one role: `node`, `electron-main`, `electron-preload`, or
|
||||
The caller may declare one role: `node`, `electron-main`, `electron-preload`, or
|
||||
`electron-renderer`. Node and Electron-main declarations require a protocol
|
||||
target of type `node`; preload and renderer declarations require `page`.
|
||||
Inspector does not authenticate the operating-system PID or distinguish an
|
||||
|
||||
@@ -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 produces completed inspection
|
||||
Evidence; the stable-read partial observation described above is retained when available.
|
||||
|
||||
`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.
|
||||
@@ -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
|
||||
@@ -654,7 +650,8 @@ unchanged signature. Comparison retains exact byte-based pairs for malformed
|
||||
signatures, including empty, truncated, or invalid headers, but reports them as
|
||||
unknown with a `signature-malformed` limitation when no change is observed.
|
||||
This applies to historical Evidence without signature-resolution attestation as
|
||||
well. Runtime-provided methods are counted separately in
|
||||
well. Runtime-provided methods have the Runtime code type or the InternalCall
|
||||
implementation flag, as core library FCalls do. They are counted separately in
|
||||
`native_implementations.runtime_provided`; they have no file-backed native body
|
||||
for this workflow to map and do not increase `native_body_unresolved`. Historical
|
||||
verification Evidence without this separate count leaves it unknown (`null`).
|
||||
|
||||
@@ -134,9 +134,10 @@ retained, and the effective values are returned in the result limitations. Virtu
|
||||
Unicorn needs a large virtual map. Limits fail with no partial success, and
|
||||
owned process/root cleanup completes independently of cancellation.
|
||||
|
||||
Core files, GDB session/state/control, optional pwndbg enrichment and instruction
|
||||
inspection are separate increments tracked by #969. This increment makes no
|
||||
real support claim for those features or other operating systems/architectures.
|
||||
For core files and optional pwndbg mapping context, use the
|
||||
[recorded-crash workflow](recorded-crashes.md). The binary-layout operations
|
||||
described here do not provide debugger session state or control, or establish
|
||||
support for other operating systems/architectures.
|
||||
|
||||
Typed decoder failures retain bounded `captured_output` (stdout, stderr and an
|
||||
explicit truncation flag) alongside the original failure category and reason.
|
||||
@@ -272,6 +273,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.
|
||||
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
# ELF unwind function ranges
|
||||
|
||||
`inspect_elf_unwind_ranges` / `inspect-elf-unwind-ranges` reads `.eh_frame`
|
||||
and `.eh_frame_hdr` from one selected local ELF32/ELF64 image and lists the
|
||||
function ranges those tables name. It reads the file without executing it and
|
||||
does not require a disassembler.
|
||||
|
||||
```bash
|
||||
rea inspect-elf-unwind-ranges /absolute/path/to/program --json
|
||||
```
|
||||
|
||||
The CLI resolves relative paths against the caller's working directory. MCP
|
||||
requires an absolute filesystem path and preserves that exact selection:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inspect_elf_unwind_ranges",
|
||||
"arguments": { "path": "/artifacts/program" }
|
||||
}
|
||||
```
|
||||
|
||||
Pass `--offset` and `--limit` (MCP `offset` and `limit`) to page the ranges.
|
||||
The default page starts at 0 and returns at most 256 ranges.
|
||||
|
||||
## Observations
|
||||
|
||||
The inline Evidence result contains the artifact path, SHA-256, and byte
|
||||
length, plus ELF class, byte order, machine, and object type.
|
||||
|
||||
`eh_frame.status` is `present`, `absent`, `incomplete`, or `unknown`. A
|
||||
present table names its source: `section` when section headers name
|
||||
`.eh_frame`, or `program` when section headers are missing and
|
||||
`PT_GNU_EH_FRAME` supplies the bytes. `location` is the file range that was
|
||||
examined. A `.eh_frame` section that is `SHT_NOBITS` or lies outside the file
|
||||
is `incomplete` with a null `location`. One that runs past the end of the
|
||||
file is `incomplete`, `location` is clamped to its in-file bytes, and the
|
||||
records in those bytes are still decoded. Only the first `.eh_frame` and
|
||||
`.eh_frame_hdr` section is decoded, and only the first `PT_GNU_EH_FRAME`
|
||||
program header. A duplicate section, or a duplicate `PT_GNU_EH_FRAME` when no
|
||||
`.eh_frame_hdr` section supplies the header, keeps `coverage.status` at
|
||||
`incomplete`.
|
||||
|
||||
`eh_frame_hdr` reports version, the three pointer encodings, the `.eh_frame`
|
||||
pointer, the declared FDE count, and how many binary-search table entries
|
||||
were decoded. A header section that is `SHT_NOBITS` or extends past the end of
|
||||
the file is `incomplete` with a null `location` and is not decoded.
|
||||
`coverage.eh_frame_hdr_agreement` is `agree` when the table has exactly one
|
||||
row per decoded FDE, the sorted starts match including repeats, and each row
|
||||
points at a distinct FDE with that start. It is `disagree` otherwise, and
|
||||
`unavailable` when the header is absent, unknown, or incomplete. Disagreement
|
||||
is a limitation. The decoded FDEs stay in the result. The search table is
|
||||
read for at most `max_ranges` rows, and for no more rows than the header bytes
|
||||
can hold. When the declared FDE count is larger than either bound, the header
|
||||
is `incomplete`, `table_entries` counts only the rows read, the comparison is
|
||||
`unavailable`, and a limitation names the cap. A declared count that does not fit
|
||||
in 32 bits is not decoded: `fde_count` is null, the header is `incomplete`,
|
||||
and the decoded FDEs stay in the result. A header whose FDE count encoding is
|
||||
`DW_EH_PE_omit` (`0xff`), as GNU ld writes when it cannot build the search
|
||||
table, is `present` with a null `fde_count`, no table rows, and comparison
|
||||
`unavailable`; it does not make coverage incomplete. A header that declares
|
||||
an FDE count but writes `DW_EH_PE_omit` as its table encoding is `present`
|
||||
with that count, no table rows, and comparison `unavailable`, and also keeps
|
||||
coverage complete. A non-zero FDE count under an indirect encoding is the
|
||||
address of a slot that is not followed, so `fde_count` is null, the header is
|
||||
`incomplete`, and the table is not read.
|
||||
|
||||
When section headers name both `.eh_frame_hdr` and `PT_GNU_EH_FRAME`, the
|
||||
section is decoded. A limitation names the segment as ignored only when it
|
||||
declares different bytes than the section. When no `.eh_frame_hdr` section is
|
||||
named, the header is read from `PT_GNU_EH_FRAME` even if a `.eh_frame`
|
||||
section is present.
|
||||
|
||||
A record whose length word is `0xffffffff` uses the 64-bit extended length
|
||||
that follows it. In `.eh_frame` the CIE ID and CIE pointer after that length
|
||||
stay 4 bytes wide.
|
||||
|
||||
`DW_EH_PE_datarel` fields in `.eh_frame_hdr` are relative to the header
|
||||
address. In `.eh_frame` they are relative to the GOT: `DT_PLTGOT` when the
|
||||
dynamic table names it, otherwise the `.got.plt` or `.got` section address.
|
||||
A limitation names the base that was used. When no GOT base is declared,
|
||||
those values are unresolved: the affected record is not reported and
|
||||
`coverage.status` is `incomplete`.
|
||||
|
||||
`debug_frame.status` is `present`, `absent`, `incomplete`, or `unknown`. It
|
||||
is `unknown` when the image has no section headers or unreadable section
|
||||
names. It is `incomplete`, with a null `location` and `coverage.status` at
|
||||
`incomplete`, when the section is `SHT_NOBITS` or its bytes are not all in
|
||||
the file. The `.eh_frame` results stay in the report. This command does not
|
||||
decode `.debug_frame`.
|
||||
|
||||
`cies` lists the CIEs that the returned page's ranges name, in index order,
|
||||
so its length never exceeds the page size. Each `cie_index` in `ranges`
|
||||
matches the `index` of one entry in `cies`. `coverage.total_cies` counts every
|
||||
decoded CIE, including CIEs no FDE on this page uses. Each CIE reports
|
||||
version 1 or 3, augmentation, code and data alignment,
|
||||
return-address register, pointer encoding, LSDA encoding, personality address
|
||||
when the augmentation carries one, signal-frame and B-key flags, and the byte
|
||||
length of the CFA program. CFA instructions are counted and not evaluated.
|
||||
A CIE whose augmentation has a letter other than `z`, `L`, `P`, `R`, `S`, or
|
||||
`B` is not decoded: the encodings of later letters cannot be trusted, so its
|
||||
FDEs are not decoded either. A limitation counts those FDEs and coverage is
|
||||
`incomplete`.
|
||||
|
||||
`ranges` is one page of FDEs. Each range has `start`, `end`, decimal `size`,
|
||||
the containing `SHF_ALLOC` section, an exact symbol name when a symbol starts
|
||||
at that address, the CIE index, LSDA, and personality. A function symbol is
|
||||
preferred, then an `STT_GNU_IFUNC` symbol, then an untyped one. An IFUNC name
|
||||
is the resolver that starts at that address, not the implementation it
|
||||
selects at run time, and a limitation says so. Symbol names, section names,
|
||||
and augmentation strings are target-derived and untrusted. Indirect EH
|
||||
pointers are not dereferenced. An FDE whose initial location is indirect names
|
||||
a pointer slot, not its function, so it is not reported as a range; a
|
||||
limitation counts those FDEs and coverage is `incomplete`. An indirect
|
||||
`eh_frame_ptr` does not locate `.eh_frame`, and the header is `incomplete`.
|
||||
A search table with an indirect encoding is not read: the header is
|
||||
`incomplete`, the comparison is `unavailable`, and the table does not bound a
|
||||
header-located `.eh_frame`.
|
||||
|
||||
An encoded pointer whose stored value is zero is a null pointer, as libgcc
|
||||
reads it: no PC-relative, text, data, or function base is added and an
|
||||
indirect pointer is not followed. A resolved address, and an FDE `end`,
|
||||
wraps at the ELF address width (32 or 64 bits), as libgcc's pointer
|
||||
arithmetic does. A zero LSDA pointer is reported as a null
|
||||
`lsda`, even when the CIE declares an LSDA encoding. An FDE whose initial
|
||||
location is zero marks a function the linker discarded. It is not reported
|
||||
as a range, `examined_records` still counts it, and a limitation counts how
|
||||
many were skipped. In a relocatable object an unrelocated initial location
|
||||
is also zero, so those FDEs are skipped too.
|
||||
|
||||
`page` reports `offset`, `limit`, `returned`, `total`, and `next_offset`.
|
||||
`next_offset` is null when the page reaches the end of the decoded list.
|
||||
`coverage` counts every decoded range, every decoded CIE, how many ranges
|
||||
match a symbol, and how many do not. `examined_records` counts CIE and FDE records visited, including
|
||||
records that could not be decoded.
|
||||
|
||||
A missing `.eh_frame` section and a missing `PT_GNU_EH_FRAME` segment are
|
||||
observed absence of those declarations. That absence is not proof the image
|
||||
has no functions. Program headers come from the shared ELF section
|
||||
directory, which rejects an image whose program-header table cannot be read,
|
||||
so a missing `PT_GNU_EH_FRAME` is always observed absence. When section
|
||||
headers are missing too, section names are unknown, so a missing header is
|
||||
`unknown` rather than `absent`.
|
||||
|
||||
A `.eh_frame` located only through the `.eh_frame_hdr` `eh_frame_ptr` has no
|
||||
section size, so it is read up to the end of its `PT_LOAD` segment. Other
|
||||
data, such as `.gcc_except_table`, can follow it there. When the search table
|
||||
was decoded, the scan stops after the last FDE the table names, as libgcc's
|
||||
`PT_GNU_EH_FRAME` lookup only binary-searches that table. Later bytes are not
|
||||
decoded and a limitation says so. Without a usable table, the scan stops at
|
||||
the first record that fails to decode, as libgcc's linear FDE search does,
|
||||
and `coverage.status` is `incomplete`. A CIE with an unrecognized
|
||||
augmentation letter, or an FDE that uses one, also stops that scan. Reaching the end of the segment with
|
||||
no terminator also keeps coverage `incomplete`, because the table's extent is
|
||||
then unknown.
|
||||
|
||||
Addresses map to file offsets through `SHF_ALLOC` sections, then `PT_LOAD`
|
||||
segments. A section without `SHF_ALLOC`, such as `.comment` or `.debug_*`,
|
||||
is not loaded, so its `sh_addr` is never used for translation and it is never
|
||||
reported as the section containing a range. A record that ends past the table, or non-zero bytes after
|
||||
the terminator, keeps `coverage.status` at `incomplete`. Relocatable objects
|
||||
stay incomplete because relocations are not applied.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
The selected file is limited to 64 MiB by default (512 MiB maximum).
|
||||
`max_ranges` defaults to 8192 and caps at 65536. That ceiling applies
|
||||
separately to CIE records and to FDEs. Exceeding either budget fails without
|
||||
partial success. One page returns at most 4096 ranges. Symbol lookup stops
|
||||
after 65536 entries across `.symtab` and `.dynsym` combined. Reaching that
|
||||
cap keeps `coverage.status` at `incomplete`. Only symbols at decoded FDE
|
||||
starts are kept, and a name is decoded only for a returned range. The names
|
||||
on one page share a fixed 16 MiB text allowance; a page that exceeds it fails
|
||||
with a resource error whose recovery is a smaller `limit`, because
|
||||
`max_ranges` and `max_file_bytes` do not raise it.
|
||||
|
||||
Malformed ELF headers fail without partial success. This workflow does not
|
||||
execute the image, evaluate CFA programs, or follow indirect pointers.
|
||||
@@ -0,0 +1,151 @@
|
||||
# Linux kernel build config
|
||||
|
||||
`inspect_kernel_build_config` / `inspect-kernel-build-config` reads the
|
||||
`Linux version` banner and the embedded `.config` from one selected local
|
||||
kernel image without executing or booting it. Accepted inputs are a `vmlinux`
|
||||
ELF, a raw arm64 `Image`, an x86 `bzImage` or `zImage` whose payload is gzip,
|
||||
and a `configs.ko` module. It does not require a Linux host,
|
||||
`extract-ikconfig`, or `/proc/config.gz`.
|
||||
|
||||
```bash
|
||||
rea inspect-kernel-build-config /absolute/path/to/vmlinux --json
|
||||
rea inspect-kernel-build-config /absolute/path/to/bzImage --name CONFIG_SECURITY_SELINUX --json
|
||||
```
|
||||
|
||||
The CLI resolves relative paths against the caller's working directory. MCP
|
||||
requires an absolute filesystem path and preserves that exact selection:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inspect_kernel_build_config",
|
||||
"arguments": { "path": "/artifacts/vmlinux", "name": "CONFIG_MODULE_SIG" }
|
||||
}
|
||||
```
|
||||
|
||||
## Observations
|
||||
|
||||
The inline Evidence result contains the artifact path, SHA-256, and byte
|
||||
length. `format` is `elf` when the file starts with the ELF magic and `file`
|
||||
otherwise.
|
||||
|
||||
`banner` is the first printable string that starts with `Linux version `
|
||||
followed by a version token beginning with a digit and ends at a NUL or
|
||||
newline within 512 bytes. `version` is that token. `builder` is the first
|
||||
parenthesized group (`user@host`). `compiler` is the second group up to the
|
||||
last `) #`, so nested parentheses in compiler strings are kept. The banner is
|
||||
`absent` when no such string was found in the searched bytes and `unknown`
|
||||
when the bytes were not searched.
|
||||
|
||||
`config` is `present` only when all of the following hold:
|
||||
|
||||
- `IKCFG_ST` is immediately followed by a gzip member (`1f 8b 08`).
|
||||
- The member inflates within `max_config_bytes` and its CRC-32 and ISIZE
|
||||
trailer match.
|
||||
- The member trailer ends exactly at the first `IKCFG_ED` after the gzip
|
||||
header. Inflation reads only the bytes up to that marker.
|
||||
- Every non-blank line of the inflated text is a `#` comment,
|
||||
`# CONFIG_X is not set`, or `CONFIG_X=value`, and the text is valid UTF-8
|
||||
with no control bytes other than tab, CR, and LF.
|
||||
|
||||
An `IKCFG_ST` string that is not followed by gzip magic, or whose complete
|
||||
member is not followed by `IKCFG_ED`, is skipped, so an ordinary string is never
|
||||
reported as a config. When `IKCFG_ST`, gzip magic, and a later `IKCFG_ED` frame
|
||||
a member that does not decode, a deflate stream cut off by that marker, a
|
||||
member that fails its CRC-32 or ISIZE check, or text that fails the grammar,
|
||||
the config is `malformed` with coverage
|
||||
`incomplete`, and `marker`, `gzip`, and `end_marker` locate the blob. A
|
||||
malformed blob is never reported as an absent config. A valid config later in
|
||||
the searched bytes still wins. `marker`, `gzip`, and `end_marker` give
|
||||
the three ranges. `sha256` hashes the inflated text. `option_count` counts
|
||||
every `CONFIG_*` line. `matched_count` counts the options that match the
|
||||
optional exact `name` filter, and `entries` is the `offset`/`limit` page of
|
||||
those matches in file order.
|
||||
|
||||
Each entry has a `name`, a `kind`, and a `value`:
|
||||
|
||||
| `kind` | Source line | `value` |
|
||||
| --------- | -------------------------- | ------------------------- |
|
||||
| `y`, `m` | `CONFIG_X=y`, `CONFIG_X=m` | `y` or `m` |
|
||||
| `number` | decimal or `0x` hex | the text as written |
|
||||
| `string` | `CONFIG_X="..."` | decoded text (`\"`, `\\`) |
|
||||
| `not_set` | `# CONFIG_X is not set` | `null` |
|
||||
|
||||
Banner text and configuration values are target-derived and untrusted.
|
||||
|
||||
## bzImage payloads
|
||||
|
||||
A file with `HdrS` at offset `0x202` is an x86 setup header. From boot
|
||||
protocol 2.08, `payload_offset` and `payload_length` locate the compressed
|
||||
kernel after the `(setup_sects + 1) * 512` setup code. `payload` reports the
|
||||
container, codec, file range, and inflated length. A gzip payload is inflated
|
||||
within `max_payload_bytes` and the inflated bytes are searched. Locations in
|
||||
those bytes have `space: "inflated_payload"` and are offsets in the inflated
|
||||
payload, not file offsets. Only the leading gzip member is inflated, and its
|
||||
own ISIZE trailer gives the inflated length. Kbuild appends a separate 4-byte
|
||||
size only for the non-gzip codecs. Any bytes after the gzip member inside the
|
||||
payload are not read.
|
||||
|
||||
xz, lz4, lzma, zstd, bzip2, and lzo payloads are `unsupported`. The result
|
||||
names the codec and `external_decompression` as the next probe. This is an
|
||||
external step, not a REA operation: decompress the payload with the matching
|
||||
utility into a separate file, then call `inspect_kernel_build_config` on that
|
||||
file. A file that is itself a compressed stream, including a whole-file gzip
|
||||
such as `Image.gz`, is reported as `unsupported` with its codec and is not
|
||||
inflated. Only a gzip payload inside a bzImage is inflated.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
The selected file is limited to 64 MiB by default (512 MiB maximum). An IKCFG
|
||||
member may inflate to 4 MiB by default (32 MiB maximum) and a bzImage payload
|
||||
to 128 MiB by default (512 MiB maximum). At most 16384 `CONFIG_*` options are
|
||||
examined by default (65536 maximum). A page holds 256 entries by default
|
||||
(4096 maximum). Exceeding any budget fails with no partial success and names
|
||||
the option to raise. An IKCFG member past `max_config_bytes` fails that way only
|
||||
when no later candidate is accepted, so an oversized decoy cannot hide a valid
|
||||
config.
|
||||
|
||||
One search inflates at most 16 `IKCFG_ST` gzip candidates and at most four
|
||||
times `max_config_bytes` of output across them. A candidate whose stream fails
|
||||
partway through is charged its full per-candidate allowance, since its partial
|
||||
output is not measured. When that search budget runs
|
||||
out before a config is accepted, the config is `incomplete` with reason
|
||||
`config_search_exhausted` instead of failing or reporting an absent config.
|
||||
Inflation runs off the event loop. Every scan, including marker
|
||||
searches that find nothing, config text checks, validation of one long value,
|
||||
and hashing, yields to it at least once
|
||||
per MiB, so a cancellation that arrives while the image is being parsed is honored
|
||||
at the next check. One inflate call runs to its output bound once started.
|
||||
|
||||
Results that could not search or read the kernel bytes stay `incomplete`,
|
||||
`malformed`, or `unsupported` and are never
|
||||
reported as an absent config:
|
||||
|
||||
| `config.reason` | Meaning |
|
||||
| ---------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `config_gzip_invalid` | a framed `IKCFG_ST` gzip member does not decode or fails its CRC-32 or ISIZE |
|
||||
| `config_text_invalid` | a framed `IKCFG_ST` gzip member is not `.config` text |
|
||||
| `config_gzip_truncated` | an `IKCFG_ST` gzip member runs past the searched bytes |
|
||||
| `config_search_exhausted` | decoy candidates used up the config search budget |
|
||||
| `payload_truncated` | the declared bzImage payload or its gzip member ends early |
|
||||
| `payload_gzip_invalid` | the bzImage gzip payload fails to inflate or its trailer |
|
||||
| `payload_codec_unsupported` | a compressed payload or whole-file stream was not inflated |
|
||||
| `unrecognized_payload_codec` | the bzImage payload starts with no known codec magic |
|
||||
| `setup_header_payload_unavailable` | the setup header predates 2.08 or has no payload length |
|
||||
|
||||
A kernel built without `CONFIG_IKCONFIG` carries no embedded config, so an
|
||||
`absent` config describes only the bytes that were searched. A kernel built
|
||||
with `CONFIG_IKCONFIG=m` keeps the config in `configs.ko`; inspect that module
|
||||
instead of the image. This workflow does not execute the image, compare the
|
||||
config with a source tree, or evaluate Kconfig dependencies.
|
||||
|
||||
## Format references
|
||||
|
||||
The markers follow Linux v6.12's
|
||||
[`kernel/configs.c`](https://github.com/torvalds/linux/blob/v6.12/kernel/configs.c)
|
||||
and
|
||||
[`scripts/extract-ikconfig`](https://github.com/torvalds/linux/blob/v6.12/scripts/extract-ikconfig).
|
||||
The setup header fields follow the
|
||||
[x86 boot protocol](https://docs.kernel.org/arch/x86/boot.html). The banner
|
||||
format follows
|
||||
[`init/version-timestamp.c`](https://github.com/torvalds/linux/blob/v6.12/init/version-timestamp.c).
|
||||
These references establish the decoded layout, not runtime behavior.
|
||||
@@ -0,0 +1,178 @@
|
||||
# ELF and Mach-O initializer functions
|
||||
|
||||
`inspect_native_initializers` / `inspect-native-initializers` lists the
|
||||
functions that one local ELF or Mach-O image declares to run before `main` and
|
||||
at exit. It reads the file without executing it and does not need a
|
||||
disassembler provider.
|
||||
|
||||
```bash
|
||||
rea inspect-native-initializers /absolute/path/to/program --json
|
||||
rea inspect-native-initializers ./Universal.app/Contents/MacOS/App --architecture arm64 --json
|
||||
```
|
||||
|
||||
The CLI resolves relative paths against the caller's working directory. MCP
|
||||
requires an absolute filesystem path:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "inspect_native_initializers",
|
||||
"arguments": { "path": "/artifacts/program", "offset": 0, "limit": 64 }
|
||||
}
|
||||
```
|
||||
|
||||
A universal Mach-O requires `architecture` to select one slice. ELF files and
|
||||
thin Mach-O files do not take it.
|
||||
|
||||
## Sources
|
||||
|
||||
ELF entries are listed in this order:
|
||||
|
||||
| Kind | Source |
|
||||
| --------------- | ------------------------------------------------------------------------------------- |
|
||||
| `preinit_array` | `DT_PREINIT_ARRAY` / `DT_PREINIT_ARRAYSZ`, else `.preinit_array` |
|
||||
| `init` | `DT_INIT` |
|
||||
| `init_array` | `DT_INIT_ARRAY` / `DT_INIT_ARRAYSZ`, else `SHT_INIT_ARRAY` or `.init_array*` sections |
|
||||
| `ctors` | legacy `.ctors` and `.ctors.*` sections |
|
||||
| `fini` | `DT_FINI` |
|
||||
| `fini_array` | `DT_FINI_ARRAY` / `DT_FINI_ARRAYSZ`, else `SHT_FINI_ARRAY` or `.fini_array*` sections |
|
||||
| `dtors` | legacy `.dtors` and `.dtors.*` sections |
|
||||
|
||||
Section fallback applies when the dynamic tag is absent, as in static
|
||||
executables and relocatable objects. Mach-O entries come from sections typed
|
||||
`S_MOD_INIT_FUNC_POINTERS` (`mod_init`), `S_INIT_FUNC_OFFSETS`
|
||||
(`init_offsets`) and `S_MOD_TERM_FUNC_POINTERS` (`mod_term`).
|
||||
|
||||
## Entries
|
||||
|
||||
Each `entries[]` item reports:
|
||||
|
||||
- `slot_va`, `slot_file_offset`, `slot_bytes` and `slot_section`: where the
|
||||
pointer or offset is stored. For a universal Mach-O, file offsets are
|
||||
relative to the whole file, not the slice. For `init` and `fini` the slot is
|
||||
the `DT_INIT` / `DT_FINI` value field in the dynamic section. When that field
|
||||
is outside every load segment, `slot_va` and `slot_section` are null and a
|
||||
limitation says so.
|
||||
- `value_va`, `value_file_offset` and `section`: the resolved target address,
|
||||
its file offset and its containing section. These are null when the value
|
||||
was not established. A file offset is also null when load segments map the
|
||||
address ambiguously (overlapping segments with different file offsets, or
|
||||
file and zero-fill memory), and the report is then `incomplete`.
|
||||
- `symbol`: a defined symbol whose value equals the target exactly, or the
|
||||
import name of an unresolved symbolic relocation or chained bind.
|
||||
- `resolution`: how the value was obtained.
|
||||
|
||||
| Resolution | Meaning |
|
||||
| ------------------- | -------------------------------------------------------------------- |
|
||||
| `raw` | The stored word, used when no relocation or fixup covers it |
|
||||
| `relative_addend` | An `R_*_RELATIVE` relocation addend (RELA, or the REL in-place word) |
|
||||
| `relr` | A `DT_RELR` packed relative relocation |
|
||||
| `symbol_addend` | A section relocation against a defined symbol plus its addend |
|
||||
| `chained_fixup` | A Mach-O chained-fixup rebase target |
|
||||
| `dyld_info_rebase` | A Mach-O `LC_DYLD_INFO` rebase opcode target |
|
||||
| `offset_table` | A 32-bit `__init_offsets` value added to the image base |
|
||||
| `unresolved_import` | A relocation or bind against an undefined symbol |
|
||||
| `unresolved` | A slot whose value this inspection cannot establish |
|
||||
|
||||
A bound import name over the 1024-byte name budget is reported as no name and
|
||||
makes the report `incomplete` with a counted limitation.
|
||||
|
||||
Symbol and section names are untrusted file text and carry
|
||||
`trust: "observed-untrusted"`.
|
||||
|
||||
For PIE executables and shared objects the array slots are usually zero on
|
||||
disk. A slot is reported `unresolved`, never as its stored zero, when the
|
||||
dynamic relocation tables use an encoding this inspection does not decode
|
||||
(for example Android packed relocations or an unsupported machine). Relative
|
||||
relocations are decoded for x86-64, i386, AArch64 and 32-bit ARM. A slot is
|
||||
also `unresolved` when a dynamic relocation writes only part of it, starts
|
||||
inside it, or writes it more than once with different values.
|
||||
|
||||
Section `REL` / `RELA` tables are applied to slots that no dynamic relocation
|
||||
covers. When such a table is skipped for an unexpected entry size, cannot be
|
||||
read, or lies past the record budget, every slot it could reach that has no
|
||||
relocation found is `unresolved`, and a `.ctors` slot is not dropped as a
|
||||
sentinel. A section record that writes only part of a slot, starts inside it,
|
||||
or repeats it also leaves the slot `unresolved`. In a relocatable object a
|
||||
table reaches only the section named by its `sh_info`. In a linked image, a relocation section without `SHF_ALLOC`
|
||||
(such as one kept by `--emit-relocs`) was already applied by the static
|
||||
linker, so the slot's stored word is used rather than applying the record
|
||||
again.
|
||||
|
||||
An absolute relocation against an `STT_GNU_IFUNC` symbol is `unresolved`: the
|
||||
symbol value is the resolver, and the loader stores whatever the resolver
|
||||
returns.
|
||||
|
||||
On 32-bit ARM (ELF `EM_ARM` and Mach-O `CPU_TYPE_ARM`), bit 0 of a function
|
||||
pointer selects Thumb state. `value_va` keeps the pointer as stored, while
|
||||
`value_file_offset` and `section` describe the code address with that bit
|
||||
cleared. A Mach-O symbol is matched at either address.
|
||||
|
||||
In a relocatable object (`ET_REL`) every section starts at address 0. Slot
|
||||
and value addresses are offsets inside the named section, and a limitation
|
||||
says so.
|
||||
|
||||
Mach-O pointer slots are decoded through chained fixups or `LC_DYLD_INFO`
|
||||
opcodes for linked little-endian arm64 and x86-64 images. Other linked images,
|
||||
including 32-bit ones, have no fixup decoder here: their stored word is used
|
||||
only when the image declares no `LC_DYLD_INFO` bind stream, and a pointer slot
|
||||
is `unresolved` otherwise. Legacy external relocations (`LC_DYSYMTAB`
|
||||
`nextrel`) are not decoded, so they make an otherwise raw pointer slot
|
||||
`unresolved` in any image. In an object file (`MH_OBJECT`), each section's own
|
||||
relocation entries set the slot: a pointer-width `UNSIGNED` entry against a
|
||||
defined symbol gives `symbol_addend`, one against an undefined symbol gives
|
||||
`unresolved_import`, a section-ordinal entry keeps the stored address, and any
|
||||
other entry leaves the slot `unresolved`. An `arm64_32` image that declares a
|
||||
64-bit header is rejected as malformed, since its pointers are four bytes.
|
||||
|
||||
`.ctors` and `.dtors` values `0` and `-1` are list sentinels and are omitted.
|
||||
`-1` means all ones at the image's pointer width: `0xffffffff` in ELF32 and
|
||||
`0xffffffffffffffff` in ELF64. A 64-bit slot holding `0xffffffff` is listed.
|
||||
A stored zero in an initializer array is listed, so the array length stays
|
||||
visible.
|
||||
|
||||
## Paging and limits
|
||||
|
||||
`offset` and `limit` page the ordered list (default limit 64, maximum 4096).
|
||||
`coverage.examined_entries` counts every slot read, including omitted
|
||||
sentinels, and `total_entries` (the listed entries) is set when the inventory
|
||||
is complete. At most 65536 slots are examined; beyond that, or when relocation
|
||||
coverage is unknown, `status` and `coverage.status` are `incomplete`.
|
||||
|
||||
ELF symbol names come from at most 65536 symbols across all `SHT_SYMTAB` and
|
||||
`SHT_DYNSYM` tables together, and section `REL` / `RELA` relocations from at
|
||||
most 1048576 records across all relocation sections together. Mach-O symbol
|
||||
names come from at most 65536 symbols across all `LC_SYMTAB` commands
|
||||
together; a repeated `LC_SYMTAB` over the same ranges is ignored with a
|
||||
limitation. Reaching any of these budgets makes the report `incomplete` with a
|
||||
limitation.
|
||||
|
||||
A symbol name that cannot be read, because its string table is missing or its
|
||||
offset lies outside the table, is reported as no name and makes the report
|
||||
`incomplete` with a counted limitation. Name offset 0 is the empty name.
|
||||
|
||||
The dynamic relocation tables are read in steps that yield to other work and
|
||||
observe cancellation, so a large `DT_RELR` table does not block the server.
|
||||
|
||||
`limitations` lists the standing limitations, then at most 24 distinct
|
||||
observations from the image. Reasons a crafted table can repeat per row, such
|
||||
as symbol names over the 1024-byte budget or relocation sections with an
|
||||
unexpected entry size, are reported once with a count, and observations past
|
||||
the 24-note budget are counted in one closing line. The list never exceeds 40
|
||||
lines.
|
||||
|
||||
The selected file is limited to 64 MiB by default (`max_file_bytes`, 512 MiB
|
||||
maximum). Malformed headers, multiple `PT_DYNAMIC` segments and truncated
|
||||
dynamic sections fail without partial success.
|
||||
|
||||
This inspection does not prove that a listed address runs, and file order is
|
||||
not the runtime order: `DT_FINI` is listed before `fini_array`, while the
|
||||
dynamic linker runs `fini_array` first, and `.ctors` runs in reverse order. A
|
||||
missing tag or section is observed absence of that declaration, not proof that
|
||||
no code runs before `main`.
|
||||
|
||||
Legacy Mach-O bind lookup examines at most 4096 candidate runs per query and
|
||||
at most twice the file byte count across the decoded image's queries. These
|
||||
resource allowances bound sparse, overlapping run descriptions without expanding
|
||||
them into per-address objects. Exhaustion leaves pointer applicability unresolved
|
||||
and the report incomplete. Bind-stream parsing and initializer batches yield so
|
||||
other requests and cancellation can run.
|
||||
@@ -332,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
|
||||
@@ -1131,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
|
||||
|
||||
@@ -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.
|
||||
@@ -35,11 +35,13 @@ different recovery: reinstall REA for the active platform, architecture, and
|
||||
Node.js version with optional dependencies enabled. Capability diagnostics
|
||||
distinguish this from the Windows capture-adapter limitation.
|
||||
|
||||
macOS also requires Apple's Swift compiler through `xcrun` for process
|
||||
ownership inspection. REA compiles its packaged, narrow process-inspection
|
||||
helper into a private temporary directory before a capture or owned provider
|
||||
process starts; the same prerequisite applies to owned provider-process
|
||||
supervision on macOS. REA removes that directory when it exits. REA does not
|
||||
macOS also requires REA's process-inspection helper for ownership inspection.
|
||||
REA reuses a verified cached helper or compiles one with the selected Swift
|
||||
toolchain before a capture or owned provider process starts; the same
|
||||
prerequisite applies to owned provider-process supervision on macOS.
|
||||
Per-process temporary helper directories are removed on exit; the verified
|
||||
cache persists. See [helper and toolchain configuration](#scenario-and-result-details)
|
||||
for cache validation and compiler overrides. REA does not
|
||||
install Xcode, Command Line Tools, or other software. Capability checks prepare
|
||||
this helper before reporting macOS capture as available.
|
||||
|
||||
@@ -97,6 +99,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 +522,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:
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ correspondence merely from their different retained registrations.
|
||||
- `compare_web_screenshots` / `rea compare-web-screenshots` performs bounded local PNG pixel comparison without OCR or external services.
|
||||
- The CLI comparison commands accept each capture, screenshot artifact or normalization policy as inline JSON or a JSON file path. Use files for screenshot artifacts and scenario captures, whose embedded PNG bytes can exceed the host's command-line length limit.
|
||||
- Every surface has equivalent CLI and MCP contracts and returns Evidence provenance.
|
||||
- MCP tools return complete results inline and include the Evidence ID. Session evidence can be exported with `export_evidence_bundle`.
|
||||
- By default, MCP tools return complete results inline and include the Evidence ID. Selected summary views retain the complete parent Evidence and return a projection. Session evidence can be exported with `export_evidence_bundle`.
|
||||
|
||||
Target discovery returns the complete in-scope target array in one result.
|
||||
|
||||
@@ -228,7 +228,7 @@ in an existing profile.
|
||||
For such a browser, pass the browser socket instead of the HTTP endpoint:
|
||||
|
||||
```bash
|
||||
rea list-browser-targets ws://127.0.0.1:9222/devtools/browser/<id>
|
||||
rea list-browser-targets "ws://127.0.0.1:9222/devtools/browser/<id>"
|
||||
```
|
||||
|
||||
Chrome writes the port and the `/devtools/browser/<id>` path to the
|
||||
|
||||
@@ -359,7 +359,7 @@ A `request` step sends one HTTP request from the page with the page's own
|
||||
recorded in the step's network events like any request the application makes.
|
||||
Use it to record an application's API, including writes, when driving the UI
|
||||
for each call would be slower or less exact than calling the endpoint the UI
|
||||
calls. It is the only action that changes application state without a user
|
||||
calls. This action directly sends a caller-declared HTTP request without a user
|
||||
gesture, so run scenarios with write requests only against an instance whose
|
||||
data you may change. This scenario creates one item:
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ The [documentation directory](README.md) lists every guide by domain.
|
||||
| Task | Guides |
|
||||
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Identify a desktop installation | [Runtime candidates, evidence and follow-up files](desktop-applications.md) |
|
||||
| Inspect native functions, references, or types | [Native binaries](guides/native/native-investigation.md), [Go metadata](guides/native/go-binaries.md), [Rust dependencies](rust-binaries.md), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [PE imports](pe-imports.md), [PE TLS/load config](pe-load-config.md), [ELF notes](elf-notes.md), [Linux kernel modules](kernel-modules.md), [Apple IPS](apple-ips.md), [Erlang BEAM](erlang-beam.md), [offline ELF layout](guides/native/binary-diagnostics.md), [recorded crashes](guides/native/recorded-crashes.md) |
|
||||
| Inspect native functions, references, or types | [Native binaries](guides/native/native-investigation.md), [Go metadata](guides/native/go-binaries.md), [Rust dependencies](rust-binaries.md), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [PE imports](pe-imports.md), [PE TLS/load config](pe-load-config.md), [ELF notes](elf-notes.md), [initializer functions](guides/native/native-initializers.md), [ELF unwind ranges](guides/native/elf-unwind-ranges.md), [Linux kernel modules](kernel-modules.md), [Linux kernel build config](guides/native/kernel-build-config.md), [Apple IPS](apple-ips.md), [Erlang BEAM](erlang-beam.md), [offline ELF layout](guides/native/binary-diagnostics.md), [recorded crashes](guides/native/recorded-crashes.md) |
|
||||
| Select a native provider or import format | [Ghidra semantics](providers/ghidra-provider.md), [Windows](providers/windows-ghidra-p0.md), [DOS](providers/ghidra-dos.md), [raw bytes](providers/raw-binary.md), [GameCube DOL](ghidra-dol.md), [MIPS](providers/ghidra-mips.md), [RISC-V](providers/ghidra-riscv.md), [PowerPC](ghidra-ppc.md), [PSP](providers/ghidra-psp.md), [NativeAOT](providers/ghidra-nativeaot.md), [IDA](providers/ida-provider.md), [Kuna](kuna-provider.md), [JEB](providers/jeb-analysis.md) |
|
||||
| Analyze JavaScript or Electron artifacts | [Static analysis](guides/javascript/javascript-artifact-reconstruction.md), [tracing and comparisons](guides/javascript/javascript-application-workflows.md), [application graph](guides/javascript/javascript-application-graph.md), [source recovery](guides/javascript/javascript-recovery.md) |
|
||||
| Compare static JavaScript with runtime observations | [Runtime attribution](guides/javascript/javascript-runtime-observation.md), [reconciliation](guides/javascript/javascript-runtime-reconciliation.md), [Electron observation](guides/javascript/electron-observation.md), [Electron fuses](electron-fuses.md) |
|
||||
|
||||
@@ -24,6 +24,13 @@ This validates the embedded bundle, not the rest of the snapshot container.
|
||||
|
||||
## Configure
|
||||
|
||||
Doctor uses the selected client's effective registration environment. An
|
||||
unresolved setting that affects the probe keeps readiness unknown rather than
|
||||
falling back to the terminal account. Kuna's home-based cache fallback includes
|
||||
`USERPROFILE` when `HOME` is absent; an explicit cache root or a selected nonempty
|
||||
`HOME` makes that fallback irrelevant. These home settings are probe dependencies
|
||||
and are not persisted as ambient provider registration settings.
|
||||
|
||||
```bash
|
||||
export REA_KUNA_COMMAND=/absolute/path/to/kuna
|
||||
rea doctor --provider kuna
|
||||
|
||||
@@ -58,7 +58,11 @@ fail without partial success. A security directory that ends in fewer than
|
||||
eight header bytes, including zeros, is a truncated `WIN_CERTIFICATE` and
|
||||
fails the same way. SignedData must contain at least one `SignerInfo`, and
|
||||
each `SignerInfo` must carry a non-empty signature value. Each embedded X.509
|
||||
certificate must include `subjectPublicKeyInfo` and `signatureValue`. Decoded
|
||||
certificate must include `subjectPublicKeyInfo` and `signatureValue`.
|
||||
Certificate issuer/subject and signer issuer names require nonempty RDN sets
|
||||
and exactly two fields (type and value) in each attribute, as defined in
|
||||
[RFC 5280](https://www.rfc-editor.org/rfc/rfc5280.html#section-4.1.2.4).
|
||||
Malformed name structures fail before their text is reported. Decoded
|
||||
certificate name text, serials, validity spellings, and subject key identifiers
|
||||
share a 64 KiB budget per PKCS#7 payload, and each payload decodes at most
|
||||
16,384 ASN.1 values. Exhausting either fixed allowance returns a nonretryable
|
||||
|
||||
@@ -267,7 +267,7 @@ profile stages before retrying their retained descriptors.
|
||||
| Function identity | Every function result carries the entry address and Ghidra FunctionManager classification for external, thunk, and resolved thunk target. These are observations, not proof that unresolved targetless calls have been recovered. |
|
||||
| Assembly and pseudocode | Assembly is complete Ghidra Listing text; pseudocode is Ghidra decompiler output. Neither is original source, and cross-provider comparison never treats Hopper and Ghidra text as equal or unequal semantic facts. |
|
||||
| Instruction fast path | `read_function_instructions` returns every raw Listing instruction for the requested function without invoking the decompiler or whole-program name/string inventories. |
|
||||
| Calls and references | Callers/callees contain only resolved functions. Reference edges preserve exact ReferenceManager type and call/jump/data/read/write/indirect/computed/conditional/terminal/external facts. Targetless computed flow remains unknown. Synthetic entry-point references without actionable memory sources are omitted explicitly. |
|
||||
| Calls and references | Callers/callees contain only resolved functions. Reference edges preserve exact ReferenceManager type and call/jump/data/read/write/indirect/computed/conditional/terminal/external facts. Targetless computed flow remains unknown. A computed call's recorded targets stay observed callees, but they are static candidates rather than an exhaustive set, so callee coverage is `partial` and names those call sites. Synthetic entry-point references without actionable memory sources are omitted explicitly. |
|
||||
| CFG | Dossiers use `BasicBlockModel` and retain only non-call successors inside the function body. CFG topology is address-normalized for comparison; provider-specific block construction remains a declared difference. |
|
||||
| P-code value flow | Function dossiers include up to 3,000 high-p-code operations, at most 64 inputs per operation, and 12,000 def-use edges. Results identify memory reads/writes, branches, and calls by p-code opcode, and mark decompiler-dead operations. Large results report truncation, an omitted-operation lower bound, and known omitted-input/edge counts. The dossier is an intra-function graph; `trace_native_values` composes derived parameter/argument and return/output dependencies across resolved calls. It does not resolve memory aliasing, call side effects, runtime behavior, persistent state, or business meaning. |
|
||||
| Result extent | Function instruction scans and native API boundary observations remain complete. P-code flow is the explicit bounded exception; its count fields distinguish exact retained counts from lower-bound or known-omitted counts. Caller cancellation and provider failures remain distinct. |
|
||||
|
||||
@@ -233,7 +233,7 @@ admits it explicitly. Raw-binary and GameCube DOL targets are refused; open
|
||||
them with Ghidra. Admission is not verification: the real workflows under
|
||||
[Verification](#verification) cover x86_64 and arm64 only.
|
||||
|
||||
All profiles support procedure/string inventory and literal or regex search, procedure resolution, pseudocode, assembly, raw function instructions, resolved callees, incoming address references, and a function dossier. Inventories and modern pseudocode/assembly follow upstream pagination. Upstream limits on modern xrefs and callees are retained as explicit truncation limitations. In the modern headless profile, targets that are not proven x86-only use processor-neutral `callgraph` edges instead of the x86 instruction checks in upstream `callees` (mrexodia/ida-pro-mcp#549). REA requests depth zero: the pinned upstream emits the root's outgoing edges without scanning child functions, then REA batches function-name lookup for those addresses. The graph covers recognized function destinations only; imports and other non-function targets remain unknown. A server without `callgraph` returns an empty relationship list with an explicit coverage limitation. Graph and path workflows retain those limitations alongside observed edges. A failed or inconsistent graph reply remains an error. A transport-level truncated preview is rejected rather than reported as complete evidence; the error preserves upstream retrieval guidance.
|
||||
All profiles support procedure/string inventory and literal or regex search, procedure resolution, pseudocode, assembly, raw function instructions, resolved callees, incoming address references, and a function dossier. Inventories and modern pseudocode/assembly follow upstream pagination. Upstream limits on modern xrefs and callees are retained as explicit truncation limitations. In the modern headless profile, targets that are not proven x86-only use processor-neutral `callgraph` edges instead of the x86 instruction checks in upstream `callees` (mrexodia/ida-pro-mcp#549). REA requests depth zero: the pinned upstream emits the root's outgoing edges without scanning child functions, then REA batches function-name lookup for those addresses. The graph covers recognized function destinations only; imports and other non-function targets remain unknown. A server without `callgraph` returns an empty relationship list with an explicit coverage limitation. Neither `callees` nor `callgraph` reports the call sites behind its edges, so a computed call's targets are never established as exhaustive; callee coverage is therefore `partial` even for an uncapped reply, and a call path that does not reach its goal remains `unknown`. Graph and path workflows retain those limitations alongside observed edges. A failed or inconsistent graph reply remains an error. A transport-level truncated preview is rejected rather than reported as complete evidence; the error preserves upstream retrieval guidance.
|
||||
|
||||
All profiles expose `list_documents` as the single target admitted for the session. Attached mode verifies its digest against IDA metadata before returning it; headless mode binds the digest-checked private input. `inspect_address_context`, `trace_feature`, and `binary_overview` can therefore resolve that identity without upstream document-listing tools. Segment enumeration is optional: when the selected profile cannot provide it, `binary_overview` still returns document and procedure/string counts and omits `segments` and `segment_count`; omission means unobserved, not empty. The modern headless profile also supports `resolve_containing_procedure`. An address resolves through upstream `lookup_funcs` to the canonical entry of the function that contains it; the body stays unavailable like other IDA identities. When no function contains it, REA reads the database-scoped minimal `survey_binary` and reports `not_in_procedure` for an address inside one of its segments (ends are exclusive) and `outside_segments` otherwise. A missing, truncated or inconsistent survey fails the read instead of guessing a reason. `trace_feature` marks a trace truncated, with a residual unknown for that address, when upstream caps the references it returned. Attached profiles do not declare address containment resolution.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · **العربية** · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: هندسة عكسية لأي شيء
|
||||
|
||||
@@ -84,6 +84,10 @@ npx rea-agents setup
|
||||
|
||||
يستخدم MCP مخططات إدخال مختصرة افتراضيًا. للحصول على إرشادات الحقول الكاملة وتفاصيل التحقق المتداخل، اضبط `REA_MCP_INPUT_SCHEMA_PROFILE=full` في تسجيل MCP. يحتفظ الخياران بجميع الأدوات والتحقق القياسي نفسه على الخادم؛ راجع دليل عقود MCP.
|
||||
|
||||
يسجّل الإعداد بيئة التشغيل المحددة وملف دخول REA مباشرةً. عند استخدام مشغّل حزم، احتفظ بإدخال ذاكرة التخزين المؤقت وبيئة التشغيل؛ ونفّذ تنزيل الحزمة من دليل موثوق خارج المشروع المستهدف. راجع دليل التثبيت والإعداد.
|
||||
|
||||
تُعلن مخططات الإخراج الكاملة افتراضيًا. إذا حدّ عميلك من حجم `tools/list`، فاضبط `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` أو `off` في تسجيل MCP؛ يظل التحقق والخروج المنظّم كاملين على الخادم. راجع قسم مخططات الإخراج في دليل عقود MCP.
|
||||
|
||||
### اطلب من وكيلك
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ npx rea-agents@latest setup
|
||||
| بنية ELF دون تشغيل | الأقسام والمقاطع والرموز ومعلومات إعادة التموضع الأصلية، وآليات الحماية المحتملة المستدلّ عليها بالفحص الثابت | pwntools يوفّره المستدعي على Linux x64؛ [تشخيص الملفات الثنائية](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا على Linux x64؛ [دليل EVM دون تشغيل](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -172,6 +177,7 @@ npx rea-agents@latest setup
|
||||
| التقاط الحزم | نقاط النهاية وDNS وTLS SNI وتوزيع البروتوكولات وطلبات HTTP | tshark وcapinfos يوفّرهما المُستدعي؛ [دليل pcap](../guides/data/pcap-analysis.md) |
|
||||
| تجميعات .NET | البيانات الوصفية، وتعليمات CIL، واعتماديات الشيفرة الأصلية المعلنة، ومقارنات البناء | فحص ثابت؛ [دليل الشيفرة المُدارة](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS/Windows x64؛ [دليل Android](../guides/android/android-analysis.md) |
|
||||
| أجهزة Android | الأجهزة والحزم والعمليات والسجلات والدامبات ولقطات الشاشة ونقل APK/الملفات | adb يوفّره المُستدعي (محاكي أو جهاز)؛ [دليل ADB](../guides/android/adb-device-analysis.md) |
|
||||
| مشاريع JEB | وحدات المشروع من المحرك وبصمات المصنّفات والكود الزائف للأنواع/الدوال | عميل JEB يبدأه المُستدعي ويقدّم MCP، ويُختار عبر REA_JEB_MCP_URL؛ [دليل JEB](../providers/jeb-analysis.md) |
|
||||
@@ -273,6 +279,12 @@ agent-env run ./my-env
|
||||
[مرجع البيئات](../agent-environments.md) ·
|
||||
[شاهد العرض على X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### بيئات تطبيقات سطح المكتب
|
||||
|
||||
يستطيع REA أيضًا إنشاء بيئة لتطبيق سطح مكتب على Linux يستخدمه الوكيل عبر لقطات الشاشة والفأرة ولوحة المفاتيح. من طلب من سطر واحد، مثل "أنشئ لي بيئة Gnote يضيف فيها الوكيل زيت الزيتون إلى ملاحظة قائمة التسوق"، يثبّت وكيلك التطبيق على حاسوب بناء محلي، ويكتب المهمة، ويصدّر البيئة، ثم يتحقق من المهمة على حاسوب جديد. يحتاج الجهاز الذي يبنيها إلى Linux على amd64 أو arm64، وDocker، وإصدار إطار agentenv الذي يحدده الدليل.
|
||||
|
||||
[إعداد بيئات تطبيقات سطح المكتب](../desktop-build-computer.md)
|
||||
|
||||
## الأسئلة الشائعة
|
||||
|
||||
<details>
|
||||
|
||||
@@ -0,0 +1,523 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · **Български**
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
### Един MCP сървър за обратно инженерство на бинарни файлове, приложения и поведение по време на изпълнение.
|
||||
|
||||
**Харесва ви функция в някое приложение? Разберете как работи, чак до ниво бинарен код.**
|
||||
|
||||
[](https://www.npmjs.com/package/rea-agents)
|
||||
[](../reference/mcp-contracts.md#generated-catalog)
|
||||
[](#current-status)
|
||||
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
||||
[](../../LICENSE)
|
||||
[](https://discord.gg/GkcryMnJDM)
|
||||
|
||||
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
||||
|
||||
**[Уебсайт](https://rea.tools/) · [Ръководства](https://rea.tools/guides/) · [Примери](https://rea.tools/showcase/)**
|
||||
|
||||
<a href="https://discord.com/invite/GkcryMnJDM"><img alt="Присъединете се към общността на REA в Discord" src="https://img.shields.io/badge/Join%20us%20on%20Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" height="40"></a>
|
||||
|
||||
[Бърз старт](#бърз-старт) · [Как работи REA](#как-работи-rea) · [Какво можете да анализирате](#какво-можете-да-анализирате) · [Примери](#примери) · [Създаване на RL среди](#build-rl-environments) · [Често задавани въпроси](#често-задавани-въпроси) · [Документация](#документация)
|
||||
|
||||
<code>npx rea-agents setup</code>
|
||||
|
||||
</div>
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Изтегляйте REA от [morluto/rea](https://github.com/morluto/rea),
|
||||
> [rea.tools](https://rea.tools/) или [npm пакета rea-agents](https://www.npmjs.com/package/rea-agents).
|
||||
> Следвайте връзките за инсталиране и издания от тези официални източници. Подобно
|
||||
> име на хранилище или копиран README не доказва, че дадено изтегляне е официално.
|
||||
|
||||
<div align="center">
|
||||
|
||||
<br />
|
||||
|
||||
<img src="../assets/rea-hopper-analysis.png" alt="REA стартира своя мост за анализ в Hopper, докато изследва нативен бинарен файл" width="1200" />
|
||||
|
||||
<br /><br />
|
||||
|
||||
<table aria-label="Общността на REA">
|
||||
<tr>
|
||||
<td align="center" width="360">
|
||||
<a href="https://discord.gg/GkcryMnJDM">
|
||||
<img src="../assets/discord.svg" height="42" alt="Discord" /><br />
|
||||
<strong>Присъединете се към общността за обратно инженерство</strong>
|
||||
</a><br />
|
||||
<sub>Discord · Въпроси и отговори · Покажете какво сте направили</sub>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
Видели сте функция в приложение и искате същата във вашия продукт? Помолете агента си да я проучи с REA. Той може да изследва приложението без изходния му код, да обясни как работи функцията, да покаже доказателствата и да изгради подобна версия за вашия проект.
|
||||
|
||||
REA свързва агента ви с инструменти за изследване на нативни бинарни файлове, JavaScript и Electron приложения, .NET асемблита и уебсайтове. Същите инструменти можете да използвате и от терминала. Анализът се извършва локално, а резултатите включват доказателствата и ограниченията зад всеки извод.
|
||||
|
||||
Настройката регистрира REA в агента ви и инсталира съответните инструкции за работния процес. Нативният анализ може да използва вече инсталиран Hopper, Ghidra, IDA или Kuna; по желание настройката може да инсталира Hopper след ваше одобрение. Статичният анализ на JavaScript не изисква двигател за нативен анализ.
|
||||
|
||||
> **[Посетете уебсайта на REA](https://rea.tools/)** за инструкции за настройка, илюстрирани ръководства и реални казуси.
|
||||
|
||||
## Бърз старт
|
||||
|
||||
В Linux стартирането на Ghidra, JADX и инструментите за фърмуер, както и
|
||||
статичният анализ на JavaScript/Electron, изискват съвместима с procps команда
|
||||
`ps` в `PATH` на REA за проверките кой процес на кого принадлежи. Стъпките за
|
||||
отстраняване на проблема са в `docs/getting-started/installation.md`, в раздела
|
||||
„Linux owned-process prerequisite“.
|
||||
|
||||
### Настройте агента си
|
||||
|
||||
След като имате инсталирани Node.js и npm, изпълнете:
|
||||
|
||||
```bash
|
||||
npx rea-agents setup
|
||||
```
|
||||
|
||||
Изберете агентите си, прегледайте предложените промени и ги одобрете. Настройката
|
||||
добавя MCP сървъра на REA и съответните инструкции за работния процес, като прави
|
||||
резервни копия на съществуващата конфигурация. След това рестартирайте агента.
|
||||
Настройката записва директно избраната среда за изпълнение и входния скрипт на
|
||||
REA. Ако сте получили REA чрез инструмент за изпълнение на пакети (package
|
||||
runner), не изтривайте записа му в кеша. Изтегляйте пакета от доверена
|
||||
директория извън целевия проект. Подробности за инсталирането и отстраняването на
|
||||
проблеми има в ръководството за настройка по-долу.
|
||||
|
||||
Настройката поддържа Claude Code, Codex, Cursor, Gemini CLI, Grok Build и
|
||||
[други агенти](../getting-started/installation.md#supported-agents). Вижте
|
||||
[инсталиране и настройка](../getting-started/installation.md) за конфигуриране на
|
||||
доставчици на анализ, ръчна регистрация на MCP и инсталиране на плъгина за
|
||||
Claude Code/Codex.
|
||||
|
||||
По подразбиране MCP използва компактни входни схеми, за да заема по-малко от
|
||||
контекста. Задайте `REA_MCP_INPUT_SCHEMA_PROFILE=full` в MCP регистрацията си,
|
||||
когато са ви нужни пълните описания на полетата и подробностите за вложената
|
||||
валидация. И двата профила запазват пълния набор от инструменти и каноничната
|
||||
валидация на сървъра. Вижте „Compact input schema profile“ в ръководството за MCP
|
||||
договорите.
|
||||
|
||||
По подразбиране се обявяват пълните изходни схеми. Ако клиентът ви ограничава
|
||||
размера на цялата рамка `tools/list`, задайте
|
||||
`REA_MCP_OUTPUT_SCHEMA_PROFILE=compact`, за да ограничите всяка обявена изходна
|
||||
схема, или `off`, за да пропуснете изходните схеми изцяло. И двете настройки
|
||||
запазват каноничната валидация от страна на сървъра и пълните структурирани
|
||||
резултати. Вижте „Output schemas“ в ръководството за MCP договорите.
|
||||
|
||||
### Попитайте агента си
|
||||
|
||||
```text
|
||||
Разбери как работи търсенето в приложението Notes, покажи ми доказателствата и
|
||||
изгради подобна функция за моя проект.
|
||||
```
|
||||
|
||||
Заменете Notes с целевото си приложение и функцията, която искате да разберете.
|
||||
|
||||
### Използвайте терминала
|
||||
|
||||
Изследвайте директорията на разархивирано JavaScript/Electron приложение или ASAR
|
||||
архив:
|
||||
|
||||
```bash
|
||||
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
|
||||
```
|
||||
|
||||
Резултатът включва модули, импорти, границите на Electron и доказателствата за
|
||||
тях. Заменете пътя с вашата цел, например `"D:/apps/example"` в Windows.
|
||||
|
||||
За да инсталирате командата `rea` за редовна употреба:
|
||||
|
||||
```bash
|
||||
npm install --global rea-agents
|
||||
rea --help
|
||||
```
|
||||
|
||||
За нативен анализ първо конфигурирайте доставчик на анализ. Вижте
|
||||
[ръководството за CLI и Evidence](../getting-started/cli.md) за нативните
|
||||
команди, избора на доставчик, моментните снимки (snapshots) и скриптирането.
|
||||
|
||||
### Обновяване на REA
|
||||
|
||||
REA се променя бързо и новите издания често съдържат поправки на грешки.
|
||||
Поддържайте инсталацията си актуална.
|
||||
|
||||
За CLI, инсталиран с `npm install --global` или `bun add --global`:
|
||||
|
||||
```bash
|
||||
rea update
|
||||
```
|
||||
|
||||
`rea --update` е псевдоним на същия проверен процес и приема същите глобални
|
||||
флагове за изхода. Използвайте `rea update`, когато го комбинирате с други опции
|
||||
на командата.
|
||||
|
||||
Командите за обновяване запазват общо най-много 4 MiB от stdout и stderr. Твърде
|
||||
големите отговори с метаданни се отхвърлят след приключване на командата;
|
||||
подробните (verbose) инсталации продължават с ограничена диагностика. Изходът за
|
||||
напредъка, предназначен за хора, се съобразява с обратното налягане
|
||||
(backpressure) на терминала и изчаква изпратените записи да завършат.
|
||||
|
||||
Глобалните обновявания чрез Bun изискват Bun 1.2.17 или по-нова версия. При
|
||||
по-стара версия първо обновете Bun ръчно и след това изпълнете `rea update`.
|
||||
|
||||
За да опресните регистрациите в агентите и умението (skill), изпълнете командата
|
||||
за настройка, която обновяването отпечатва.
|
||||
|
||||
Ако използвате `npx`, обновете настройката на агента си с:
|
||||
|
||||
```bash
|
||||
npx rea-agents@latest setup
|
||||
```
|
||||
|
||||
Прегледайте промените от настройката и рестартирайте агента. За еднократни CLI
|
||||
команди използвайте `npx rea-agents@latest`, последвано от командата. С Bun
|
||||
използвайте `bunx rea-agents@latest` вместо `npx rea-agents@latest`.
|
||||
|
||||
## Как работи REA
|
||||
|
||||
Агентът ви извиква REA чрез MCP, за да изследва целта и да проследи съответния
|
||||
код. REA връща констатации заедно с доказателствата за тях. Агентът ги използва,
|
||||
за да задава допълнителни въпроси, да обяснява поведението или да напише и тества
|
||||
реализация. CLI командите използват същите работни процеси.
|
||||
|
||||

|
||||
|
||||
[Отворете фигурата в пълен размер](../../website/public/assets/figures/rea-investigation-flow.svg).
|
||||
|
||||
<a id="current-status"></a>
|
||||
|
||||
## Какво можете да анализирате
|
||||
|
||||
REA изисква Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) или 26.12.1+, както и
|
||||
npm. Допълнителните инструменти и поддържаните операционни системи зависят от
|
||||
целта:
|
||||
|
||||
| Цел | Какво връща REA | Изисквания и ръководство |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Инсталирани настолни приложения | Кандидати за среда за изпълнение, поддържащи файлове, маркери на компоненти и следващи проверки | Вградена ограничена проверка на директории и заглавни части; [настолни приложения](../desktop-applications.md) |
|
||||
| Нативни бинарни файлове | Псевдокод, асемблер, низове, символи, извиквания и препратки | Hopper, Ghidra, IDA или Kuna; [нативен анализ](../guides/native/native-investigation.md) |
|
||||
| Структура на ELF (офлайн) | Секции, сегменти, оригинални символи/релокации и кандидати за статични защитни механизми | Предоставен от вас pwntools на Linux x64; [диагностика на бинарни файлове](../guides/native/binary-diagnostics.md) |
|
||||
| Go бинарни файлове | Вградена версия на компилатора, модули, замени и настройки на компилацията | Вградена статична проверка на ELF/PE/thin Mach-O; не изисква инсталиран Go |
|
||||
| GPU кодови обекти | CUDA/HIP цели, избрани параметри и ресурси на ядрата, запазен PTX текст | Вградена статична проверка на ELF/PE/fatbin/CUBIN/PTX; [GPU кодови обекти](../gpu-code-objects.md) |
|
||||
| Файлове на модели | Метаданни на GGUF / safetensors, декларации на тензори и изчислени общи стойности | Вградена проверка на заглавните части; по желание хеш на целия файл; [файлове на модели](../model-artifacts.md) |
|
||||
| IL2CPP метаданни | Образи на асемблита от Unity global-metadata.dat, имена на типове и методи и диапазони на индекси | Вградено статично декодиране на версии 24, 27, 29, 31 и 39; не изисква Unity |
|
||||
| Godot PCK | Опис и извличане на архива, оригинални данни от заглавната част и директорията и идентичност на избрано съдържание | Вградена статична поддръжка на формати 2, 3 и 4; не изисква Godot |
|
||||
| Rust бинарни файлове | Вградени от cargo-auditable имена на crate-ове, версии, източници и връзки между зависимостите | Вградена статична проверка на ELF/PE/thin Mach-O; [Rust бинарни файлове](../rust-binaries.md) |
|
||||
| PE сертификати | Записи Authenticode WIN_CERTIFICATE и полета за самоличност на подписващия от PKCS#7/X.509 | Вградена статична проверка на PE; [PE сертификати](../pe-certificates.md) |
|
||||
| PE импорти | Имена на импортирани и отложено зареждани (delay-load) DLL библиотеки, ординали, IAT RVA адреси и pefile хеш на импортите | Вградена статична проверка на PE; [PE импорти](../pe-imports.md) |
|
||||
| Windows преки пътища | Цел, аргументи, работна директория и данни от Shell Link | Вградена статична проверка на LNK; [Windows преки пътища](../guides/native/windows-shortcut.md) |
|
||||
| ELF бележки | Собственици и типове на PT_NOTE/SHT_NOTE, полета GNU build-id и ABI-tag | Вградена статична проверка на ELF; [ELF бележки](../elf-notes.md) |
|
||||
| Защита на бинарни файлове | PIE, NX, RELRO, CFG и свързаните с тях флагове в заглавните части на ELF, PE и Mach-O | Вградена статична проверка на заглавните части; [защита на бинарни файлове](../binary-hardening.md) |
|
||||
| Сривове на Apple (IPS) | Метаданни от .ips, нишки, образи, регистри и документирани класове сривове | Вградена статична проверка на JSON; [Apple IPS](../apple-ips.md) |
|
||||
| Модули на ядрото на Linux | Ключове от .modinfo, CRC стойности от __versions, наличие на this_module и подпис в края на файла | Вградена статична проверка на ELF; [модули на ядрото](../kernel-modules.md) |
|
||||
| Erlang BEAM | IFF блокове (chunks), атоми, експорти, импорти, ламбди и заглавната част Code | Вградена статична проверка на BEAM; [Erlang BEAM](../erlang-beam.md) |
|
||||
| WASM артефакти | Валидация, секции, точни WAT форми на импортите/експортите и декодиран WAT | Предоставен от вас WABT 1.0.42; `inspect_wasm_artifact` |
|
||||
| EVM байткод | Селектори на функции, отмествания в байтове, изведени аргументи и променливост (mutability) | Локален raw/hex носител на Linux x64; [ръководство за офлайн EVM](../guides/evm/evm-bytecode.md) |
|
||||
| SQLite бази данни | Таблици, колони, индекси, изгледи, тригери и избрани редове от обикновени таблици | Локална моментна снимка на базата/WAL; Node.js 24.x >=24.15 или 26+ с нативни ограничения на SQLite |
|
||||
| Записани сривове в Linux | Сурови бележки, регистри/сигнали на всяка записана нишка и по желание кандидати за съпоставяне с файлове в паметта | Предоставен от вас pwntools на Linux x64; по желание GDB/pwndbg; [записани сривове](../guides/native/recorded-crashes.md) |
|
||||
| JavaScript / Electron | Модули, импорти, source maps, маршрути, IPC и връзки с нативни добавки | Node.js и npm; Linux: съвместима с procps команда `ps`; [анализ на приложения](../guides/javascript/javascript-application-workflows.md) |
|
||||
| Уебсайтове | Структура на страниците, скриптове, мрежови наблюдения и заявени екранни снимки | Браузър от семейството на Chrome; [анализ в браузъра](../guides/web/browser-observation.md) |
|
||||
| Запазени мрежови записи | Заявки, отговори, открити полезни данни (payloads) и местоположения в изходния код | HAR или Fiddler Everywhere SAZ; mitmdump на Linux за нативен mitmproxy; [ръководство за мрежови записи](../guides/web/web-network-captures.md) |
|
||||
| .NET асемблита | Метаданни, CIL инструкции, декларирани нативни зависимости и сравнения между компилации | Няма (само статичен анализ); [ръководство за управляван код](../guides/managed/managed-code-analysis.md) |
|
||||
| Android APK файлове | Декларации в манифеста, класове, декомпилирани методи и препратки | JADX без графичен интерфейс и пълен JDK на Linux/macOS/Windows x64; [ръководство за Android](../guides/android/android-analysis.md) |
|
||||
| Подписи на APK | Подписващи v1/v2/v3/v3.1, отпечатъци на сертификати, ротация на ключове и вътрешна съгласуваност на хешовете | Няма (само статичен анализ); `inspect_apk_signature` |
|
||||
| Android устройства | Устройства, пакети, процеси, логове, дъмпове, екранни снимки и прехвърляне на APK/файлове | Предоставен от вас adb (емулатор или физическо устройство); [ръководство за ADB](../guides/android/adb-device-analysis.md) |
|
||||
| JEB проекти | Единици на проекта от двигателя на JEB, хешове на артефакти и псевдокод на типове/методи | Стартиран от вас JEB клиент, който обслужва MCP и е избран чрез REA_JEB_MCP_URL; [ръководство за JEB](../providers/jeb-analysis.md) |
|
||||
| Android ресурси | Декодиран манифест, таблици с низове, локали и данни за версията | Предоставен от вас стартер за Apktool; [ръководство за ресурси](../guides/android/apktool-resource-analysis.md) |
|
||||
| Flutter приложения | Хеш на Dart snapshot, хешове на библиотеките за всяко ABI и произход на компилацията на двигателя | Няма (статичен анализ на APK); [ръководство за Flutter](../guides/android/flutter-analysis.md) |
|
||||
| Фърмуер | Региони, резултати от извличането и предаване към нативен анализ | Binwalk / Unblob на Linux; [ръководство за фърмуер](../guides/firmware/firmware-analysis.md) |
|
||||
| Записани пакети | Избрани полета, повтарящи се стойности, филтри и правила decode-as | Linux: TShark 4.x + prlimit; [ръководство за записи](../guides/data/packet-captures.md) |
|
||||
| Обобщения на пакети | Крайни точки, DNS, TLS SNI, разпределение по протоколи и HTTP заявки | Предоставени от вас tshark и capinfos (проверено на Linux); [ръководство за pcap](../guides/data/pcap-analysis.md) |
|
||||
| Записани логически сигнали | Анотации от декодерите, диапазони от семпли и диагностика | Linux: sigrok-cli 0.7.2 + prlimit; [записи на сигнали](../guides/signals/signal-recordings.md) |
|
||||
| Пакети и ресурси | Описи на файлове, хешове, plist файлове, устройство на Apple пакети (bundles) и извлечени ресурси | [Ръководство за артефакти и JavaScript](../guides/javascript/javascript-artifact-reconstruction.md), [Apple приложения](../guides/apple/apple-application-analysis.md) |
|
||||
| Поведение на процеси | Изход в терминала, взаимодействия, наблюдения на изхода от процеса и на файловата система и сравнения между изпълнения | Linux/macOS с нативен PTY; [запис на процеси](../guides/runtime/process-capture.md) |
|
||||
| PyInstaller изпълними файлове | Членове на CArchive, версия на Python, входни скриптове и извлечен байткод | Няма (само статичен анализ); [пакетирани Python приложения](../python-packaged-applications.md) |
|
||||
| Изпълними файлове на Deno | Виртуални файлове, входна точка, опции и размер на npm снимката | Няма (само статичен анализ); [изпълними файлове на Deno](../deno-standalone.md) |
|
||||
|
||||
Статичната проверка на JavaScript и .NET чете предоставените файлове, без да
|
||||
стартира приложението. Записът по време на изпълнение стартира избраната цел или
|
||||
взаимодейства с нея с правата на вашия потребител; всяко ръководство за анализ по
|
||||
време на изпълнение описва какво точно прави.
|
||||
|
||||
За офлайн проверка на нативни бинарни файлове REA поддържа и предоставени от вас
|
||||
GNU objdump и Rizin. Вижте
|
||||
[ръководството за инструменти за обратно инженерство](../reverse-engineering-tools.md)
|
||||
за настройка на доставчиците, CLI командите и ограниченията на Evidence. REA не
|
||||
инсталира и не обновява нито един от двата доставчика.
|
||||
|
||||
<a id="choosing-a-deep-analysis-provider"></a>
|
||||
|
||||
Поддържаните нативни формати и операционни системи зависят от доставчика. Вижте
|
||||
[настройката на Hopper и Ghidra](../getting-started/installation.md#hopper),
|
||||
[ръководството за IDA](../providers/ida-provider.md) (включително незадължителен
|
||||
нативен MCP мост), [ръководството за декомпилатора Kuna](../kuna-provider.md) и
|
||||
[експерименталната поддръжка на Ghidra за Windows](../providers/windows-ghidra-p0.md).
|
||||
Ghidra поддържа и [анализ на 16-битов DOS код](../providers/ghidra-dos.md). За
|
||||
големи бинарни файлове увеличете времето за стартиране на доставчика с
|
||||
`REA_GHIDRA_STARTUP_TIMEOUT_MS` или `REA_HOPPER_STARTUP_TIMEOUT_MS`. За избора
|
||||
на доставчик вижте [ръководството за CLI](../getting-started/cli.md#choose-a-provider).
|
||||
Проверете [наличността в изданията](../getting-started/installation.md#released-package-and-main)
|
||||
за функции, добавени след последното издание в npm.
|
||||
|
||||
## Примери
|
||||
|
||||
<a href="https://rea.tools/showcase/">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="../assets/rea-showcases-dark.svg" />
|
||||
<img alt="Илюстрации на примерите DX-Ball (звукова панорама), Notion (мост за клипборда) и TH04 (пръстен от куршуми)" src="../assets/rea-showcases.svg" />
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
### DX-Ball: реконструиране на изчислението на звуковата панорама
|
||||
|
||||
Проследете извикване на звук до помощната функция, която превръща позицията в
|
||||
панорама, изследвайте инструкциите и превърнете непълния псевдокод в C.
|
||||
Реконструкцията минава 3 205 тестови случая спрямо оригиналния x86 код и
|
||||
възпроизвежда всичките 63 байта на компилираната функция.
|
||||
|
||||
[Прочетете казуса](https://rea.tools/showcase/dx-ball/) ·
|
||||
[Хранилище с реконструкцията](https://github.com/N0zoM1z0/dx-ball)
|
||||
|
||||
### Notion: проследяване на моста за клипборда в Electron
|
||||
|
||||
Открийте API-то за клипборда в renderer процеса, проследете го през preload
|
||||
скрипта и IPC до главния процес и изследвайте формата за форматирано съдържание
|
||||
в клипборда.
|
||||
|
||||
[Прочетете казуса](https://rea.tools/showcase/notion/)
|
||||
|
||||
### TH04: възстановяване на изчислението на пръстена от куршуми в DOS
|
||||
|
||||
Изследвайте 16-битовите инструкции на оригиналната игра за PC-98, възстановете
|
||||
изчисленията на фиксираните и насочените ъгли и сравнете реконструирания C++ код
|
||||
с изхода на историческия компилатор.
|
||||
|
||||
[Прочетете казуса](https://rea.tools/showcase/th04/) ·
|
||||
[Хранилище с реконструкцията](https://github.com/N0zoM1z0/th04)
|
||||
|
||||
### Създавайте RL среди с REA
|
||||
|
||||
Запишете сесия в уеб приложение, превърнете неговото API в инструменти и експортирайте среда, която AI агент може да използва. Стартирайте я с AgentEnv, след което добавете задачи и проверки за награда за RL обучение или оценка.
|
||||
|
||||
[Прочетете ръководството](https://rea.tools/guides/rl-environments/) ·
|
||||
[Гледайте видеото](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
Ако сте използвали REA за нещо интересно, ще се радваме да го видим. Споделете
|
||||
случая си в [issue](https://github.com/morluto/rea/issues) или
|
||||
[pull request](https://github.com/morluto/rea/pulls), като включите целта,
|
||||
въпроса си, как ви помогна REA и какво открихте.
|
||||
|
||||
<a id="build-rl-environments"></a>
|
||||
|
||||
## Създаване на RL среди
|
||||
|
||||
Дайте на AI агент локална среда, в която да упражнява задачи като намиране на issue или създаване на папка, без да стартира оригиналното приложение. Използвайте я за обучение с подсилване (reinforcement learning, RL) или за да проверите колко добре агентът изпълнява задачи.
|
||||
|
||||
REA превръща записаните API заявки и отговори в инструменти, които агентът може да извиква. Средата използва записаните данни и поддържа промени само когато записът потвърждава ефекта им.
|
||||
|
||||
След като REA е настроен в агента ви, заменете примерния URL адрес и задачите с папки по-долу със свои:
|
||||
|
||||
```text
|
||||
Използвай REA, за да изградиш RL среда от тестовото ми уеб приложение на
|
||||
http://127.0.0.1:3000.
|
||||
Обхвани извеждането на списък, създаването, преименуването и изтриването на
|
||||
папки. Можеш да създаваш и премахваш тестови папки. Не променяй съществуващите
|
||||
данни.
|
||||
Запази я в папка с име my-env. Провери кои операции работят и ми кажи как да я
|
||||
стартирам.
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Използвайте командния ред вместо това</summary>
|
||||
|
||||
Използвайте тези команди, ако вече имате файл със записаните от браузъра заявки и отговори на приложението. За да стартирате резултата, са нужни и AgentEnv, и Docker.
|
||||
|
||||
```sh
|
||||
rea environment-build ./session.har ./my-env --name my-env --json
|
||||
agent-env run ./my-env
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
REA експортира готова за стартиране среда с базов тест, който проверява дали тя стартира и отговаря. Използвайте я с вашата RL рамка, за да зададете целите на задачите, да добавите проверки за награда и да стартирате обучението.
|
||||
|
||||
[Изградете среда](https://rea.tools/guides/rl-environments/) ·
|
||||
[Справочник за средите](../agent-environments.md) ·
|
||||
[Гледайте демонстрацията в X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Среди за настолни приложения
|
||||
|
||||
REA може да създаде среда за Linux настолно приложение: агентът го управлява чрез снимки на екрана, мишка и клавиатура. От кратка заявка агентът инсталира приложението, създава задача, експортира средата и я проверява на нов компютър. За изграждането са необходими Linux на amd64 или arm64, Docker и версията на agentenv, посочена в ръководството.
|
||||
|
||||
[Настройка на среди за настолни приложения](../desktop-build-computer.md)
|
||||
|
||||
## Често задавани въпроси
|
||||
|
||||
<details>
|
||||
<summary><strong>Кои агенти могат да използват REA?</strong></summary>
|
||||
|
||||
Всеки агент, който поддържа локални MCP сървъри. Настройката конфигурира
|
||||
[поддържаните агенти](../getting-started/installation.md#supported-agents);
|
||||
другите клиенти могат да използват
|
||||
[ръчна MCP регистрация](../getting-started/installation.md#mcp-registry).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Нужен ли ми е двигател за нативен анализ?</strong></summary>
|
||||
|
||||
Задълбоченият нативен анализ използва Hopper, Ghidra, IDA или Kuna в зависимост
|
||||
от целта и операцията. Статичната проверка на JavaScript и .NET работи без
|
||||
двигател за нативен анализ. Настройката може да инсталира Hopper след ваше
|
||||
одобрение; Ghidra, IDA и Kuna се използват от вече съществуващите ви инсталации.
|
||||
Вижте [настройката на доставчиците](../getting-started/installation.md#hopper)
|
||||
за възможностите и поддържаните от тях цели.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Трябва ли първо да стартирам Hopper?</strong></summary>
|
||||
|
||||
REA стартира Hopper, когато дадена операция се нуждае от него. В macOS при първо
|
||||
стартиране може да се появи диалогов прозорец, който ви пита дали да изберете
|
||||
демо режим, или да активирате лиценза си. Завършете този диалог в същата
|
||||
потребителска сесия преди първата си CLI/MCP операция или задача, която ще се
|
||||
изпълнява без надзор. При нужда отворете Hopper ръчно. Вижте
|
||||
[стартиране и отстраняване на проблеми с Hopper](../getting-started/installation.md#launcher-paths-and-troubleshooting).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Какво прави инсталирането на умението (skill) от skills.sh?</strong></summary>
|
||||
|
||||
Умението дава на агента ви инструкции как да провежда изследвания. Използвайте
|
||||
`npx rea-agents setup`, за да регистрирате MCP сървъра на REA и да инсталирате
|
||||
съответните инструкции, след което рестартирайте агента. Вижте
|
||||
[инсталиране само на умението](../getting-started/installation.md#skill-only-installation).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Какъв код връща REA?</strong></summary>
|
||||
|
||||
Нативният анализ връща псевдокод и асемблер. Анализът на JavaScript/Electron
|
||||
възстановява модулите и връзките между тях. Агентът ви използва тези
|
||||
констатации, за да напише и тества реализация; [примерите](#примери) показват
|
||||
цялостни разработени случаи.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Качва ли REA приложението ми някъде?</strong></summary>
|
||||
|
||||
REA анализира целите локално. Агентът ви получава резултатите от инструментите,
|
||||
а доставчикът на модела, който агентът използва, има собствена политика за
|
||||
данните.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Какво да направя, ако попадна на грешка?</strong></summary>
|
||||
|
||||
Първо обновете; възможно е скорошно издание вече да я е поправило.
|
||||
|
||||
За CLI, инсталиран с `npm install --global` или `bun add --global`:
|
||||
|
||||
```bash
|
||||
rea update
|
||||
```
|
||||
|
||||
За настройка на агента чрез `npx`:
|
||||
|
||||
```bash
|
||||
npx rea-agents@latest setup
|
||||
```
|
||||
|
||||
Ако използвате агент, извършете
|
||||
[опресняването на настройката](#обновяване-на-rea) и го рестартирайте. Опитайте
|
||||
отново същата задача. Ако проблемът продължава,
|
||||
[отворете issue](https://github.com/morluto/rea/issues), като посочите версията
|
||||
на REA, типа на целта, стъпките за възпроизвеждане и изхода с грешката.
|
||||
|
||||
</details>
|
||||
|
||||
## Документация
|
||||
|
||||
Започнете с [практическите ръководства](https://rea.tools/guides/) на уебсайта.
|
||||
За точните опции, предварителните изисквания и договорите за резултатите:
|
||||
|
||||
- [Инсталиране и настройка](../getting-started/installation.md): регистриране на агенти, конфигуриране на доставчици, обновяване и деинсталиране.
|
||||
- [Готовност и отстраняване на проблеми](../getting-started/installation.md#check-readiness-for-your-task): диагностика на конкретен агент или двигател за анализ.
|
||||
- [CLI и Evidence](../getting-started/cli.md): команди, избор на доставчик, моментни снимки, импорт/експорт и изходни статуси.
|
||||
- [MCP договори](../reference/mcp-contracts.md) и [подсказки за агенти](../getting-started/mcp-prompts.md): резултати от инструментите, сесии и насочвани изследвания.
|
||||
- [Каталог с инструменти](../reference/mcp-contracts.md#generated-catalog): генериран списък с инструменти, доставчици и CLI команди.
|
||||
- [Пътна карта](../development/roadmap.md): планирана работа и проследяване на възможностите.
|
||||
|
||||
Съобщавайте за уязвимости чрез [SECURITY.md](../../SECURITY.md).
|
||||
|
||||
## История на звездите
|
||||
|
||||
🎉 **400 000 звезди в GitHub — благодарим ви!**
|
||||
|
||||
Благодарим на всички, които използват REA, съобщават за грешки, предлагат нови функции, тестват версии и допринасят с поправки.
|
||||
|
||||
<a href="https://www.star-history.com/?repos=morluto%2Frea&type=date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&type=date&theme=dark&legend=top-left" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&type=date" />
|
||||
<img alt="История на звездите на REA в GitHub" src="https://api.star-history.com/chart?repos=morluto/rea&type=date" />
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
## Отказ от отговорност
|
||||
|
||||
Вижте [DISCLAIMER.md](../../DISCLAIMER.md) за насоки за отговорна употреба.
|
||||
|
||||
Позицията на проекта относно незаконната или неразрешената употреба обхваща
|
||||
всички версии, канали за разпространение и платформи на REA; всяко копие запазва
|
||||
приложимите за него лицензи.
|
||||
|
||||
REA е предназначен за законни изследвания, обучение, оперативна съвместимост,
|
||||
съхраняване на софтуер и анализ на софтуер, който притежавате или имате
|
||||
разрешение да изследвате.
|
||||
|
||||
## Принос към проекта
|
||||
|
||||
Ще се радваме на помощта ви с REA! [Отворете issue](https://github.com/morluto/rea/issues),
|
||||
за да съобщите за грешка или да предложите функция, или
|
||||
[изпратете pull request](https://github.com/morluto/rea/pulls), за да подобрите
|
||||
кода или документацията.
|
||||
|
||||
Вижте [CONTRIBUTING.md](../../CONTRIBUTING.md) за настройка на средата за
|
||||
разработка и проверките, [тестване](../development/testing.md) за видовете
|
||||
проверки и [картата на архитектурата](../architecture/architecture.mermaid) за
|
||||
избрани слоеве и пътища на зависимостите.
|
||||
|
||||
## Лиценз
|
||||
|
||||
[MIT](../../LICENSE)
|
||||
|
||||
Кодът, написан за проекта REA, е лицензиран под MIT. Материалите от трети страни
|
||||
запазват собствените си лицензи и бележки за авторски права; вижте
|
||||
[бележките за трети страни](../../THIRD_PARTY_NOTICES.md) за списъка със
|
||||
зависимости, запазените текстове на лицензите и условията на външните
|
||||
инструменти.
|
||||
|
||||
**Трябва да сте придобили законно търговските инструменти и да имате право да ги
|
||||
използвате**, включително IDA Pro / декомпилаторите на Hex-Rays, Hopper и JEB,
|
||||
съгласно приложимите им лицензи. REA не предоставя лиценз, ключ или право на
|
||||
активиране за нито един инструмент. Пробните и демо версиите остават обект на
|
||||
условията на производителя, включително ограниченията за брой потребители,
|
||||
функции, автоматизация и споделяне на резултатите. Кракнати копия, откраднати
|
||||
ключове, неразрешено споделяне на ключове и заобикаляне на лицензионни
|
||||
ограничения не са разрешени. Тези насоки не изменят лиценза MIT или лицензите на
|
||||
трети страни.
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · **Deutsch** · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Alles reverse-engineeren
|
||||
|
||||
@@ -84,6 +84,10 @@ Die Einrichtung unterstützt Claude Code, Codex, Cursor, Gemini CLI, Grok Build
|
||||
|
||||
MCP verwendet standardmäßig kompakte Eingabeschemas. Für vollständige Feldhinweise und Details zur verschachtelten Validierung setze `REA_MCP_INPUT_SCHEMA_PROFILE=full` in der MCP-Registrierung. Beide Profile behalten alle Tools und dieselbe kanonische Servervalidierung; siehe MCP-Vertragsleitfaden.
|
||||
|
||||
Die Einrichtung registriert die gewählte Laufzeit und das REA-Einstiegsskript direkt. Bewahre bei einem Paket-Runner dessen Cache-Eintrag und die Laufzeit auf; lade das Paket aus einem vertrauenswürdigen Verzeichnis außerhalb des Zielprojekts. Siehe die Installationsanleitung.
|
||||
|
||||
Vollständige Ausgabeschemas werden standardmäßig angekündigt. Begrenzt dein Client `tools/list`, setze in der MCP-Registrierung `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` oder `off`. Servervalidierung und strukturierte Ergebnisse bleiben vollständig. Siehe „Output schemas“ im MCP-Vertragsleitfaden.
|
||||
|
||||
### Deinen Agenten fragen
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ REA benötigt Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) oder 26+ (>=26.12.1) so
|
||||
| Offline-ELF-Struktur | Sektionen, Segmente, ursprüngliche Symbole/Relokationen und mögliche Schutzmaßnahmen aus statischer Analyse | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; [Binärdiagnostik](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| EVM-Bytecode | Dispatch-Selektoren, Byte-Offsets, abgeleitete Argumente und Veränderbarkeit des Zustands | Lokale Eingabe mit Rohbytes oder Hexdarstellung unter Linux x64; [Offline-EVM-Leitfaden](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -172,6 +177,7 @@ REA benötigt Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) oder 26+ (>=26.12.1) so
|
||||
| Paketerfassungen | Endpunkte, DNS, TLS SNI, Protokollverteilung und HTTP-Anfragen | Vom Aufrufer bereitgestellte tshark- und capinfos-Binaries; [pcap-Leitfaden](../guides/data/pcap-analysis.md) |
|
||||
| .NET-Assemblies | Metadaten, CIL-Anweisungen, deklarierte native Abhängigkeiten und Build-Vergleiche | Statische Untersuchung; [Leitfaden für verwalteten Code](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Android-APKs | Manifest-Deklarationen, Klassen, dekompilierte Methoden und Verweise | JADX ohne grafische Oberfläche und ein vollständiges JDK unter Linux/macOS/Windows x64; [Android-Leitfaden](../guides/android/android-analysis.md) |
|
||||
| Android-Geräte | Geräte, Pakete, Prozesse, Logs, Dumps, Bildschirmaufnahmen sowie APK- und Dateiübertragungen | Vom Aufrufer bereitgestelltes adb (Emulator oder Gerät); [ADB-Leitfaden](../guides/android/adb-device-analysis.md) |
|
||||
| JEB-Projekte | Engine-gestützte Projekteinheiten, Artefakt-Prüfsummen und Pseudokode von Typen/Methoden | Ein vom Aufrufer gestarteter JEB-Client mit MCP, ausgewählt über REA_JEB_MCP_URL; [JEB-Leitfaden](../providers/jeb-analysis.md) |
|
||||
@@ -273,6 +279,12 @@ REA exportiert eine lauffähige Umgebung mit einem einfachen Test, der prüft, o
|
||||
[Umgebungsreferenz](../agent-environments.md) ·
|
||||
[Demo auf X ansehen](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Desktop-App-Umgebungen
|
||||
|
||||
REA kann auch eine Umgebung für eine Linux-Desktop-App erstellen, die ein Agent über Screenshots, Maus und Tastatur bedient. Aus einer einzeiligen Anfrage wie „Erstelle mir eine Gnote-Umgebung, in der der Agent der Einkaufslisten-Notiz Olivenöl hinzufügt“ installiert dein Agent die App auf einem lokalen Build-Computer, schreibt die Aufgabe, exportiert die Umgebung und prüft die Aufgabe auf einem frischen Computer. Der Rechner, der sie erstellt, braucht Linux auf amd64 oder arm64, Docker und die Version des agentenv-Frameworks, die der Leitfaden festlegt.
|
||||
|
||||
[Desktop-App-Umgebungen einrichten](../desktop-build-computer.md)
|
||||
|
||||
## Häufige Fragen
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md) · **Ελληνικά** · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md) · **Ελληνικά** · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -86,6 +86,10 @@ npx rea-agents setup
|
||||
|
||||
Το MCP χρησιμοποιεί συμπαγή σχήματα εισόδου από προεπιλογή. Για πλήρεις οδηγίες πεδίων και ένθετης επικύρωσης, όρισε `REA_MCP_INPUT_SCHEMA_PROFILE=full` στην καταχώριση MCP. Και τα δύο προφίλ διατηρούν όλα τα εργαλεία και την ίδια κανονική επικύρωση διακομιστή· δες τον οδηγό συμβολαίων MCP.
|
||||
|
||||
Η εγκατάσταση καταχωρίζει απευθείας τον επιλεγμένο runtime και το αρχικό script του REA. Αν χρησιμοποιείς package runner, διατήρησε την καταχώριση cache και τον runtime· απόκτησε το πακέτο από έμπιστο κατάλογο έξω από το έργο-στόχο. Δες τον οδηγό εγκατάστασης.
|
||||
|
||||
Τα πλήρη σχήματα εξόδου ανακοινώνονται από προεπιλογή. Αν ο client περιορίζει το `tools/list`, όρισε `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` ή `off` στην καταχώριση MCP. Η επικύρωση του διακομιστή και τα δομημένα αποτελέσματα παραμένουν πλήρη. Δες το «Output schemas» στον οδηγό συμβάσεων MCP.
|
||||
|
||||
### Ζήτησε από τον agent σου
|
||||
|
||||
```text
|
||||
@@ -159,6 +163,7 @@ npx rea-agents@latest setup
|
||||
| Δυαδικά αρχεία Rust | Ενσωματωμένα ονόματα, εκδόσεις, πηγές και σχέσεις εξάρτησης των crates από το cargo-auditable | Ενσωματωμένη στατική εξέταση ELF/PE/thin Mach-O· [δυαδικά αρχεία Rust](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../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](../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](../binary-hardening.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
@@ -174,6 +179,7 @@ npx rea-agents@latest setup
|
||||
| Αποθηκευμένες καταγραφές δικτύου | Αιτήματα, αποκρίσεις, διαθέσιμα δεδομένα φορτίου και θέσεις στην πηγή | HAR ή SAZ του Fiddler Everywhere· mitmdump σε Linux για την εγγενή μορφή mitmproxy· [οδηγός καταγραφών](../guides/web/web-network-captures.md) |
|
||||
| Assemblies .NET | Μεταδεδομένα, εντολές CIL, δηλωμένες εξαρτήσεις από κώδικα μηχανής και συγκρίσεις builds | Καμία πρόσθετη απαίτηση (μόνο στατική ανάλυση)· [οδηγός διαχειριζόμενου κώδικα](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| APK Android | Δηλώσεις manifest, κλάσεις, απομεταγλωττισμένες μέθοδοι και αναφορές | JADX χωρίς γραφικό περιβάλλον και πλήρες JDK σε Linux/macOS/Windows x64· [οδηγός Android](../guides/android/android-analysis.md) |
|
||||
| Συσκευές Android | Συσκευές, πακέτα, διεργασίες, logs, dumps, στιγμιότυπα οθόνης και μεταφορές APK/αρχείων | adb που παρέχει ο χρήστης (εξομοιωτής ή φυσική συσκευή)· [οδηγός ADB](../guides/android/adb-device-analysis.md) |
|
||||
| Έργα JEB | Μονάδες έργου από τη μηχανή ανάλυσης, ψηφιακά αποτυπώματα αρχείων και ψευδοκώδικα τύπων/μεθόδων | Client JEB που έχει ξεκινήσει ο χρήστης και παρέχει MCP, επιλεγμένος μέσω REA_JEB_MCP_URL· [οδηγός JEB](../providers/jeb-analysis.md) |
|
||||
@@ -275,6 +281,12 @@ agent-env run ./my-env
|
||||
[Αναφορά περιβαλλόντων](../agent-environments.md) ·
|
||||
[Δείτε το demo στο X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Περιβάλλοντα εφαρμογών επιφάνειας εργασίας
|
||||
|
||||
Το REA μπορεί επίσης να δημιουργήσει περιβάλλον για μια εφαρμογή επιφάνειας εργασίας Linux, την οποία ο πράκτορας χρησιμοποιεί μέσω στιγμιότυπων οθόνης, ποντικιού και πληκτρολογίου. Από ένα αίτημα μίας γραμμής, όπως «Φτιάξε μου ένα περιβάλλον Gnote όπου ο πράκτορας προσθέτει ελαιόλαδο στη σημείωση με τη λίστα αγορών», ο πράκτοράς σας εγκαθιστά την εφαρμογή σε έναν τοπικό υπολογιστή κατασκευής, γράφει την εργασία, εξάγει το περιβάλλον και ελέγχει την εργασία σε έναν νέο υπολογιστή. Ο υπολογιστής που το κατασκευάζει χρειάζεται Linux σε amd64 ή arm64, Docker και την έκδοση του πλαισίου agentenv που ορίζει ο οδηγός.
|
||||
|
||||
[Ρύθμιση περιβαλλόντων εφαρμογών επιφάνειας εργασίας](../desktop-build-computer.md)
|
||||
|
||||
## Συχνές ερωτήσεις
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · **Español** · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Ingeniería inversa de cualquier cosa
|
||||
|
||||
@@ -84,6 +84,10 @@ La configuración admite Claude Code, Codex, Cursor, Gemini CLI, Grok Build y [o
|
||||
|
||||
MCP usa esquemas de entrada compactos por defecto. Para ver todas las instrucciones de campos y la validación anidada, establece `REA_MCP_INPUT_SCHEMA_PROFILE=full` en el registro MCP. Ambos perfiles conservan todas las herramientas y la misma validación canónica del servidor; consulta la guía de contratos MCP.
|
||||
|
||||
La configuración registra directamente el entorno de ejecución elegido y el script de entrada de REA. Si usas un ejecutor de paquetes, conserva su entrada de caché y el entorno de ejecución; descarga el paquete desde un directorio de confianza fuera del proyecto objetivo. Consulta la guía de instalación.
|
||||
|
||||
Los esquemas de salida completos se anuncian por defecto. Si tu cliente limita `tools/list`, establece `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` o `off` en el registro MCP. La validación del servidor y los resultados estructurados siguen siendo completos. Consulta «Output schemas» en la guía de contratos MCP.
|
||||
|
||||
### Pregunta a tu agente
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ REA requiere Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), adem
|
||||
| Estructura ELF sin ejecutar | Secciones, segmentos, símbolos/reubicaciones originales y posibles medidas de mitigación detectadas mediante análisis estático | pwntools proporcionado por quien llama, en Linux x64; [diagnóstico de binarios](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| Bytecode EVM | Selectores de despacho, desplazamientos en bytes, argumentos inferidos y mutabilidad | Entrada local con bytes sin procesar o representación hexadecimal, en Linux x64; [guía de EVM sin ejecutar](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -172,6 +177,7 @@ REA requiere Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), adem
|
||||
| Capturas de paquetes | Endpoints, DNS, TLS SNI, distribución de protocolos y solicitudes HTTP | tshark y capinfos suministrados por el autor de la llamada; [guía pcap](../guides/data/pcap-analysis.md) |
|
||||
| Ensamblados .NET | Metadatos, instrucciones CIL, dependencias nativas declaradas y comparaciones de compilaciones | Inspección estática; [guía de código administrado](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| APK de Android | Declaraciones del manifiesto, clases, métodos descompilados y referencias | JADX sin interfaz gráfica y un JDK completo en Linux/macOS/Windows x64; [guía de Android](../guides/android/android-analysis.md) |
|
||||
| Dispositivos Android | Dispositivos, paquetes, procesos, registros, volcados, capturas de pantalla y transferencias de APK/archivos | adb suministrado por el autor de la llamada (emulador o dispositivo); [guía de ADB](../guides/android/adb-device-analysis.md) |
|
||||
| Proyectos JEB | Unidades de proyecto del motor, resúmenes de artefactos y pseudocódigo de tipos/métodos | Un cliente JEB iniciado por el autor de la llamada que sirve MCP, seleccionado con REA_JEB_MCP_URL; [guía de JEB](../providers/jeb-analysis.md) |
|
||||
@@ -273,6 +279,12 @@ REA exporta un entorno ejecutable con una prueba básica que comprueba que arran
|
||||
[Referencia de entornos](../agent-environments.md) ·
|
||||
[Ver la demo en X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Entornos de aplicaciones de escritorio
|
||||
|
||||
REA también puede crear un entorno de una aplicación de escritorio de Linux, que un agente usa mediante capturas de pantalla, el ratón y el teclado. A partir de una petición de una línea, como «Créame un entorno de Gnote en el que el agente añada aceite de oliva a la nota de la lista de la compra», tu agente instala la aplicación en un ordenador de compilación local, escribe la tarea, exporta el entorno y comprueba la tarea en un ordenador nuevo. El equipo que lo crea necesita Linux en amd64 o arm64, Docker y la versión del framework agentenv que fija la guía.
|
||||
|
||||
[Configurar entornos de aplicaciones de escritorio](../desktop-build-computer.md)
|
||||
|
||||
## Preguntas frecuentes
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center" dir="rtl">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · **فارسی** · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: مهندسی معکوس هر چیزی
|
||||
|
||||
@@ -76,6 +76,10 @@ npx rea-agents setup
|
||||
|
||||
MCP بهطور پیشفرض از schema ورودی فشرده استفاده میکند. برای راهنمای کامل فیلدها و اعتبارسنجی تودرتو، در ثبت MCP مقدار `REA_MCP_INPUT_SCHEMA_PROFILE=full` را تنظیم کنید. هر دو حالت همهٔ ابزارها و اعتبارسنجی استاندارد یکسان سرور را نگه میدارند؛ راهنمای قراردادهای MCP را ببینید.
|
||||
|
||||
راهاندازی، محیط اجرای انتخابشده و اسکریپت ورودی REA را مستقیماً ثبت میکند. اگر از اجراکنندهٔ بسته استفاده میکنید، ورودی حافظهٔ پنهان و محیط اجرا را حفظ کنید؛ بسته را از پوشهای قابل اعتماد خارج از پروژهٔ هدف دریافت کنید. راهنمای نصب را ببینید.
|
||||
|
||||
طرحهای خروجی کامل بهطور پیشفرض اعلام میشوند. اگر کلاینت `tools/list` را محدود میکند، در ثبت MCP مقدار `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` یا `off` را تنظیم کنید. اعتبارسنجی سرور و نتایج ساختیافته کامل میمانند. بخش «Output schemas» در راهنمای قراردادهای MCP را ببینید.
|
||||
|
||||
### از ایجنت خود بپرسید
|
||||
|
||||
```text
|
||||
@@ -149,6 +153,7 @@ REA به Node.js 22.x (>=22.23.4)، 24.x (>=24.22.1) یا 26+ (>=26.12.1)، به
|
||||
| ساختار ELF آفلاین | بخشها، سگمنتها، نمادها و relocationهای اصلی و گزینههای احتمالی کاهش آسیبپذیری ایستا | pwntools تأمینشده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| بایتکد EVM | selectorهای dispatch، offsetهای بایتی، آرگومانهای استنباطشده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -163,6 +168,7 @@ REA به Node.js 22.x (>=22.23.4)، 24.x (>=24.22.1) یا 26+ (>=26.12.1)، به
|
||||
| دادههای ضبطشدهٔ شبکه | درخواستها، پاسخها، payloadهای آشکارشده و مکان آنها در منبع | HAR / Fiddler Everywhere SAZ؛ ابزار mitmdump در لینوکس برای ضبطهای بومی mitmproxy؛ [راهنمای ضبط شبکه](../guides/web/web-network-captures.md) |
|
||||
| اسمبلیهای .NET | فراداده، دستورالعملهای CIL، وابستگیهای بومی اعلامشده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریتشده](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| فایلهای APK اندروید | تعاریف Manifest، کلاسها، متدهای دیکامپایلشده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS/Windows x64؛ [راهنمای اندروید](../guides/android/android-analysis.md) |
|
||||
| دستگاههای اندروید | دستگاهها، بستهها، فرایندها، لاگها، دامپها، اسکرینشاتها و انتقال APK/فایل | adb تأمینشده توسط فراخوانکننده (شبیهساز یا دستگاه)؛ [راهنمای ADB](../guides/android/adb-device-analysis.md) |
|
||||
| پروژههای JEB | واحدهای پروژه از موتور، هشهای مصنوع و شبهکدِ نوع/متد | یک کلاینت JEB که توسط فراخوانکننده اجرا شده و MCP ارائه میدهد و با REA_JEB_MCP_URL انتخاب میشود؛ [راهنمای JEB](../providers/jeb-analysis.md) |
|
||||
@@ -265,6 +271,12 @@ REA محیطی آمادهٔ اجرا همراه با یک آزمون ساده ب
|
||||
[مرجع محیطها](../agent-environments.md) ·
|
||||
[نمایش را در X ببینید](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### محیطهای برنامههای دسکتاپ
|
||||
|
||||
REA میتواند برای یک برنامهٔ دسکتاپ Linux هم محیط بسازد که عامل با تصویر صفحه، ماوس و صفحهکلید از آن استفاده میکند. از یک درخواست یکخطی، مثل «یک محیط Gnote برایم بساز که در آن عامل روغن زیتون را به یادداشت فهرست خرید اضافه کند»، عامل شما برنامه را روی یک رایانهٔ ساخت محلی نصب میکند، کار را مینویسد، محیط را صادر میکند و کار را روی یک رایانهٔ تازه بررسی میکند. دستگاهی که آن را میسازد به Linux روی amd64 یا arm64، Docker و نسخهای از چارچوب agentenv که راهنما تعیین کرده نیاز دارد.
|
||||
|
||||
[راهاندازی محیطهای برنامههای دسکتاپ](../desktop-build-computer.md)
|
||||
|
||||
## پرسشهای متداول
|
||||
|
||||
<details><summary><strong>کدام ایجنتها میتوانند از REA استفاده کنند؟</strong></summary>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · **Français** · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA : rétro-ingénierie de tout
|
||||
|
||||
@@ -84,6 +84,10 @@ Setup prend en charge Claude Code, Codex, Cursor, Gemini CLI, Grok Build et [d'a
|
||||
|
||||
MCP utilise par défaut des schémas d’entrée compacts. Pour les descriptions complètes des champs et de la validation imbriquée, définissez `REA_MCP_INPUT_SCHEMA_PROFILE=full` dans l’enregistrement MCP. Les deux profils conservent tous les outils et la même validation canonique du serveur ; voir le guide des contrats MCP.
|
||||
|
||||
La configuration enregistre directement le runtime choisi et le script d’entrée de REA. Avec un exécuteur de paquets, conservez son entrée de cache et le runtime ; récupérez le paquet depuis un répertoire de confiance hors du projet cible. Consultez le guide d’installation.
|
||||
|
||||
Les schémas de sortie complets sont annoncés par défaut. Si votre client limite `tools/list`, définissez `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` ou `off` dans l’enregistrement MCP. La validation du serveur et les résultats structurés restent complets. Consultez « Output schemas » dans le guide des contrats MCP.
|
||||
|
||||
### Interroger votre agent
|
||||
|
||||
```text
|
||||
@@ -156,6 +160,7 @@ REA nécessite Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), ai
|
||||
| Structure ELF hors ligne | Sections, segments, symboles et relocations d'origine, et protections statiques candidates | pwntools fourni par l'utilisateur sous Linux x64 ; [diagnostics binaires](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| Artefact WASM | Validation, sections, formes WAT exactes d'import/export et WAT décodé | WABT 1.0.42 fourni par l'utilisateur ; `inspect_wasm_artifact` |
|
||||
| Bytecode EVM | Sélecteurs de dispatch, offsets en octets, arguments inférés et mutabilité | Fichier local brut ou hexadécimal sous Linux x64 ; [guide EVM hors ligne](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
@@ -172,6 +177,7 @@ REA nécessite Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), ai
|
||||
| Captures de paquets | Points de terminaison, DNS, TLS SNI, distribution des protocoles et requêtes HTTP | tshark et capinfos fournis par l'appelant ; [guide pcap](../guides/data/pcap-analysis.md) |
|
||||
| Assemblys .NET | Métadonnées, instructions CIL, dépendances natives déclarées et comparaisons de builds | Inspection statique ; [guide du code managé](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| APK Android | Déclarations du manifeste, classes, méthodes décompilées et références | JADX headless et un JDK complet sous Linux/macOS/Windows x64 ; [guide Android](../guides/android/android-analysis.md) |
|
||||
| Appareils Android | Appareils, paquets, processus, journaux, dumps, captures d'écran et transferts d'APK/fichiers | adb fourni par l'appelant (émulateur ou appareil) ; [guide ADB](../guides/android/adb-device-analysis.md) |
|
||||
| Projets JEB | Unités de projet fournies par le moteur, condensés d'artefacts et pseudo-code de types/méthodes | Un client JEB démarré par l'appelant servant MCP, sélectionné via REA_JEB_MCP_URL ; [guide JEB](../providers/jeb-analysis.md) |
|
||||
@@ -270,6 +276,12 @@ REA exporte un environnement exécutable avec un test de base qui vérifie qu’
|
||||
[Référence des environnements](../agent-environments.md) ·
|
||||
[Voir la démo sur X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Environnements d’applications de bureau
|
||||
|
||||
REA peut aussi créer un environnement pour une application de bureau Linux, qu’un agent utilise par captures d’écran, souris et clavier. À partir d’une demande d’une ligne, comme « Crée-moi un environnement Gnote où l’agent ajoute de l’huile d’olive à la note de liste de courses », votre agent installe l’application sur un ordinateur de construction local, rédige la tâche, exporte l’environnement et vérifie la tâche sur un ordinateur neuf. La machine qui le construit a besoin de Linux sur amd64 ou arm64, de Docker et de la version du framework agentenv fixée par le guide.
|
||||
|
||||
[Configurer les environnements d’applications de bureau](../desktop-build-computer.md)
|
||||
|
||||
## Questions fréquentes
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · **Bahasa Indonesia** · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Rekayasa Balik Apa Pun
|
||||
|
||||
@@ -84,6 +84,10 @@ Penyiapan mendukung Claude Code, Codex, Cursor, Gemini CLI, Grok Build, dan [age
|
||||
|
||||
MCP menggunakan skema input ringkas secara default. Untuk petunjuk bidang lengkap dan validasi bertingkat, atur `REA_MCP_INPUT_SCHEMA_PROFILE=full` pada pendaftaran MCP. Kedua profil mempertahankan semua alat dan validasi server kanonis yang sama; lihat panduan kontrak MCP.
|
||||
|
||||
Setup mencatat runtime yang dipilih dan skrip masuk REA secara langsung. Jika memakai package runner, pertahankan entri cache dan runtime tersebut; unduh paket dari direktori tepercaya di luar proyek target. Lihat panduan instalasi.
|
||||
|
||||
Skema keluaran lengkap diumumkan secara default. Jika klien membatasi `tools/list`, atur `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` atau `off` dalam registrasi MCP. Validasi server dan hasil terstruktur tetap lengkap. Lihat «Output schemas» di panduan kontrak MCP.
|
||||
|
||||
### Minta agen Anda
|
||||
|
||||
```text
|
||||
@@ -159,6 +163,7 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
|
||||
| Tata letak ELF offline | Bagian, segmen, simbol/relokasi asli, dan kandidat mitigasi statis | pwntools yang disediakan pemanggil pada Linux x64; [diagnostik biner](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| Artefak WASM | Validasi, bagian, bentuk WAT import/ekspor yang tepat, dan WAT yang didekode | WABT 1.0.42 yang disediakan pemanggil; `inspect_wasm_artifact` |
|
||||
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal di Linux x64; [panduan EVM offline](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
@@ -175,6 +180,7 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
|
||||
| Capturan paket | Endpoint, DNS, TLS SNI, distribusi protokol, dan permintaan HTTP | tshark dan capinfos buatan pemanggil; [panduan pcap](../guides/data/pcap-analysis.md) |
|
||||
| Assembly .NET | Metadata, instruksi CIL, dependensi native yang dideklarasikan, dan perbandingan build | Tidak ada (hanya analisis statis); [panduan kode terkelola](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| APK Android | Deklarasi manifest, kelas, metode hasil dekompilasi, dan referensi | JADX mode headless dan JDK lengkap di Linux/macOS/Windows x64; [panduan Android](../guides/android/android-analysis.md) |
|
||||
| Perangkat Android | Perangkat, paket, proses, log, dump, tangkapan layar, serta transfer APK/berkas | adb buatan pemanggil (emulator atau perangkat); [panduan ADB](../guides/android/adb-device-analysis.md) |
|
||||
| Proyek JEB | Unit proyek bertenaga mesin, hash artefak, dan pseudokode tipe/metode | Klien JEB yang dijalankan pemanggil dan menyajikan MCP, dipilih dengan REA_JEB_MCP_URL; [panduan JEB](../providers/jeb-analysis.md) |
|
||||
@@ -281,6 +287,12 @@ REA mengekspor lingkungan yang dapat dijalankan dengan uji dasar untuk memeriksa
|
||||
[Referensi lingkungan](../agent-environments.md) ·
|
||||
[Tonton demo di X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Lingkungan aplikasi desktop
|
||||
|
||||
REA juga dapat membuat lingkungan untuk aplikasi desktop Linux yang digunakan agen melalui tangkapan layar, mouse, dan keyboard. Dari permintaan satu baris, seperti "Buatkan lingkungan Gnote tempat agen menambahkan minyak zaitun ke catatan daftar belanja", agen Anda memasang aplikasi di komputer build lokal, menulis tugas, mengekspor lingkungan, dan memeriksa tugas di komputer baru. Mesin yang membuatnya memerlukan Linux di amd64 atau arm64, Docker, dan versi framework agentenv yang ditetapkan panduan.
|
||||
|
||||
[Siapkan lingkungan aplikasi desktop](../desktop-build-computer.md)
|
||||
|
||||
## FAQ
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · **Italiano**
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -84,6 +84,10 @@ La configurazione supporta Claude Code, Codex, Cursor, Gemini CLI, Grok Build e
|
||||
|
||||
MCP usa schemi di input compatti per impostazione predefinita. Per tutte le indicazioni sui campi e la validazione annidata, imposta `REA_MCP_INPUT_SCHEMA_PROFILE=full` nella registrazione MCP. Entrambi i profili mantengono tutti gli strumenti e la stessa validazione canonica del server; vedi la guida ai contratti MCP.
|
||||
|
||||
La configurazione registra direttamente il runtime scelto e lo script di avvio di REA. Se usi un package runner, conserva la sua voce nella cache e il runtime; scarica il pacchetto da una directory attendibile fuori dal progetto di destinazione. Consulta la guida di installazione.
|
||||
|
||||
Gli schemi di output completi sono dichiarati per impostazione predefinita. Se il client limita `tools/list`, imposta `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` o `off` nella registrazione MCP. La validazione del server e i risultati strutturati restano completi. Consulta «Output schemas» nella guida ai contratti MCP.
|
||||
|
||||
### Chiedi al tuo agente
|
||||
|
||||
```text
|
||||
@@ -156,6 +160,7 @@ REA richiede Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), oltre
|
||||
| Layout ELF offline | Sezioni, segmenti, simboli/relocazioni originali e candidati mitigazioni statiche | pwntools fornito dal chiamante su Linux x64; [diagnostica binaria](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| Artefatto WASM | Convalida, sezioni, forme WAT di import/export esatte e WAT decodificato | WABT 1.0.42 fornito dal chiamante; `inspect_wasm_artifact` |
|
||||
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale su Linux x64; [guida EVM offline](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
@@ -172,6 +177,7 @@ REA richiede Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), oltre
|
||||
| Captured di pacchetti | Endpoint, DNS, TLS SNI, distribuzione dei protocolli e richieste HTTP | tshark e capinfos forniti dal chiamante; [guida pcap](../guides/data/pcap-analysis.md) |
|
||||
| Assembly .NET | Metadati, istruzioni CIL, dipendenze native dichiarate e confronti di build | Nessuno (solo statico); [guida managed-code](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| APK Android | Dichiarazioni manifest, classi, metodi decompilati e riferimenti | JADX headless e un JDK completo su Linux/macOS/Windows x64; [guida Android](../guides/android/android-analysis.md) |
|
||||
| Dispositivi Android | Dispositivi, pacchetti, processi, log, dump, screenshot e trasferimenti APK/file | adb fornito dal chiamante (emulatore o hardware); [guida ADB](../guides/android/adb-device-analysis.md) |
|
||||
| Progetti JEB | Unità di progetto dal motore, digest degli artifact e pseudocodice di tipi/metodi | Client JEB avviato dal chiamante via MCP, selezionato con REA_JEB_MCP_URL; [guida JEB](../providers/jeb-analysis.md) |
|
||||
@@ -270,6 +276,12 @@ REA esporta un ambiente eseguibile con un test di base che ne verifica l’avvio
|
||||
[Riferimento degli ambienti](../agent-environments.md) ·
|
||||
[Guarda la demo su X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Ambienti di app desktop
|
||||
|
||||
REA può creare anche un ambiente per un’app desktop Linux, che un agente usa tramite screenshot, mouse e tastiera. Da una richiesta di una riga, come «Creami un ambiente Gnote in cui l’agente aggiunge l’olio d’oliva alla nota della lista della spesa», il tuo agente installa l’app su un computer di build locale, scrive l’attività, esporta l’ambiente e verifica l’attività su un computer nuovo. La macchina che lo crea richiede Linux su amd64 o arm64, Docker e la versione del framework agentenv indicata dalla guida.
|
||||
|
||||
[Configurare gli ambienti di app desktop](../desktop-build-computer.md)
|
||||
|
||||
## FAQ
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · **日本語** · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA:あらゆるものをリバースエンジニアリング
|
||||
|
||||
@@ -84,6 +84,10 @@ npx rea-agents setup
|
||||
|
||||
MCP は既定でコンパクトな入力スキーマを使用します。完全なフィールド説明と入れ子の検証情報が必要な場合は、MCP 登録に `REA_MCP_INPUT_SCHEMA_PROFILE=full` を設定してください。どちらも全ツールと同じ正規サーバー検証を維持します。詳細は MCP 契約ガイドを参照してください。
|
||||
|
||||
セットアップは選択したランタイムと REA のエントリースクリプトを直接登録します。パッケージランナーを使う場合は、そのキャッシュ項目とランタイムを残し、対象プロジェクト外の信頼できるディレクトリからパッケージを取得してください。 インストールガイドを参照してください。
|
||||
|
||||
出力スキーマはデフォルトで完全なものが公開されます。クライアントが `tools/list` を制限する場合は、MCP 登録で `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` または `off` を設定してください。サーバー側の検証と構造化結果は完全なままです。 MCP 契約ガイドの「Output schemas」を参照してください。
|
||||
|
||||
### エージェントに依頼する
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ REA には Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)、または 26+ (>=
|
||||
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | Linux x64 上のローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -172,6 +177,7 @@ REA には Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)、または 26+ (>=
|
||||
| パケットキャプチャ | エンドポイント、DNS、TLS SNI、プロトコル分布、HTTPリクエスト | 呼び出し側が用意した tshark と capinfos;[pcapガイド](../guides/data/pcap-analysis.md) |
|
||||
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS/Windows x64 上のヘッドレス JADX と完全な JDK;[Android ガイド](../guides/android/android-analysis.md) |
|
||||
| Android デバイス | デバイス、パッケージ、プロセス、ログ、ダンプ、スクリーンキャプチャ、APK/ファイル転送 | 呼び出し側が用意した adb(エミュレーターまたは実機);[ADB ガイド](../guides/android/adb-device-analysis.md) |
|
||||
| JEBプロジェクト | エンジンによるプロジェクトユニット、アーティファクトのダイジェスト、型/メソッドの擬似コード | 呼び出し側が起動し MCP を提供する JEB クライアント(REA_JEB_MCP_URL で選択);[JEB ガイド](../providers/jeb-analysis.md) |
|
||||
@@ -275,6 +281,12 @@ REA は実行可能な環境と、起動して応答することを確認する
|
||||
[環境リファレンス](../agent-environments.md) ·
|
||||
[X でデモを見る](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### デスクトップアプリの環境
|
||||
|
||||
REA は、エージェントがスクリーンショット、マウス、キーボードで操作する Linux デスクトップアプリの環境も構築できます。「エージェントが買い物リストのメモにオリーブオイルを追加する Gnote 環境を作って」のような 1 行の依頼から、エージェントがローカルのビルド用コンピューターにアプリをインストールし、タスクを書き、環境をエクスポートし、新しいコンピューターでタスクを確認します。構築するマシンには、amd64 または arm64 の Linux、Docker、ガイドが指定するバージョンの agentenv フレームワークが必要です。
|
||||
|
||||
[デスクトップアプリ環境を設定する](../desktop-build-computer.md)
|
||||
|
||||
## よくある質問
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · **한국어** · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: 무엇이든 리버스 엔지니어링
|
||||
|
||||
@@ -84,6 +84,10 @@ npx rea-agents setup
|
||||
|
||||
MCP는 기본적으로 간결한 입력 스키마를 사용합니다. 전체 필드 안내와 중첩 검증 정보가 필요하면 MCP 등록에서 `REA_MCP_INPUT_SCHEMA_PROFILE=full`을 설정하세요. 두 프로필 모두 전체 도구와 동일한 정규 서버 검증을 유지합니다. MCP 계약 가이드를 참고하세요.
|
||||
|
||||
설정은 선택한 런타임과 REA 진입 스크립트를 직접 등록합니다. 패키지 실행기를 사용한다면 해당 캐시 항목과 런타임을 유지하고, 대상 프로젝트 밖의 신뢰할 수 있는 디렉터리에서 패키지를 받으세요. 설치 가이드를 참고하세요.
|
||||
|
||||
기본적으로 완전한 출력 스키마가 제공됩니다. 클라이언트가 `tools/list` 크기를 제한한다면 MCP 등록에서 `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` 또는 `off`로 설정하세요. 서버 검증과 구조화된 결과는 완전하게 유지됩니다. MCP 계약 가이드의 «Output schemas»를 참고하세요.
|
||||
|
||||
### 에이전트에게 요청
|
||||
|
||||
```text
|
||||
@@ -159,6 +163,7 @@ REA에는 Node.js 22.x(>=22.23.4), 24.x(>=24.22.1) 또는 26+ (>=26.12.1)와 npm
|
||||
| Rust 바이너리 | cargo-auditable이 내장한 크레이트 이름, 버전, 소스, 의존성 관계 | REA 내장 ELF/PE/thin Mach-O 정적 검사; [Rust 바이너리](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../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](../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](../binary-hardening.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
@@ -185,6 +190,7 @@ REA에는 Node.js 22.x(>=22.23.4), 24.x(>=24.22.1) 또는 26+ (>=26.12.1)와 npm
|
||||
| 패키지 및 리소스 | 파일 목록, 다이제스트, plist, Apple 번들 구조, 추출한 리소스 | [아티팩트 및 JavaScript 가이드](../guides/javascript/javascript-artifact-reconstruction.md), [Apple 애플리케이션](../guides/apple/apple-application-analysis.md) |
|
||||
| 프로세스 동작 | 터미널 출력, 상호작용, 종료 및 파일 시스템 관찰 결과, 실행 비교 | 네이티브 PTY를 지원하는 Linux/macOS; [프로세스 캡처](../guides/runtime/process-capture.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| GPU 코드 객체 | CUDA/HIP 대상, 선택한 커널 매개변수와 자원, 보존된 PTX 텍스트 | 내장 정적 검사 ELF/PE/fatbin/CUBIN/PTX; [GPU](../gpu-code-objects.md) |
|
||||
| 모델 파일 | GGUF / safetensors 메타데이터, 텐서 선언과 계산한 합계 | 헤더 검사; 전체 파일 해시는 선택 사항; [GGUF / safetensors](../model-artifacts.md) |
|
||||
| IL2CPP 메타데이터 | Unity global-metadata.dat 어셈블리 이미지, 형식·메서드 이름과 인덱스 범위 | 버전 24, 27, 29, 31, 39 정적 디코딩; Unity 불필요 |
|
||||
@@ -273,6 +279,12 @@ REA는 실행 가능한 환경과 시작 및 응답 여부를 확인하는 기
|
||||
[환경 참조 문서](../agent-environments.md) ·
|
||||
[X에서 데모 보기](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### 데스크톱 앱 환경
|
||||
|
||||
REA는 에이전트가 스크린샷, 마우스, 키보드로 사용하는 Linux 데스크톱 앱의 환경도 만들 수 있습니다. "에이전트가 장보기 목록 메모에 올리브유를 추가하는 Gnote 환경을 만들어 줘" 같은 한 줄 요청에서 에이전트가 로컬 빌드 컴퓨터에 앱을 설치하고, 작업을 작성하고, 환경을 내보낸 뒤 새 컴퓨터에서 작업을 확인합니다. 환경을 만드는 머신에는 amd64 또는 arm64의 Linux, Docker, 가이드가 지정한 버전의 agentenv 프레임워크가 필요합니다.
|
||||
|
||||
[데스크톱 앱 환경 설정하기](../desktop-build-computer.md)
|
||||
|
||||
## 자주 묻는 질문
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · **മലയാളം** · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · **മലയാളം** · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: എന്തും Reverse Engineer ചെയ്യുക
|
||||
|
||||
@@ -86,6 +86,10 @@ Claude Code, Codex, Cursor, Gemini CLI, Grok Build, കൂടാതെ [മറ
|
||||
|
||||
MCP സാധാരണയായി compact input schemas ഉപയോഗിക്കുന്നു. പൂർണ്ണ field guidance-ഉം nested validation details-ഉം വേണമെങ്കിൽ MCP registration-ൽ `REA_MCP_INPUT_SCHEMA_PROFILE=full` സജ്ജമാക്കുക. രണ്ടു profiles-ലും എല്ലാ tools-ഉം ഒരേ canonical server validation-ഉം നിലനിൽക്കും; MCP contracts guide കാണുക.
|
||||
|
||||
തിരഞ്ഞെടുത്ത runtime-ഉം REA entry script-ഉം setup നേരിട്ട് രജിസ്റ്റർ ചെയ്യുന്നു. Package runner ഉപയോഗിക്കുമ്പോൾ അതിന്റെ cache entry-യും runtime-ഉം നിലനിർത്തുക; target project-ന് പുറത്തുള്ള വിശ്വസനീയമായ ഡയറക്ടറിയിൽ നിന്ന് package നേടുക. ഇൻസ്റ്റലേഷൻ ഗൈഡ് കാണുക.
|
||||
|
||||
പൂർണ്ണ output schema-കൾ സ്ഥിരസ്ഥിതിയായി പരസ്യപ്പെടുത്തുന്നു. Client `tools/list` പരിമിതപ്പെടുത്തുന്നുവെങ്കിൽ MCP registration-ൽ `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` അല്ലെങ്കിൽ `off` സജ്ജമാക്കുക. Server validation-ഉം structured result-കളും പൂർണ്ണമായി നിലനിൽക്കും. MCP കരാർ ഗൈഡിലെ «Output schemas» കാണുക.
|
||||
|
||||
### നിങ്ങളുടെ agent-നോട് ആവശ്യപ്പെടുക
|
||||
|
||||
```text
|
||||
@@ -159,6 +163,7 @@ REA-യ്ക്ക് Node.js 22.x (>=22.23.4), 24.x (>=24.22.1), അല്ല
|
||||
| Rust binaries | ഉൾച്ചേർത്ത cargo-auditable crate പേരുകൾ, versions, sources, dependency edges | Built-in static ELF/PE/thin Mach-O പരിശോധന; [Rust binaries](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../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](../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](../binary-hardening.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
@@ -174,6 +179,7 @@ REA-യ്ക്ക് Node.js 22.x (>=22.23.4), 24.x (>=24.22.1), അല്ല
|
||||
| Saved network captures | Requests, responses, പുറത്തുകാണുന്ന payload-ുകൾ, source locations | HAR അല്ലെങ്കിൽ Fiddler Everywhere SAZ; native mitmproxy-നായി Linux-ൽ mitmdump; [capture guide](../guides/web/web-network-captures.md) |
|
||||
| .NET assemblies | Metadata, CIL instructions, പ്രഖ്യാപിച്ച native dependencies, build comparisons | ഒന്നും ആവശ്യമില്ല (static മാത്രം); [managed-code guide](../guides/managed/managed-code-analysis.md) |
|
||||
| Python packaged apps | CArchive/PYZ entries, Python version, bytecode, resources and runtime options | Static PyInstaller parsing; [Python guide](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Android APKs | Manifest declarations, classes, decompiled methods, references | Linux/macOS/Windows x64-ൽ Headless JADX-ഉം full JDK-ഉം; [Android guide](../guides/android/android-analysis.md) |
|
||||
| Android devices | Devices, packages, processes, logs, dumps, screen captures, APK/file transfers | Caller നൽകുന്ന adb (emulator അല്ലെങ്കിൽ hardware); [ADB guide](../guides/android/adb-device-analysis.md) |
|
||||
| JEB projects | Engine-backed project units, artifact digests, type/method pseudo-code | MCP സേവനം നൽകുന്ന caller ആരംഭിച്ച JEB client; REA_JEB_MCP_URL ഉപയോഗിച്ച് തിരഞ്ഞെടുക്കുക; [JEB guide](../providers/jeb-analysis.md) |
|
||||
@@ -277,6 +283,12 @@ agent-env run ./my-env
|
||||
[പരിതസ്ഥിതി റഫറൻസ്](../agent-environments.md) ·
|
||||
[X-ൽ ഡെമോ കാണുക](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### ഡെസ്ക്ടോപ്പ് ആപ്പ് പരിതസ്ഥിതികൾ
|
||||
|
||||
സ്ക്രീൻഷോട്ടുകൾ, മൗസ്, കീബോർഡ് എന്നിവ വഴി ഏജന്റ് ഉപയോഗിക്കുന്ന Linux ഡെസ്ക്ടോപ്പ് ആപ്പിന്റെ പരിതസ്ഥിതിയും REA-യ്ക്ക് നിർമ്മിക്കാം. "ഷോപ്പിംഗ് ലിസ്റ്റ് നോട്ടിൽ ഏജന്റ് ഒലിവ് ഓയിൽ ചേർക്കുന്ന ഒരു Gnote പരിതസ്ഥിതി നിർമ്മിക്കുക" പോലുള്ള ഒറ്റവരി അഭ്യർത്ഥനയിൽ നിന്ന്, നിങ്ങളുടെ ഏജന്റ് ഒരു പ്രാദേശിക ബിൽഡ് കമ്പ്യൂട്ടറിൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യുന്നു, ടാസ്ക് എഴുതുന്നു, പരിതസ്ഥിതി എക്സ്പോർട്ട് ചെയ്യുന്നു, ഒരു പുതിയ കമ്പ്യൂട്ടറിൽ ടാസ്ക് പരിശോധിക്കുന്നു. ഇത് നിർമ്മിക്കുന്ന മെഷീന് amd64 അല്ലെങ്കിൽ arm64-ലെ Linux, Docker, ഗൈഡ് നിശ്ചയിക്കുന്ന agentenv ഫ്രെയിംവർക്ക് പതിപ്പ് എന്നിവ വേണം.
|
||||
|
||||
[ഡെസ്ക്ടോപ്പ് ആപ്പ് പരിതസ്ഥിതികൾ സജ്ജീകരിക്കുക](../desktop-build-computer.md)
|
||||
|
||||
## പതിവുചോദ്യങ്ങൾ
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · **Polski** · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -84,6 +84,10 @@ Konfigurator obsługuje Claude Code, Codex, Cursor, Gemini CLI, Grok Build i [in
|
||||
|
||||
MCP domyślnie używa zwartych schematów wejściowych. Pełne opisy pól i zagnieżdżonej walidacji włącza `REA_MCP_INPUT_SCHEMA_PROFILE=full` w rejestracji MCP. Oba profile zachowują wszystkie narzędzia i tę samą kanoniczną walidację serwera; zobacz przewodnik kontraktów MCP.
|
||||
|
||||
Konfiguracja zapisuje bezpośrednio wybrane środowisko uruchomieniowe i skrypt wejściowy REA. Przy użyciu narzędzia uruchamiającego pakiety zachowaj jego wpis w pamięci podręcznej i środowisko; pobierz pakiet z zaufanego katalogu poza projektem docelowym. Zobacz instrukcję instalacji.
|
||||
|
||||
Pełne schematy wyjściowe są udostępniane domyślnie. Jeśli klient ogranicza `tools/list`, ustaw `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` lub `off` w rejestracji MCP. Walidacja serwera i wyniki strukturalne pozostają pełne. Zobacz „Output schemas” w przewodniku po kontraktach MCP.
|
||||
|
||||
### Zapytaj agenta
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ REA wymaga Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) lub 26+ (>=26.12.1) oraz n
|
||||
| Układ pliku ELF w trybie offline | Sekcje, segmenty, oryginalne symbole/relokacje i potencjalne mechanizmy zabezpieczeń wskazane przez analizę statyczną | pwntools dostarczone przez użytkownika w systemie Linux x64; [diagnostyka plików binarnych](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| Kod bajtowy EVM | Selektory wywołań, przesunięcia bajtowe, wywnioskowane argumenty i mutowalność | Lokalny plik z surowymi bajtami lub zapisem szesnastkowym w systemie Linux x64; [przewodnik EVM offline](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -172,6 +177,7 @@ REA wymaga Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) lub 26+ (>=26.12.1) oraz n
|
||||
| Przechwytywanie pakietów | Punkty końcowe, DNS, TLS SNI, dystrybucja protokołów i żądania HTTP | Dostarczone przez wywołującego tshark i capinfos; [przewodnik pcap](../guides/data/pcap-analysis.md) |
|
||||
| Zestawy .NET | Metadane, instrukcje CIL, zadeklarowane zależności natywne i porównania kompilacji | Analiza statyczna; [przewodnik kodu zarządzanego](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Pakiety APK dla Androida | Deklaracje manifestu, klasy, zdekompilowane metody i odwołania | JADX bez interfejsu graficznego i pełny JDK w systemach Linux/macOS/Windows x64; [przewodnik Androida](../guides/android/android-analysis.md) |
|
||||
| Urządzenia z Androidem | Urządzenia, pakiety, procesy, logi, zrzuty, zrzuty ekranu oraz transfery APK/plików | adb dostarczony przez wywołującego (emulator lub urządzenie); [przewodnik ADB](../guides/android/adb-device-analysis.md) |
|
||||
| Projekty JEB | Jednostki projektu obsługiwane przez silnik, skróty artefaktów i pseudokod typów/metod | Uruchomiony przez wywołującego klient JEB udostępniający MCP, wybrany przez REA_JEB_MCP_URL; [przewodnik JEB](../providers/jeb-analysis.md) |
|
||||
@@ -273,6 +279,12 @@ REA eksportuje gotowe do uruchomienia środowisko z podstawowym testem uruchamia
|
||||
[Dokumentacja środowisk](../agent-environments.md) ·
|
||||
[Obejrzyj demo w X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Środowiska aplikacji desktopowych
|
||||
|
||||
REA może też zbudować środowisko aplikacji desktopowej dla Linuksa, z której agent korzysta przez zrzuty ekranu, mysz i klawiaturę. Z jednowierszowej prośby, takiej jak „Zbuduj mi środowisko Gnote, w którym agent dodaje oliwę z oliwek do notatki z listą zakupów”, twój agent instaluje aplikację na lokalnym komputerze budującym, pisze zadanie, eksportuje środowisko i sprawdza zadanie na nowym komputerze. Maszyna, która je buduje, potrzebuje Linuksa na amd64 lub arm64, Dockera i wersji frameworka agentenv wskazanej w przewodniku.
|
||||
|
||||
[Konfiguracja środowisk aplikacji desktopowych](../desktop-build-computer.md)
|
||||
|
||||
## FAQ
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · **Português (Brasil)** · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Faça engenharia reversa de qualquer coisa
|
||||
|
||||
@@ -84,6 +84,10 @@ A configuração oferece suporte ao Claude Code, Codex, Cursor, Gemini CLI, Grok
|
||||
|
||||
O MCP usa esquemas de entrada compactos por padrão. Para obter todas as orientações de campos e validação aninhada, defina `REA_MCP_INPUT_SCHEMA_PROFILE=full` no registro MCP. Ambos os perfis mantêm todas as ferramentas e a mesma validação canônica do servidor; veja o guia dos contratos MCP.
|
||||
|
||||
A configuração registra diretamente o runtime escolhido e o script de entrada do REA. Ao usar um executor de pacotes, mantenha sua entrada de cache e o runtime; obtenha o pacote em um diretório confiável fora do projeto alvo. Consulte o guia de instalação.
|
||||
|
||||
Os esquemas de saída completos são anunciados por padrão. Se o cliente limitar `tools/list`, defina `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` ou `off` no registro MCP. A validação do servidor e os resultados estruturados continuam completos. Consulte “Output schemas” no guia de contratos MCP.
|
||||
|
||||
### Peça ao seu agente
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ O REA requer Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), alé
|
||||
| Estrutura ELF sem execução | Seções, segmentos, símbolos/relocações originais e possíveis mecanismos de mitigação identificados por análise estática | pwntools fornecido pelo chamador no Linux x64; [diagnóstico de binários](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| Bytecode EVM | Seletores de despacho, offsets de bytes, argumentos inferidos e mutabilidade | Entrada local com bytes brutos ou representação hexadecimal no Linux x64; [guia de EVM sem execução](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -172,6 +177,7 @@ O REA requer Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), alé
|
||||
| Capturas de pacotes | Endpoints, DNS, TLS SNI, distribuição de protocolos e requisições HTTP | tshark e capinfos fornecidos pelo chamador; [guia pcap](../guides/data/pcap-analysis.md) |
|
||||
| Assemblies .NET | Metadados, instruções CIL, dependências nativas declaradas e comparações de builds | Inspeção estática; [guia de código gerenciado](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| APKs Android | Declarações do manifesto, classes, métodos descompilados e referências | JADX sem interface gráfica e um JDK completo no Linux/macOS/Windows x64; [guia de Android](../guides/android/android-analysis.md) |
|
||||
| Dispositivos Android | Dispositivos, pacotes, processos, logs, despejos, capturas de tela e transferências de APK/arquivos | adb fornecido pelo chamador (emulador ou aparelho); [guia de ADB](../guides/android/adb-device-analysis.md) |
|
||||
| Projetos JEB | Unidades de projeto do motor, hashes de artefatos e pseudocódigo de tipos/métodos | Um cliente JEB iniciado pelo chamador servindo MCP, selecionado com REA_JEB_MCP_URL; [guia de JEB](../providers/jeb-analysis.md) |
|
||||
@@ -273,6 +279,12 @@ O REA exporta um ambiente executável com um teste básico para verificar se ele
|
||||
[Referência de ambientes](../agent-environments.md) ·
|
||||
[Veja a demonstração no X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Ambientes de aplicativos de desktop
|
||||
|
||||
O REA também pode criar um ambiente de um aplicativo de desktop Linux, que um agente usa por capturas de tela, mouse e teclado. A partir de um pedido de uma linha, como "Crie um ambiente do Gnote em que o agente adiciona azeite à nota da lista de compras", seu agente instala o aplicativo em um computador de build local, escreve a tarefa, exporta o ambiente e verifica a tarefa em um computador novo. A máquina que o cria precisa de Linux em amd64 ou arm64, Docker e da versão do framework agentenv fixada pelo guia.
|
||||
|
||||
[Configurar ambientes de aplicativos de desktop](../desktop-build-computer.md)
|
||||
|
||||
## Perguntas frequentes
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · **Română**
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · **Română** · [Български](README_bg.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -99,6 +99,10 @@ validării structurilor imbricate. Ambele profiluri păstrează toate uneltele
|
||||
validarea canonică a serverului. Consultă secțiunea „Compact input schema profile”
|
||||
din ghidul contractelor MCP.
|
||||
|
||||
Configurarea înregistrează direct mediul de execuție ales și scriptul de intrare REA. Dacă folosești un executor de pachete, păstrează intrarea sa din cache și mediul de execuție; obține pachetul dintr-un director de încredere din afara proiectului țintă. Consultă ghidul de instalare.
|
||||
|
||||
Schemele complete de ieșire sunt anunțate implicit. Dacă clientul limitează `tools/list`, setează `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` sau `off` în înregistrarea MCP. Validarea serverului și rezultatele structurate rămân complete. Consultă „Output schemas” din ghidul contractelor MCP.
|
||||
|
||||
### Cere-i agentului
|
||||
|
||||
```text
|
||||
@@ -199,6 +203,7 @@ Uneltele suplimentare și platformele acceptate depind de ținta analizată:
|
||||
| Fișiere binare Rust | Nume, versiuni, surse și relații de dependență ale pachetelor crate încorporate prin cargo-auditable | Inspectare statică integrată a fișierelor ELF/PE/Mach-O cu o singură arhitectură; [binare Rust](../rust-binaries.md) |
|
||||
| Certificate PE | Intrări Authenticode WIN_CERTIFICATE și câmpuri de identitate ale semnatarilor PKCS#7 și certificatelor X.509 | Inspectare statică integrată a fișierelor PE; [certificate PE](../pe-certificates.md) |
|
||||
| Importuri PE | Numele DLL-urilor importate și încărcate întârziat, ordinale, RVA-uri ale IAT și hash-ul importurilor calculat de pefile | Inspectare statică integrată a fișierelor PE; [importuri PE](../pe-imports.md) |
|
||||
| Scurtături Windows | Țintă Shell Link, argumente, director de lucru, ExtraData și identificatori Tracker | Inspectare statică integrată a fișierelor LNK; [scurtături Windows](../guides/native/windows-shortcut.md) |
|
||||
| Note ELF | Proprietari și tipuri PT_NOTE/SHT_NOTE, câmpuri GNU build-id și ABI-tag | Inspectare statică integrată a fișierelor ELF; [note ELF](../elf-notes.md) |
|
||||
| Întărire binară | PIE, NX, RELRO, CFG și indicatori de antet pentru ELF, PE și Mach-O | Inspecție statică integrată a antetelor; [întărire binară](../binary-hardening.md) |
|
||||
| Rapoarte Apple IPS de eroare fatală | Metadate .ips, fire de execuție, imagini binare, registre și clase documentate de erori fatale | Inspectare statică integrată a datelor JSON; [Apple IPS](../apple-ips.md) |
|
||||
@@ -225,6 +230,7 @@ Uneltele suplimentare și platformele acceptate depind de ținta analizată:
|
||||
| Pachete și resurse | Inventare de fișiere, hash-uri, fișiere plist, structura pachetelor de aplicație Apple și resurse extrase | [Ghidul artefactelor și JavaScript](../guides/javascript/javascript-artifact-reconstruction.md), [aplicații Apple](../guides/apple/apple-application-analysis.md) |
|
||||
| Comportamentul proceselor | Ieșirea în terminal, interacțiuni, observații despre terminarea proceselor și sistemul de fișiere și comparații între rulări | Linux/macOS cu un PTY nativ; [capturarea proceselor](../guides/runtime/process-capture.md) |
|
||||
| Executabile PyInstaller | Membri CArchive, versiunea Python, scripturi de intrare și bytecode extras | Fără cerințe suplimentare (doar analiză statică); [aplicații Python împachetate](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
|
||||
Inspectarea statică JavaScript și .NET citește fișierele furnizate fără a rula
|
||||
aplicația. Capturarea în timpul execuției rulează ținta selectată sau interacționează
|
||||
@@ -333,6 +339,12 @@ REA exportă un mediu executabil cu un test de bază care verifică pornirea și
|
||||
[Referință pentru medii](../agent-environments.md) ·
|
||||
[Vezi demonstrația pe X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Medii pentru aplicații desktop
|
||||
|
||||
REA poate crea și un mediu pentru o aplicație desktop Linux, pe care un agent o folosește prin capturi de ecran, mouse și tastatură. Dintr-o cerere de un rând, precum „Creează-mi un mediu Gnote în care agentul adaugă ulei de măsline în notița cu lista de cumpărături”, agentul tău instalează aplicația pe un computer de build local, scrie sarcina, exportă mediul și verifică sarcina pe un computer nou. Mașina care îl creează are nevoie de Linux pe amd64 sau arm64, Docker și versiunea frameworkului agentenv fixată de ghid.
|
||||
|
||||
[Configurează mediile pentru aplicații desktop](../desktop-build-computer.md)
|
||||
|
||||
## Întrebări frecvente
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · **Русский** · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Реверс-инжиниринг чего угодно
|
||||
|
||||
@@ -84,6 +84,10 @@ npx rea-agents setup
|
||||
|
||||
MCP по умолчанию использует компактные входные схемы. Для полного описания полей и вложенной валидации задайте `REA_MCP_INPUT_SCHEMA_PROFILE=full` в регистрации MCP. Оба профиля сохраняют все инструменты и одинаковую каноническую проверку на сервере; см. руководство по контрактам MCP.
|
||||
|
||||
Настройка напрямую регистрирует выбранную среду выполнения и входной скрипт REA. При использовании средства запуска пакетов сохраняйте его запись в кэше и среду выполнения; получайте пакет из доверенного каталога вне целевого проекта. См. руководство по установке.
|
||||
|
||||
Полные схемы вывода объявляются по умолчанию. Если клиент ограничивает `tools/list`, задайте `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` или `off` в регистрации MCP. Проверка на сервере и структурированные результаты остаются полными. См. раздел «Output schemas» в руководстве по контрактам MCP.
|
||||
|
||||
### Задайте вопрос агенту
|
||||
|
||||
```text
|
||||
@@ -159,6 +163,7 @@ REA требует Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) или 26+ (>=26.1
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../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](../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](../binary-hardening.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
@@ -182,6 +187,7 @@ REA требует Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) или 26+ (>=26.1
|
||||
| Пакеты и ресурсы | Списки файлов, хеши, plist, структура пакетов Apple и извлечённые ресурсы | [Руководство по артефактам и JavaScript](../guides/javascript/javascript-artifact-reconstruction.md), [приложения Apple](../guides/apple/apple-application-analysis.md) |
|
||||
| Поведение процессов | Вывод терминала, взаимодействия, наблюдения за завершением и файловой системой, сравнения запусков | Linux/macOS с нативным PTY; [захват процессов](../guides/runtime/process-capture.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Бинарные файлы Go | Встроенная версия компилятора, модули, замены и параметры сборки | Встроенный статический анализ ELF/PE/thin Mach-O; Установка Go не нужна |
|
||||
| Базы SQLite | Таблицы, столбцы, индексы, представления, триггеры и выбранные строки обычных таблиц | Локальный снимок БД/WAL; Node.js 24.x >=24.15 или 26+ с нативными ограничениями SQLite |
|
||||
| Объекты кода GPU | Цели CUDA/HIP, параметры и ресурсы выбранных ядер, сохранённый текст PTX | Встроенный статический анализ ELF/PE/fatbin/CUBIN/PTX; [GPU](../gpu-code-objects.md) |
|
||||
@@ -273,6 +279,12 @@ REA экспортирует готовое к запуску окружение
|
||||
[Справочник окружений](../agent-environments.md) ·
|
||||
[Смотреть демо в X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Окружения десктопных приложений
|
||||
|
||||
REA также может создать окружение десктопного приложения для Linux, которым агент пользуется через снимки экрана, мышь и клавиатуру. По запросу в одну строку, например «Создай окружение Gnote, где агент добавляет оливковое масло в заметку со списком покупок», ваш агент устанавливает приложение на локальный компьютер сборки, пишет задание, экспортирует окружение и проверяет задание на новом компьютере. Машине, которая его собирает, нужны Linux на amd64 или arm64, Docker и версия фреймворка agentenv, указанная в руководстве.
|
||||
|
||||
[Настройка окружений десктопных приложений](../desktop-build-computer.md)
|
||||
|
||||
## Частые вопросы
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · **ไทย** · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -84,6 +84,10 @@ npx rea-agents setup
|
||||
|
||||
MCP ใช้สคีมาอินพุตแบบกระชับโดยปริยาย หากต้องการคำอธิบายฟิลด์และการตรวจสอบแบบซ้อนทั้งหมด ให้ตั้ง `REA_MCP_INPUT_SCHEMA_PROFILE=full` ในการลงทะเบียน MCP ทั้งสองแบบคงเครื่องมือครบและใช้การตรวจสอบมาตรฐานฝั่งเซิร์ฟเวอร์เดียวกัน ดูคู่มือสัญญา MCP
|
||||
|
||||
การตั้งค่าจะลงทะเบียนรันไทม์ที่เลือกและสคริปต์เริ่มต้นของ REA โดยตรง หากใช้ตัวรันแพ็กเกจ ให้เก็บรายการแคชและรันไทม์ไว้ และรับแพ็กเกจจากไดเรกทอรีที่เชื่อถือได้นอกโปรเจกต์เป้าหมาย ดูคู่มือการติดตั้ง
|
||||
|
||||
ระบบประกาศสคีมาเอาต์พุตฉบับเต็มตามค่าเริ่มต้น หากไคลเอนต์จำกัด `tools/list` ให้ตั้ง `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` หรือ `off` ในการลงทะเบียน MCP การตรวจสอบฝั่งเซิร์ฟเวอร์และผลลัพธ์แบบมีโครงสร้างยังคงครบถ้วน ดูหัวข้อ “Output schemas” ในคู่มือสัญญา MCP
|
||||
|
||||
### ถามเอเจนต์
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ REA ต้องใช้ Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) หรื
|
||||
| โครงสร้าง ELF แบบออฟไลน์ | เซกชัน เซกเมนต์ สัญลักษณ์/รีโลเคชันต้นฉบับ และตัวเลือกกลไกป้องกันที่พบจากการวิเคราะห์แบบสถิต | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; [การวินิจฉัยไบนารี](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหกบน Linux x64; [คู่มือ EVM แบบออฟไลน์](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -172,6 +177,7 @@ REA ต้องใช้ Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) หรื
|
||||
| การจับแพ็กเก็ต | จุดเชื่อมต่อ, DNS, TLS SNI, การกระจายโปรโตคอล และคำขอ HTTP | tshark และ capinfos ที่ผู้เรียกจัดเตรียม; [คู่มือ pcap](../guides/data/pcap-analysis.md) |
|
||||
| แอสเซมบลี .NET | เมทาดาทา คำสั่ง CIL การพึ่งพาเนทีฟที่ประกาศไว้ และการเปรียบเทียบผลการบิลด์ | การตรวจสอบแบบสถิต; [คู่มือโค้ดแบบจัดการ](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS/Windows x64; [คู่มือ Android](../guides/android/android-analysis.md) |
|
||||
| อุปกรณ์ Android | อุปกรณ์ แพ็กเกจ โพรเซส บันทึก ดัมพ์ ภาพหน้าจอ และการถ่ายโอน APK/ไฟล์ | adb ที่ผู้เรียกจัดเตรียม (โปรแกรมจำลองหรืออุปกรณ์จริง); [คู่มือ ADB](../guides/android/adb-device-analysis.md) |
|
||||
| โปรเจกต์ JEB | หน่วยโปรเจกต์จากเอนจิน, แฮชของอาร์ติแฟกต์ และซูโดโค้ดของไทป์/เมท็อด | ไคลเอนต์ JEB ที่ผู้เรียกเริ่มและให้บริการ MCP เลือกด้วย REA_JEB_MCP_URL; [คู่มือ JEB](../providers/jeb-analysis.md) |
|
||||
@@ -273,6 +279,12 @@ REA ส่งออกสภาพแวดล้อมที่รันได
|
||||
[เอกสารอ้างอิงสภาพแวดล้อม](../agent-environments.md) ·
|
||||
[ชมเดโมบน X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### สภาพแวดล้อมของแอปเดสก์ท็อป
|
||||
|
||||
REA ยังสร้างสภาพแวดล้อมของแอปเดสก์ท็อปบน Linux ที่เอเจนต์ใช้งานผ่านภาพหน้าจอ เมาส์ และคีย์บอร์ดได้ด้วย จากคำขอเพียงบรรทัดเดียว เช่น "สร้างสภาพแวดล้อม Gnote ที่เอเจนต์เพิ่มน้ำมันมะกอกลงในโน้ตรายการซื้อของ" เอเจนต์ของคุณจะติดตั้งแอปบนคอมพิวเตอร์สำหรับบิลด์ในเครื่อง เขียนงาน ส่งออกสภาพแวดล้อม และตรวจสอบงานบนคอมพิวเตอร์เครื่องใหม่ เครื่องที่ใช้สร้างต้องมี Linux บน amd64 หรือ arm64, Docker และ agentenv framework เวอร์ชันที่คู่มือกำหนด
|
||||
|
||||
[ตั้งค่าสภาพแวดล้อมของแอปเดสก์ท็อป](../desktop-build-computer.md)
|
||||
|
||||
## คำถามที่พบบ่อย
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · **Türkçe** · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Her şeyi tersine mühendislikle inceleyin
|
||||
|
||||
@@ -84,6 +84,10 @@ Kurulum Claude Code, Codex, Cursor, Gemini CLI, Grok Build ve [diğer ajanları]
|
||||
|
||||
MCP varsayılan olarak kompakt girdi şemaları kullanır. Tam alan açıklamaları ve iç içe doğrulama ayrıntıları için MCP kaydında `REA_MCP_INPUT_SCHEMA_PROFILE=full` ayarlayın. Her iki profil tüm araçları ve aynı kanonik sunucu doğrulamasını korur; MCP sözleşme rehberine bakın.
|
||||
|
||||
Kurulum, seçilen çalışma zamanını ve REA giriş betiğini doğrudan kaydeder. Paket çalıştırıcısı kullanıyorsanız önbellek girdisini ve çalışma zamanını koruyun; paketi hedef projenin dışında güvenilir bir dizinden edinin. Kurulum rehberine bakın.
|
||||
|
||||
Tam çıktı şemaları varsayılan olarak duyurulur. İstemciniz `tools/list` boyutunu sınırlıyorsa MCP kaydında `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` veya `off` ayarlayın. Sunucu doğrulaması ve yapılandırılmış sonuçlar tam kalır. MCP sözleşmeleri rehberindeki “Output schemas” bölümüne bakın.
|
||||
|
||||
### Ajanınıza sorun
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ REA; Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) veya 26+ (>=26.12.1) ve npm gere
|
||||
| Rust ikili dosyaları | Gömülü cargo-auditable crate adları, sürümleri, kaynakları ve bağımlılık ilişkileri | Yerleşik statik ELF/PE/thin Mach-O incelemesi; [Rust ikili dosyaları](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../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](../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](../binary-hardening.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
@@ -172,6 +177,7 @@ REA; Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) veya 26+ (>=26.12.1) ve npm gere
|
||||
| Kaydedilmiş ağ yakalamaları | İstekler, yanıtlar, erişilebilir yük içerikleri ve kaynak konumları | HAR veya Fiddler Everywhere SAZ; Linux'ta native mitmproxy için mitmdump; [ağ yakalama rehberi](../guides/web/web-network-captures.md) |
|
||||
| .NET derlemeleri | Meta veriler, CIL talimatları, bildirilmiş yerel bağımlılıklar ve derleme karşılaştırmaları | Statik inceleme; [yönetilen kod rehberi](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Android APK'leri | Manifest bildirimleri, sınıflar, tersine derlenmiş metotlar ve referanslar | Linux/macOS/Windows x64 üzerinde arayüzsüz JADX ve tam bir JDK; [Android rehberi](../guides/android/android-analysis.md) |
|
||||
| Android cihazları | Cihazlar, paketler, süreçler, günlükler, dökümler, ekran görüntüleri ve APK/dosya aktarımları | Çağıranın sağladığı adb (emülatör veya cihaz); [ADB rehberi](../guides/android/adb-device-analysis.md) |
|
||||
| JEB projeleri | Motor destekli proje birimleri, artefakt özetleri ve tür/metot sözdekodu | Çağıranın başlattığı, MCP sunan bir JEB istemcisi, REA_JEB_MCP_URL ile seçilir; [JEB rehberi](../providers/jeb-analysis.md) |
|
||||
@@ -267,6 +273,12 @@ REA, çalıştırılabilir bir ortamı ve başlayıp yanıt verdiğini kontrol e
|
||||
[Ortam referansı](../agent-environments.md) ·
|
||||
[Demoyu X’te izleyin](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Masaüstü uygulama ortamları
|
||||
|
||||
REA, bir ajanın ekran görüntüleri, fare ve klavye ile kullandığı bir Linux masaüstü uygulamasının ortamını da oluşturabilir. “Ajanın alışveriş listesi notuna zeytinyağı eklediği bir Gnote ortamı oluştur” gibi tek satırlık bir istekten ajanınız uygulamayı yerel bir derleme bilgisayarına kurar, görevi yazar, ortamı dışa aktarır ve görevi yeni bir bilgisayarda kontrol eder. Ortamı oluşturan makinede amd64 veya arm64 üzerinde Linux, Docker ve kılavuzun sabitlediği agentenv framework sürümü gerekir.
|
||||
|
||||
[Masaüstü uygulama ortamlarını kurun](../desktop-build-computer.md)
|
||||
|
||||
## Sık sorulan sorular
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · **Українська** · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Реверс-інжиніринг будь-чого
|
||||
|
||||
@@ -84,6 +84,10 @@ npx rea-agents setup
|
||||
|
||||
MCP типово використовує компактні вхідні схеми. Для повного опису полів і вкладеної перевірки задайте `REA_MCP_INPUT_SCHEMA_PROFILE=full` у реєстрації MCP. Обидва профілі зберігають усі інструменти й однакову канонічну перевірку сервера; див. посібник контрактів MCP.
|
||||
|
||||
Налаштування безпосередньо реєструє вибране середовище виконання та стартовий скрипт REA. Якщо ви використовуєте засіб запуску пакетів, збережіть його запис у кеші та середовище виконання; отримуйте пакет із довіреного каталогу поза цільовим проєктом. Див. посібник зі встановлення.
|
||||
|
||||
Повні схеми виводу оголошуються за замовчуванням. Якщо клієнт обмежує `tools/list`, задайте `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` або `off` у реєстрації MCP. Перевірка сервера та структуровані результати залишаються повними. Див. розділ «Output schemas» у посібнику з контрактів MCP.
|
||||
|
||||
### Запитайте агента
|
||||
|
||||
```text
|
||||
@@ -157,6 +161,7 @@ REA потребує Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) або 26+ (>=26
|
||||
| Структура ELF без запуску | Секції, сегменти, початкові символи/релокації та можливі захисні механізми за даними статичного аналізу | pwntools, наданий стороною, що викликає інструмент, у Linux x64; [діагностика бінарних файлів](../guides/native/binary-diagnostics.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення у Linux x64; [посібник EVM без запуску](../guides/evm/evm-bytecode.md) |
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
|
||||
@@ -172,6 +177,7 @@ REA потребує Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) або 26+ (>=26
|
||||
| Захоплення пакетів | Кінцеві точки, DNS, TLS SNI, розподіл протоколів та HTTP-запити | Надані викликаючою стороною tshark та capinfos; [підручник pcap](../guides/data/pcap-analysis.md) |
|
||||
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS/Windows x64; [посібник Android](../guides/android/android-analysis.md) |
|
||||
| Пристрої Android | Пристрої, пакети, процеси, журнали, дампи, знімки екрана та передавання APK/файлів | adb, наданий викликаючою стороною (емулятор або пристрій); [підручник ADB](../guides/android/adb-device-analysis.md) |
|
||||
| Проєкти JEB | Єдиниці проєкту від рушія, дайджести артефактів і псевдокод типів/методів | Запущений викликаною стороною клієнт JEB з MCP, обирається через REA_JEB_MCP_URL; [посібник JEB](../providers/jeb-analysis.md) |
|
||||
@@ -273,6 +279,12 @@ REA експортує готове до запуску середовище з
|
||||
[Довідник середовищ](../agent-environments.md) ·
|
||||
[Дивитися демо в X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Середовища настільних застосунків
|
||||
|
||||
REA також може створити середовище настільного застосунку для Linux, яким агент користується через знімки екрана, мишу й клавіатуру. За запитом в один рядок, як-от «Створи середовище Gnote, де агент додає оливкову олію до нотатки зі списком покупок», ваш агент встановлює застосунок на локальний комп’ютер збирання, пише завдання, експортує середовище й перевіряє завдання на новому комп’ютері. Машині, яка його збирає, потрібні Linux на amd64 або arm64, Docker і версія фреймворку agentenv, зазначена в посібнику.
|
||||
|
||||
[Налаштування середовищ настільних застосунків](../desktop-build-computer.md)
|
||||
|
||||
## Поширені запитання
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · **Roman Urdu** · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · **Roman Urdu** · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Reverse Engineer Anything
|
||||
|
||||
@@ -99,6 +99,10 @@ set karein. Dono profiles mein tamam tools aur canonical server validation
|
||||
maujood rehte hain. MCP contracts guide ka "Compact input schema profile"
|
||||
section dekhein.
|
||||
|
||||
Setup chuna hua runtime aur REA entry script seedha register karta hai. Package runner use karne par uski cache entry aur runtime barqarar rakhein; package target project se bahar kisi bharosemand directory se hasil karein. Installation guide dekhein.
|
||||
|
||||
Mukammal output schemas default mein advertise hote hain. Agar client `tools/list` ko limit karta hai to MCP registration mein `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` ya `off` set karein. Server validation aur structured results mukammal rehte hain. MCP contracts guide ka “Output schemas” section dekhein.
|
||||
|
||||
### Apne agent se kahein
|
||||
|
||||
```text
|
||||
@@ -199,6 +203,7 @@ Mazeed tools aur host support target par depend karte hain:
|
||||
| Rust binaries | Embedded cargo-auditable crate names, versions, sources aur dependency edges | Built-in static ELF/PE/thin Mach-O inspection; [Rust binaries](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries aur PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
|
||||
| PE imports | Import aur delay-load DLL names, ordinals, IAT RVAs aur pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../guides/native/windows-shortcut.md) |
|
||||
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id aur ABI-tag fields | Built-in static ELF inspection; [ELF notes](../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](../binary-hardening.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
@@ -225,6 +230,7 @@ Mazeed tools aur host support target par depend karte hain:
|
||||
| Packages aur resources | File inventories, digests, plists, Apple bundle structure aur extracted resources | [Artifact aur JavaScript guide](../guides/javascript/javascript-artifact-reconstruction.md), [Apple applications](../guides/apple/apple-application-analysis.md) |
|
||||
| Process behavior | Terminal output, interactions, exit aur filesystem observations aur runs ka comparison | Native PTY ke saath Linux/macOS; [process capture](../guides/runtime/process-capture.md) |
|
||||
| PyInstaller executables | CArchive members, Python version, entry scripts aur extracted bytecode | Koi additional tool nahi (sirf static analysis); [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
|
||||
Static JavaScript aur .NET inspection di hui files ko application chalaye baghair
|
||||
parhti hai. Runtime capture aapki user permissions se selected target ko chalata
|
||||
@@ -332,6 +338,12 @@ REA chalne ke liye tayyar environment aur aik bunyadi test export karta hai jo u
|
||||
[Environment reference](../agent-environments.md) ·
|
||||
[X par demo dekhein](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Desktop app environments
|
||||
|
||||
REA Linux desktop app ka environment bhi bana sakta hai, jise agent screenshots, mouse aur keyboard se istemal karta hai. Aik line ki request se, jaise "Mere liye Gnote environment banao jis mein agent shopping list note mein olive oil shamil kare", aap ka agent app ko local build computer par install karta hai, task likhta hai, environment export karta hai aur naye computer par task check karta hai. Ise banane wali machine ko amd64 ya arm64 par Linux, Docker aur guide mein muqarrar agentenv framework version chahiye.
|
||||
|
||||
[Desktop app environments setup karein](../desktop-build-computer.md)
|
||||
|
||||
## FAQ
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · **Tiếng Việt** · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA: Kỹ thuật dịch ngược cho mọi thứ
|
||||
|
||||
@@ -84,6 +84,10 @@ Quá trình thiết lập hỗ trợ Claude Code, Codex, Cursor, Gemini CLI, Gro
|
||||
|
||||
MCP mặc định dùng schema đầu vào gọn. Để có hướng dẫn đầy đủ về trường và xác thực lồng nhau, đặt `REA_MCP_INPUT_SCHEMA_PROFILE=full` trong đăng ký MCP. Cả hai cấu hình giữ toàn bộ công cụ và cùng xác thực chuẩn ở máy chủ; xem hướng dẫn hợp đồng MCP.
|
||||
|
||||
Thiết lập đăng ký trực tiếp runtime đã chọn và script khởi chạy REA. Khi dùng trình chạy gói, hãy giữ mục cache và runtime đó; tải gói từ một thư mục đáng tin cậy bên ngoài dự án đích. Xem hướng dẫn cài đặt.
|
||||
|
||||
Schema đầu ra đầy đủ được công bố theo mặc định. Nếu client giới hạn `tools/list`, hãy đặt `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` hoặc `off` trong cấu hình MCP. Xác thực phía server và kết quả có cấu trúc vẫn đầy đủ. Xem mục “Output schemas” trong hướng dẫn hợp đồng MCP.
|
||||
|
||||
### Hỏi tác nhân
|
||||
|
||||
```text
|
||||
@@ -159,6 +163,7 @@ REA yêu cầu Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) hoặc 26+ (>=26.12.1)
|
||||
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../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](../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](../binary-hardening.md) |
|
||||
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
|
||||
@@ -182,6 +187,7 @@ REA yêu cầu Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) hoặc 26+ (>=26.12.1)
|
||||
| Gói và tài nguyên | Danh sách tệp, giá trị băm, plist, cấu trúc bundle Apple và tài nguyên được trích xuất | [Hướng dẫn hiện vật phần mềm và JavaScript](../guides/javascript/javascript-artifact-reconstruction.md), [ứng dụng Apple](../guides/apple/apple-application-analysis.md) |
|
||||
| Hành vi tiến trình | Đầu ra terminal, tương tác, quan sát khi thoát và hệ thống tệp, cùng so sánh các lần chạy | Linux/macOS có PTY gốc; [ghi lại tiến trình](../guides/runtime/process-capture.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Tệp nhị phân Go | Phiên bản trình biên dịch nhúng, mô-đun, thay thế và thiết lập build | Kiểm tra tĩnh tích hợp ELF/PE/thin Mach-O; Không cần cài Go |
|
||||
| Cơ sở dữ liệu SQLite | Bảng, cột, chỉ mục, view, trigger và hàng được chọn từ bảng thông thường | Ảnh chụp cơ sở dữ liệu/WAL cục bộ; Node.js 24.x >=24.15 hoặc 26+ có giới hạn SQLite native |
|
||||
| Đối tượng mã GPU | Đích CUDA/HIP, tham số và tài nguyên kernel được chọn, văn bản PTX được giữ lại | Kiểm tra tĩnh tích hợp ELF/PE/fatbin/CUBIN/PTX; [GPU](../gpu-code-objects.md) |
|
||||
@@ -273,6 +279,12 @@ REA xuất môi trường chạy được cùng bài kiểm tra cơ bản để
|
||||
[Tài liệu tham chiếu môi trường](../agent-environments.md) ·
|
||||
[Xem bản demo trên X](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### Môi trường ứng dụng desktop
|
||||
|
||||
REA cũng có thể xây dựng môi trường cho một ứng dụng desktop Linux mà tác tử dùng qua ảnh chụp màn hình, chuột và bàn phím. Từ một yêu cầu một dòng, chẳng hạn "Tạo cho tôi một môi trường Gnote trong đó tác tử thêm dầu ô liu vào ghi chú danh sách mua sắm", tác tử của bạn cài ứng dụng trên một máy tính dựng cục bộ, viết tác vụ, xuất môi trường và kiểm tra tác vụ trên một máy tính mới. Máy dựng môi trường cần Linux trên amd64 hoặc arm64, Docker và phiên bản framework agentenv mà hướng dẫn chỉ định.
|
||||
|
||||
[Thiết lập môi trường ứng dụng desktop](../desktop-build-computer.md)
|
||||
|
||||
## Câu hỏi thường gặp
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · [简体中文](README_zh.md) · **繁體中文** · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA:逆向一切
|
||||
|
||||
@@ -84,6 +84,10 @@ npx rea-agents setup
|
||||
|
||||
MCP 預設使用精簡輸入 Schema,以減少上下文開銷。需要完整欄位說明和巢狀驗證細節時,請在 MCP 註冊中設定 `REA_MCP_INPUT_SCHEMA_PROFILE=full`。兩種設定都保留完整工具集和標準的伺服器驗證;見 MCP 合約指南。
|
||||
|
||||
設定會直接登記所選執行環境和 REA 入口指令碼。使用套件執行器時,請保留其快取項目及執行環境,並從目標專案以外的可信任目錄取得套件。 請參閱安裝指南。
|
||||
|
||||
預設會公布完整輸出 Schema。若用戶端限制 `tools/list` 的大小,請在 MCP 登記中設定 `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` 或 `off`。伺服器驗證和結構化結果仍保持完整。 請參閱 MCP 合約指南中的「Output schemas」。
|
||||
|
||||
### 詢問 AI 代理
|
||||
|
||||
```text
|
||||
@@ -160,6 +164,7 @@ REA 需要 Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)或 26+ (>=26.12.1)
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../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](../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](../binary-hardening.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
@@ -172,6 +177,7 @@ REA 需要 Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)或 26+ (>=26.12.1)
|
||||
| 封包擷取 | 端點、DNS、TLS SNI、通訊協定分佈和 HTTP 請求 | 呼叫端提供的 tshark 和 capinfos;[pcap 指南](../guides/data/pcap-analysis.md) |
|
||||
| .NET 程式集 | 中繼資料、CIL 指令、聲明的原生依賴和建置對比 | 靜態檢查;[托管程式碼指南](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS/Windows x64 上的無界面 JADX 和完整 JDK;[Android 指南](../guides/android/android-analysis.md) |
|
||||
| Android 裝置 | 裝置、套件、程序、日誌、傾印、螢幕擷取以及 APK/檔案傳輸 | 呼叫端提供的 adb(模擬器或實體裝置);[ADB 指南](../guides/android/adb-device-analysis.md) |
|
||||
| JEB 專案 | 引擎支援的專案單元、成品摘要和型別/方法的虛擬碼 | 由呼叫端啟動、提供 MCP 的 JEB 用戶端,透過 REA_JEB_MCP_URL 選擇;[JEB 指南](../providers/jeb-analysis.md) |
|
||||
@@ -273,6 +279,12 @@ REA 匯出可直接執行的環境,並附帶基本測試,檢查環境能否
|
||||
[環境參考文件](../agent-environments.md) ·
|
||||
[在 X 上觀看示範](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### 桌面應用程式環境
|
||||
|
||||
REA 也能為 Linux 桌面應用程式建立環境,代理透過螢幕截圖、滑鼠和鍵盤使用它。只要一行請求,例如「幫我建立一個 Gnote 環境,讓代理在購物清單筆記中加入橄欖油」,你的代理就會在本機建置電腦上安裝應用程式、撰寫任務、匯出環境,並在全新的電腦上檢查任務。建立環境的機器需要 amd64 或 arm64 上的 Linux、Docker,以及指南固定的 agentenv 框架版本。
|
||||
|
||||
[設定桌面應用程式環境](../desktop-build-computer.md)
|
||||
|
||||
## 常見問題
|
||||
|
||||
<details>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div align="center">
|
||||
|
||||
[English](../../README.md) · **简体中文** · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md)
|
||||
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md) · [Roman Urdu](README_ur-Latn.md) · [Română](README_ro.md) · [Български](README_bg.md)
|
||||
|
||||
# REA:逆向一切
|
||||
|
||||
@@ -84,6 +84,10 @@ npx rea-agents setup
|
||||
|
||||
MCP 默认使用紧凑输入 Schema 来减少上下文开销。需要完整字段说明和嵌套验证细节时,在 MCP 注册中设置 `REA_MCP_INPUT_SCHEMA_PROFILE=full`。两种配置都保留完整工具集和规范的服务端验证;见 MCP 合约指南。
|
||||
|
||||
设置会直接注册所选运行时和 REA 入口脚本。使用包运行器时,请保留其缓存条目和运行时,并从目标项目以外的可信目录获取包。 请参阅安装指南。
|
||||
|
||||
默认公布完整输出 Schema。如果客户端限制 `tools/list` 的大小,请在 MCP 注册中设置 `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` 或 `off`。服务端验证和结构化结果仍保持完整。 请参阅 MCP 合约指南中的“Output schemas”。
|
||||
|
||||
### 询问智能体
|
||||
|
||||
```text
|
||||
@@ -160,6 +164,7 @@ REA 需要 Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)或 26+ (>=26.12.1)
|
||||
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
|
||||
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../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](../pe-imports.md) |
|
||||
| Windows shortcuts | Shell Link target, arguments, working dir, ExtraData and Tracker droid facts | Built-in static LNK inspection; [Windows shortcuts](../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](../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](../binary-hardening.md) |
|
||||
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
|
||||
@@ -172,6 +177,7 @@ REA 需要 Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)或 26+ (>=26.12.1)
|
||||
| 数据包捕获 | 端点、DNS、TLS SNI、协议分布和 HTTP 请求 | 调用方提供的 tshark 和 capinfos;[pcap 指南](../guides/data/pcap-analysis.md) |
|
||||
| .NET 程序集 | 元数据、CIL 指令、声明的原生依赖和构建对比 | 静态检查;[托管代码指南](../guides/managed/managed-code-analysis.md) |
|
||||
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
|
||||
| Deno compile binaries | Virtual files, entry point, recorded options, npm snapshot length | Static inspection; [Deno compile executables](../deno-standalone.md) |
|
||||
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS/Windows x64 上的无界面 JADX 和完整 JDK;[Android 指南](../guides/android/android-analysis.md) |
|
||||
| Android 设备 | 设备、软件包、进程、日志、转储、屏幕截图以及 APK/文件传输 | 调用方提供的 adb(模拟器或实体设备);[ADB 指南](../guides/android/adb-device-analysis.md) |
|
||||
| JEB 项目 | 引擎支持的项目单元、工件摘要和类型/方法的伪代码 | 由调用方启动、提供 MCP 的 JEB 客户端,通过 REA_JEB_MCP_URL 选择;[JEB 指南](../providers/jeb-analysis.md) |
|
||||
@@ -271,6 +277,12 @@ REA 导出可直接运行的环境,并附带基本测试,检查环境能否
|
||||
[环境参考文档](../agent-environments.md) ·
|
||||
[在 X 上观看演示](https://x.com/reatools/status/2112574822584918075?s=20)
|
||||
|
||||
### 桌面应用环境
|
||||
|
||||
REA 也能为 Linux 桌面应用构建环境,智能体通过截图、鼠标和键盘使用它。只需一行请求,例如“帮我构建一个 Gnote 环境,让智能体在购物清单笔记中加入橄榄油”,你的智能体就会在本地构建计算机上安装应用、编写任务、导出环境,并在全新的计算机上检查任务。构建环境的机器需要 amd64 或 arm64 上的 Linux、Docker,以及指南固定的 agentenv 框架版本。
|
||||
|
||||
[设置桌面应用环境](../desktop-build-computer.md)
|
||||
|
||||
## 常见问题
|
||||
|
||||
<details>
|
||||
|
||||
@@ -28,6 +28,11 @@ this effective scope. A claim verifier must commit to its own surfaces and
|
||||
their reachable dependencies, including their artifact and implemented-owner
|
||||
digests. Callers do not need to duplicate the transitive closure in the request.
|
||||
|
||||
Listed `residual_unknown_ids` select unknown identities from the Evidence bundle.
|
||||
The evaluator uses each identity's latest revision: resolved questions do not
|
||||
block the boundary, while reopened questions do. An active, unallowed question
|
||||
retains its cited supporting, contradicting and mutation Evidence in the result.
|
||||
|
||||
## Comparable verifier Evidence
|
||||
|
||||
At least one record explicitly cited by the latest verifier observation must
|
||||
|
||||
@@ -10,6 +10,9 @@ and [session discovery](#identity-and-discovery). See [transports](#transports)
|
||||
for the opt-in HTTP listener, [cancellation](#progress-and-cancellation)
|
||||
for partial-result recovery and [first-query deadlines](#ghidra-first-query-deadlines-and-recovery)
|
||||
when a cold provider exceeds the client's wait.
|
||||
The shared [caller-path](#caller-selected-paths) and
|
||||
[publication](#evidence-publication-and-source-recovery) fields also apply to CLI
|
||||
Evidence.
|
||||
|
||||
## Tool results
|
||||
|
||||
@@ -221,7 +224,7 @@ graph, while `search_scope.discovery` describes whether discovery of applicable
|
||||
direct relationships is established. A missing goal is `unknown` when either
|
||||
discovery or a relationship read is unestablished. A found path is shortest
|
||||
within the observed graph; undiscovered calls may produce a shorter path.
|
||||
`truncated` describes relationship reads, not unestablished discovery.
|
||||
`truncated` describes relationship reads, not unestablished discovery. Ghidra's recorded incoming references do not establish every computed caller; computed outgoing candidates likewise retain unknown callee discovery. IDA function-edge replies retain their observed truncation status while unclassified call targets remain unknown in discovery.
|
||||
`build_call_path` applies the same distinction to supplied function Evidence:
|
||||
its `search_scope.exhaustive` describes the supplied graph and
|
||||
`search_scope.observed_status` preserves that graph's result. Evidence without
|
||||
@@ -519,6 +522,23 @@ that buffer. It does not raise REA's reserved single-string limit, which is
|
||||
raise that Node ceiling. It does not change analysis coverage or retained
|
||||
content. Ordinary responses keep their existing complete result contract.
|
||||
|
||||
### Caller-selected paths
|
||||
|
||||
Evidence can include `caller_input_path` for the verbatim primary selection and
|
||||
`caller_input_paths` for named auxiliary selections. Each auxiliary value is a
|
||||
string or an ordered array of strings; repeated selections preserve order and
|
||||
duplicates. Consumers must accept both forms.
|
||||
|
||||
These fields record request provenance outside semantic Evidence identity.
|
||||
They do not replace the inspected identity in `subject` or prove format validity.
|
||||
One-shot binary CLI requests retain relative spelling and symlink aliases;
|
||||
provider inspections also keep the established `parameters.input_path` field.
|
||||
|
||||
Older records and workflows without a caller-path binding omit these fields.
|
||||
A workflow's explicit sensitive-value policy can exclude primary and auxiliary
|
||||
spellings independently; do not infer a missing primary from an auxiliary value.
|
||||
See [capture redaction](../guides/web/web-network-captures.md) for its policy.
|
||||
|
||||
### Input validation resource allowance
|
||||
|
||||
Both HTTP and stdio admit at most 1,024 combined array elements and object
|
||||
@@ -1356,11 +1376,9 @@ uses `cleanup_incomplete` and lists only the owned resource kinds that remain.
|
||||
Once those owners confirm cleanup, composed failures recover their original
|
||||
typed primary outcome and recovery guidance. Historical composition diagnostics
|
||||
remain in `details.cleanup_history`, separate from the primary diagnostics.
|
||||
An atomic Evidence bundle or snapshot write can publish its complete output
|
||||
before staging cleanup fails. In that case, `details.published: true`,
|
||||
`details.published_path`, and `details.bytes` retain the publication receipt.
|
||||
Use that receipt to distinguish completed publication from a write that never
|
||||
committed. Staging resources remain owned until cleanup is verified.
|
||||
For written Evidence and snapshot outcomes, use the
|
||||
[publication receipt](#evidence-publication-and-source-recovery) separately from
|
||||
cleanup status.
|
||||
Native call tracing and process capture retain available observations in
|
||||
`details.partial_observation` on failure, including when cleanup succeeds.
|
||||
The observation reports its partial coverage; cleanup details describe host
|
||||
@@ -1432,6 +1450,46 @@ through provider cleanup, including repeated delivery by package runners.
|
||||
Existing controlled-process cleanup and provider shutdown rules still apply;
|
||||
REA never kills a process it cannot prove it owns.
|
||||
|
||||
### Evidence publication and source recovery
|
||||
|
||||
An atomic Evidence bundle or snapshot write can commit before later cancellation
|
||||
or staging cleanup failure. Cancellation observed before publication leaves the
|
||||
destination unchanged; once publication has started, the owning operation can
|
||||
complete it.
|
||||
Inspect the returned receipt before retrying or replacing output:
|
||||
|
||||
| Outcome | Receipt |
|
||||
| ----------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| Evidence or snapshot publication committed, then staging cleanup failed | `details.published: true`, `details.published_path`, and `details.bytes` |
|
||||
| CLI Evidence delivery cancelled after its bundle committed | `details.diagnostics.evidence_bundle` with the written path and byte count |
|
||||
|
||||
Receipt paths can be omitted when unavailable or explicitly excluded. A missing
|
||||
path alone does not establish that publication failed.
|
||||
|
||||
A publication failure can retain completed Evidence in
|
||||
`details.partial_observation`. The receipt confirms written output, not that
|
||||
cleanup succeeded or every analysis stage completed. Staging resources remain
|
||||
owned until cleanup is verified. Other output kinds use their own contracts,
|
||||
such as [environment directory publication](../getting-started/cli.md#export-an-environment-bundle)
|
||||
and [decompile output receipts](../guides/native/native-investigation.md).
|
||||
|
||||
For a requested one-shot Evidence bundle that did not commit, the error can
|
||||
include `details.source_closure` when completed Evidence has source records or
|
||||
links, or source collection failed. `publication` is `not_published`.
|
||||
When collection yields source facts, `records` contains captured Evidence within
|
||||
64 KiB; explicit sensitivity exclusions can withhold all inline records.
|
||||
`omitted` lists up to 64 other identities, and `omitted_count` gives the total:
|
||||
|
||||
- `not_captured`: this invocation has no record to return; its ancestry remains unknown.
|
||||
- `not_inlined`: the record was captured but is outside this bounded response.
|
||||
|
||||
`complete` is true only when source inspection succeeded and every cited record
|
||||
is included or embedded in the observation. On inspection failure,
|
||||
`collection_failure` names the error type and closure stays unknown. Captured
|
||||
records can still be returned, but record and omission fields can be absent if
|
||||
collection itself failed. The original operation failure remains primary.
|
||||
The one-shot process retains nothing after exit; rerunning is a new observation.
|
||||
|
||||
## Request scope and local effects
|
||||
|
||||
Each tool request names the target and lifecycle it will use. Browser calls
|
||||
|
||||
@@ -129,7 +129,9 @@ separately from its type and flags, and
|
||||
REA preserves known empty names separately from unavailable names; an unavailable
|
||||
name table still leaves `.dep-v0` presence unknown.
|
||||
The hash is not a claim that that compiler produced the binary. Several
|
||||
distinct hashes leave a single commit unknown.
|
||||
distinct hashes leave a single commit unknown. Windows builds join the rest of
|
||||
the path with a backslash, as in `/rustc/<40-hex>\library\core`, and that form
|
||||
counts too.
|
||||
|
||||
## Limits and failures
|
||||
|
||||
|
||||
+26
-9
@@ -1,17 +1,34 @@
|
||||
# Feature specifications
|
||||
|
||||
Feature specifications are grouped by domain and meaningful feature slug. Each
|
||||
directory owns one `spec.md`, one `plan.md` and one `tasks.md`.
|
||||
This directory indexes proposals and implementation records. It is not a catalog
|
||||
of current capabilities; use the [documentation directory](../README.md) for
|
||||
current guides. Preserve original requirements and dated verification evidence
|
||||
when later increments change behavior.
|
||||
|
||||
New feature directories use one `spec.md`, one `plan.md` and one `tasks.md`.
|
||||
Some historical records have fewer artifacts; their presence or absence does not
|
||||
establish completion. Do not invent past plans or completed tasks to fill gaps.
|
||||
Follow [documentation ownership and authoring](../development/documentation.md#feature-lifecycle)
|
||||
for the specification lifecycle, roadmap granularity and producer-owned contracts.
|
||||
for new work, roadmap granularity and producer-owned contracts.
|
||||
|
||||
## Documentation
|
||||
## Environment roadmaps
|
||||
|
||||
- [Organization](documentation/organization/spec.md)
|
||||
([plan](documentation/organization/plan.md), [tasks](documentation/organization/tasks.md))
|
||||
- [Agent environments](agent-environments/README.md)
|
||||
- [Desktop application environments](desktop-app-environments/README.md)
|
||||
|
||||
## Native
|
||||
## Other feature records
|
||||
|
||||
- [Go static string-header literal recovery](native/go-string-literals/spec.md)
|
||||
([plan](native/go-string-literals/plan.md), [tasks](native/go-string-literals/tasks.md))
|
||||
- [Core WebAssembly interface comparison (#2356)](2356-wasm-interface-comparison/spec.md) ([plan](2356-wasm-interface-comparison/plan.md), [tasks](2356-wasm-interface-comparison/tasks.md), [verification](2356-wasm-interface-comparison/verification.md))
|
||||
- [Inspect APK signature schemes (v1–v3.1)](apk-signature/spec.md)
|
||||
- [Documentation organization](documentation/organization/spec.md) ([plan](documentation/organization/plan.md), [tasks](documentation/organization/tasks.md), [verification](documentation/organization/verification.md))
|
||||
- [V8 cached-data compilation boundaries](javascript/v8-cached-data/spec.md) ([plan](javascript/v8-cached-data/plan.md), [tasks](javascript/v8-cached-data/tasks.md))
|
||||
- [Android `.note.android.ident` ELF note decoding](native/android-elf-ident-note/spec.md) ([plan](native/android-elf-ident-note/plan.md), [tasks](native/android-elf-ident-note/tasks.md))
|
||||
- [Native call source coordinates](native/call-source-locations/spec.md) ([plan](native/call-source-locations/plan.md), [tasks](native/call-source-locations/tasks.md), [verification](native/call-source-locations/verification.md))
|
||||
- [Go static string-header literal recovery](native/go-string-literals/spec.md) ([plan](native/go-string-literals/plan.md), [tasks](native/go-string-literals/tasks.md))
|
||||
- [Windows Shell Link shortcut inspection](native/windows-shortcut/spec.md) ([plan](native/windows-shortcut/plan.md), [tasks](native/windows-shortcut/tasks.md))
|
||||
- [Solidity terminal metadata inspection](solidity/cbor-metadata/spec.md) ([plan](solidity/cbor-metadata/plan.md), [tasks](solidity/cbor-metadata/tasks.md), [verification](solidity/cbor-metadata/verification.md))
|
||||
- [Inspect a V8 code cache container](v8/code-cache-inspection/spec.md) ([plan](v8/code-cache-inspection/plan.md), [tasks](v8/code-cache-inspection/tasks.md))
|
||||
- [Deno compile executable inventory and extraction](artifacts/deno-standalone/spec.md) ([plan](artifacts/deno-standalone/plan.md), [tasks](artifacts/deno-standalone/tasks.md))
|
||||
- [ELF unwind function ranges](native/elf-unwind-ranges/spec.md) ([plan](native/elf-unwind-ranges/plan.md), [tasks](native/elf-unwind-ranges/tasks.md))
|
||||
- [Linux kernel build config](native/kernel-build-config/spec.md) ([plan](native/kernel-build-config/plan.md), [tasks](native/kernel-build-config/tasks.md))
|
||||
- [Native initializers](native/native-initializers/spec.md) ([plan](native/native-initializers/plan.md), [tasks](native/native-initializers/tasks.md))
|
||||
@@ -81,3 +81,15 @@ configuration. Retrieval rewards demonstrate particular task outcomes.
|
||||
normalizations and omissions. Keep these claims separate, and retain the
|
||||
version and coverage limits when quoting any result. This index is a source
|
||||
and PR review; it does not constitute a new real-application or benchmark run.
|
||||
|
||||
## Additional feature records
|
||||
|
||||
These feature directories supplement the dated census above; this list does not
|
||||
assert merge or verification status.
|
||||
|
||||
- [Saved values in browser scenarios](scenario-saved-values/spec.md)
|
||||
- [Serve the calls agents make and the values applications count](write-call-values/spec.md)
|
||||
- [Serve the writes callers make without recorded form fields](write-form-calls/spec.md)
|
||||
- [Serve the writes that later reads explain](write-later-reads/spec.md)
|
||||
- [Serve writes whose calls send different members](write-varied-calls/spec.md)
|
||||
- [Serve sorted creates, listed references and toggles](write-sorts-references-toggles/spec.md)
|
||||
@@ -1,5 +1,9 @@
|
||||
# Serve an environment manifest as a replay environment
|
||||
|
||||
This specification records an implementation increment and its original problem
|
||||
statement. For current behavior and limitations, see the
|
||||
[current guide](../../../agent-environments.md).
|
||||
|
||||
Issue: https://github.com/morluto/rea/issues/4933
|
||||
|
||||
## Outcome
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Environment state view from captures
|
||||
|
||||
This specification records an implementation increment and its original problem
|
||||
statement. For current behavior and limitations, see the
|
||||
[current guide](../../../agent-environments.md).
|
||||
|
||||
Issue: https://github.com/morluto/rea/issues/4933
|
||||
|
||||
## Outcome
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# Implementation plan
|
||||
|
||||
## Boundary and contract
|
||||
|
||||
Register `deno-standalone` in the existing artifact format owners:
|
||||
`src/artifacts/artifactFormats.ts`, `ArtifactEmbeddedFormatProbes.ts`,
|
||||
`ArtifactReader.ts`, `ArtifactReaderAdmission.ts`, `inventory/classify.ts`,
|
||||
`inventory/scanReader.ts` and `extraction/ArtifactExtraction.ts`. Add the format
|
||||
metadata and member roles to `src/domain/artifactFormatMetadata.ts`,
|
||||
`artifactGraph.ts`, `artifactInspection.ts` and `evidenceSubject.ts`, and accept
|
||||
the format in `src/contracts/artifactToolContracts.ts`. No new tool, provider or
|
||||
bridge is added; the CLI and MCP changes are additive.
|
||||
|
||||
Split the layout into owners under `src/artifacts/deno/`, following Deno
|
||||
`cli/lib/standalone/binary.rs` and `virtual_fs.rs` at 2.9.8 with libsui 0.16.4
|
||||
section placement:
|
||||
|
||||
- `DenoStandaloneLocation.ts` confirms the carrier name before claiming a file.
|
||||
It reads ELF and note headers, walks PE resource directories to the named
|
||||
payload through `src/native/pe/PeResourceLayout.ts`, and scans Intel trailers
|
||||
to the slice start so an enclosing app wins over a stored executable.
|
||||
- `DenoSectionLayout.ts` parses metadata JSON, the virtual-filesystem header,
|
||||
specifier, redirect and remote tables, and the npm snapshot length.
|
||||
- `DenoVirtualFs.ts` walks directories, files and symlinks into safe logical
|
||||
paths with indexed fallbacks, using `ArtifactPathRegistry.conflicts` in
|
||||
`src/artifacts/ArtifactPaths.ts` to avoid occupied paths.
|
||||
- `DenoStandaloneAdmission.ts` binds the located carrier to the admitted file.
|
||||
|
||||
`src/artifacts/DenoStandaloneArtifactReader.ts` projects members, metadata,
|
||||
limitations and extraction regions through the existing stable artifact read and
|
||||
safe output tree.
|
||||
|
||||
## Incremental work and validation
|
||||
|
||||
1. Define the format, member roles and contracts, preserving native inventory
|
||||
for files with no confirmed carrier.
|
||||
2. Implement carrier location for Mach-O, Intel trailer, ELF and PE, with
|
||||
duplicate-section checks that reject unequal lengths before hashing.
|
||||
3. Implement section parsing and the bounded virtual-filesystem walk with
|
||||
indexed path fallbacks and remote specifier encoding.
|
||||
4. Add the reader, inventory and extraction wiring with retained environment
|
||||
and CA limitations.
|
||||
5. Add synthetic layout, location, virtual-filesystem and reader tests, CLI
|
||||
acceptance, filesystem boundary and MCP boundary tests.
|
||||
6. Add `scripts/verify-deno-standalone.mjs` (`npm run verify:deno:standalone`)
|
||||
for real Deno 2.9.8 host and cross-target compiles without execution.
|
||||
7. Update the [usage guide](../../../deno-standalone.md), CLI guide, limits,
|
||||
READMEs and skill references.
|
||||
|
||||
## Effects and compatibility
|
||||
|
||||
Inventory reads existing local files only; nothing is executed, injected or
|
||||
downloaded. A `deno compile` executable that inventoried as a native binary now
|
||||
reports `deno-standalone`, and a damaged section keeps the native format. There
|
||||
is no runtime override for the named ceilings. Deno is a fixture producer for
|
||||
the verifier only and is not installed by REA.
|
||||
@@ -0,0 +1,58 @@
|
||||
# Deno compile executable inventory and extraction
|
||||
|
||||
## Problem and outcome
|
||||
|
||||
`deno compile` embeds an application's metadata, virtual filesystem and remote
|
||||
modules in a section of a native Mach-O, ELF or PE runtime. REA inventories such
|
||||
a file as an ordinary native binary, so the embedded application stays hidden.
|
||||
Let `inspect-artifact` / `inspect_artifact` report the file as root format
|
||||
`deno-standalone` and `extract-artifact` write its embedded files through the
|
||||
existing safe output tree, without running the executable or the Deno runtime.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Recognize the Deno 2.9.8 / libsui 0.16.4 carriers: a Mach-O `__SUI` section
|
||||
named `d3n0l4nd`, an Intel Mach-O `<~sui-data~>` trailer, an ELF `PT_NOTE` or
|
||||
`SHT_NOTE` owned by `SUI` with type `0x53554901` and descriptor name
|
||||
`d3n0l4nd`, and a PE `RT_RCDATA` resource named `D3N0L4ND`. Other layouts,
|
||||
including older eszip trailers, are `unsupported`.
|
||||
- Report root metadata: carrier, embedding, entry point, argv, V8 flags,
|
||||
permission options, unstable configuration, application name, self-extracting
|
||||
marker, virtual-filesystem case sensitivity and npm snapshot byte length. Keep
|
||||
the compiler version unknown, because the metadata JSON has no version field.
|
||||
- Report each virtual file as one occurrence with logical path, size and SHA-256,
|
||||
and its transpiled output, CJS export analysis and source map as separate
|
||||
occurrences with the same `index` and their own `role`.
|
||||
- Keep logical paths safe and unique: unsafe, deep, colliding or over-long names
|
||||
(255-byte component, 512-byte path, including `.deno-*` suffixes) use indexed
|
||||
`deno-vfs/<index>` or `deno-remote/<index>` paths and retain the original
|
||||
spelling when it fits the name allowance. Percent-encode colons, backslashes
|
||||
and control characters in remote specifiers and keep the original in
|
||||
`source_path`. Never follow symlink targets.
|
||||
- Retain `Metadata.env_vars_from_env_file` values and `ca_data` bytes in local
|
||||
Evidence with their counts and byte lengths, say so in the inventory
|
||||
limitation, and do not write them as extracted files.
|
||||
- Report a virtual filesystem that cannot be listed as `vfs_listing:
|
||||
unsupported` with unknown coverage while remote modules still extract.
|
||||
- Claim a file only after confirming the carrier name. A malformed table before
|
||||
confirmation keeps the native inventory; a confirmed section that cannot be
|
||||
parsed fails closed. Side-by-side trailers with different bytes fail closed.
|
||||
- Bound metadata, header, table, specifier, remote body, virtual-filesystem
|
||||
record, depth, retained-unit and retained-byte work with named allowances,
|
||||
documented in [limits and recovery](../../../design/limits-and-recovery.md#deno-compile-sections).
|
||||
|
||||
## Acceptance
|
||||
|
||||
Synthetic fixtures cover every carrier, nested and side-by-side Intel trailers,
|
||||
malformed and duplicate declarations, path indexing and encoding, unlistable
|
||||
virtual filesystems, remote modules, npm snapshots and `ca_data`. Boundary tests
|
||||
cover CLI inventory/extraction and MCP `inspect_artifact`. A real Deno 2.9.8
|
||||
compile of the host and Linux, Windows and Intel macOS targets is inspected and
|
||||
extracted by `npm run verify:deno:standalone` without running the output
|
||||
([verification record](../../../verification/deno-standalone-2026-10-31.md)).
|
||||
|
||||
## Out of scope
|
||||
|
||||
Running the target, decoding npm snapshots, downloading remote modules,
|
||||
withholding embedded environment values by default, and layouts other than Deno
|
||||
2.9.8.
|
||||
@@ -0,0 +1,10 @@
|
||||
# Tasks
|
||||
|
||||
- [x] Define single-feature scope, contracts and implementation plan (`spec.md`, `plan.md`).
|
||||
- [x] Register `deno-standalone` in the artifact format, inventory, extraction, domain and tool contract owners.
|
||||
- [x] Implement carrier location for Mach-O sections, Intel trailers, ELF notes and PE resources in `src/artifacts/deno/DenoStandaloneLocation.ts`.
|
||||
- [x] Implement bounded section parsing and the virtual-filesystem walk with indexed and percent-encoded logical paths.
|
||||
- [x] Retain environment-file values and CA bytes in local Evidence with inventory limitations, and keep them out of extraction.
|
||||
- [x] Add synthetic layout, location, virtual-filesystem and reader tests, CLI acceptance, filesystem boundary and MCP boundary tests.
|
||||
- [x] Verify real Deno 2.9.8 host and cross-target compiles with `npm run verify:deno:standalone` ([record](../../../verification/deno-standalone-2026-10-31.md)).
|
||||
- [x] Update the usage guide, CLI guide, limits, READMEs and skill references; pass documentation checks.
|
||||
@@ -1,11 +1,19 @@
|
||||
# Desktop application environments
|
||||
|
||||
This roadmap records the planned implementation sequence. It does not establish
|
||||
current completion, review approval or verification status. For current workflows,
|
||||
see [desktop capture](../../desktop-application-capture.md),
|
||||
[build computers](../../desktop-build-computer.md),
|
||||
[tasks](../../desktop-application-tasks.md) and
|
||||
[export](../../desktop-application-export.md). Individual verification records
|
||||
retain their original scope and limitations.
|
||||
|
||||
Goal: REA turns an application installed and used on a Linux desktop into an
|
||||
agent environment's computer application. The real application installs into
|
||||
a computer image, launches to ready, exposes reset, load and get over its own
|
||||
state, and ships with tasks graded through that state.
|
||||
|
||||
The work lands as one PR per step:
|
||||
The planned sequence was one PR per step:
|
||||
|
||||
1. Pin the real agent environment lane to the framework release that carries
|
||||
the computer application contract.
|
||||
@@ -49,6 +57,21 @@ The work lands as one PR per step:
|
||||
14. [XML text checks](xml-text-checks/spec.md): XML whose DOCTYPE only names
|
||||
its DTD read as XML, starting with AbiWord, and checks of an element's
|
||||
whole text across the runs an app splits a paragraph into.
|
||||
15. [Download installs](download-installs/spec.md): applications no package
|
||||
offers, from their project's AppImage or tarball pinned by URL and
|
||||
SHA-256, unpacked under `/opt/rea-apps` by the build computer and the
|
||||
export alike, starting with FreeCAD.
|
||||
16. [Readers](file-readers/spec.md): checks of a file REA reads as binary,
|
||||
such as GIMP's `.xcf` or Blender's `.blend`, through the app's own
|
||||
headless command, run in the computer on a private copy of the file.
|
||||
17. [Screen judges](screen-judge/spec.md): checks of state no file shows,
|
||||
such as a calculator's result, by a model judging a screenshot against
|
||||
the build's labelled seed and end screenshots.
|
||||
18. [Secrets typed unseen](build-secrets/spec.md): a password or key the
|
||||
person keeps in a file on the build host, typed by its handle, which no
|
||||
result, log, record or exported bundle holds; sign-in and licence state
|
||||
withheld from the seed and supplied at run time, seeded only with the
|
||||
person's recorded consent; known handle values are checked explicitly.
|
||||
|
||||
Version 1 covers Linux with X11, applications whose state lives in files or
|
||||
SQLite under the home directory, and real applications from public packages.
|
||||
|
||||
@@ -38,14 +38,14 @@ it for building, or from an existing bundle folder.
|
||||
rather than its first package downloads.
|
||||
- The control token never appears in a result, an error or a log; the helper's
|
||||
stderr is redacted of it.
|
||||
- Build bundle from a request: the app from the Ubuntu archive, an apt
|
||||
repository with its key file, or a `.deb` URL with its SHA-256, dependencies
|
||||
and architecture, rendered with the export's install shapes and Python
|
||||
helpers; `Launch(at="demand")` through `gtk-launch`; no seed and no data
|
||||
hooks. When the request sets `electron`, the install rewrites that desktop
|
||||
entry's command with the export's launch policy (`--no-sandbox` right after
|
||||
the program, unless the command already has it) before `gtk-launch`; REA in
|
||||
a build-only layer, with Node.js 24.22.1 downloaded per
|
||||
- Build bundle from a request: the app from the Ubuntu archive, with up to 16
|
||||
extra archive packages beside it, an apt repository with its key file, or a
|
||||
`.deb` URL with its SHA-256, dependencies and architecture, rendered with
|
||||
the export's install shapes and Python helpers; `Launch(at="demand")` through
|
||||
`gtk-launch`; no seed and no data hooks. When the request sets `electron`, the
|
||||
install rewrites that desktop entry's command with the export's launch policy
|
||||
(`--no-sandbox` right after the program, unless the command already has it)
|
||||
before `gtk-launch`; REA in a build-only layer, with Node.js 24.22.1 downloaded per
|
||||
architecture and checked, and REA's payload a parameter: a local archive
|
||||
shipped in the environment folder (`REA_BUILD_COMPUTER_REA_ARCHIVE`) or,
|
||||
later, a released download.
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# Plan
|
||||
|
||||
1. Domain: `buildSecrets.ts` holds the handle schema, the value rules, the
|
||||
spellings, `secretsIn` over bytes and a gzip file's inside, and
|
||||
`redactSecrets` and `redactSecretsInJson` over text and JSON.
|
||||
2. Host files: `BuildSecretFiles.ts` resolves the folder from the server's
|
||||
environment, reads one handle's file under the ownership and permission
|
||||
rules, and lists the handles the folder holds.
|
||||
3. Typing: `computerActions.ts` adds `type_secret`, which `driverCall` maps to
|
||||
`computer_type` with its handle; `DesktopBuildSecrets.ts` keeps the values
|
||||
a server types and types one, shaping the result and refusals itself;
|
||||
`DesktopBuildComputers.ts` logs the handle and sends the value.
|
||||
4. Redaction: the action log, the witness record and the build tools'
|
||||
registration redact each typed value.
|
||||
5. Export: `DesktopBuildExport.ts` scans each fetched file before writing it
|
||||
and refuses the bundle when one holds a secret.
|
||||
6. Contract, skill, the build computer guide and this spec; unit tests for
|
||||
the spellings and the files, and MCP boundary tests for typing, the
|
||||
witness record and the export.
|
||||
7. Withheld state: `appWithheld.ts` finds the files and names their
|
||||
settings; `DesktopExportWithheld.ts` leaves them out of the seed, reads
|
||||
them for the copy, and checks the consent; the class, `env.toml` and the
|
||||
README declare them; the draft and the task admission leave them out.
|
||||
8. Host: the capture passes the sign-in window, the files named and the
|
||||
consents to the draft and the export, keeps the withheld files as
|
||||
secrets, and supplies a bundle's settings at its start;
|
||||
`record_build_consent` records the person's words.
|
||||
9. Preserve values without inferring secrecy from their shape; only declared
|
||||
handles and transport credentials are redacted.
|
||||
@@ -0,0 +1,106 @@
|
||||
# Secrets typed unseen
|
||||
|
||||
## Outcome
|
||||
|
||||
An agent building an environment for an app that asks for a password, a
|
||||
licence key or a sign-in types it through REA without seeing it. The person
|
||||
keeps the secret in a file on the build host; the agent names it by a handle;
|
||||
REA types its value into the build computer. No tool result, action log,
|
||||
witness record or exported bundle holds the value, and an export refuses a
|
||||
bundle that does. The sign-in or licence state the app writes is withheld
|
||||
from the bundle and supplied by whoever runs it, unless the person consents
|
||||
to seed it. REA does not infer secrecy from a value or name.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Secret files: one per handle, in `$XDG_CONFIG_HOME/rea/build-secrets/`, or
|
||||
`~/.config/rea/build-secrets/` when `XDG_CONFIG_HOME` is unset or relative,
|
||||
as the REA server's environment gives them. A handle is
|
||||
`^[a-z0-9][a-z0-9._-]{0,62}$`. REA reads a handle's file when it types it
|
||||
and refuses it unless the folder is a real folder, not a symbolic link, and
|
||||
the file is a regular file, opened without following a link and without
|
||||
blocking, owned by the server's user, with no group or other permission
|
||||
bit, of at most one secret's size, and UTF-8. Its text, without one final
|
||||
`\n` or `\r\n`, must hold 8 to 1024 characters and no control character.
|
||||
A refusal names the file and the reason, never its text.
|
||||
- `act_on_build_computer` action `type_secret`, taking only `secret`, a
|
||||
handle, and refusing `screenshot`, `text` or any other field, and its
|
||||
absence: REA sends `computer_type` with the value as `text`. Its result is
|
||||
REA's own: `summary` `Typed the secret <handle>` and the driver's
|
||||
`applied`, `delivery` and `others_since_frame`, one text block saying the
|
||||
same, and no image. A driver refusal, or a call that fails, is REA's own
|
||||
error naming the handle, without the driver's words or the cause, since
|
||||
either could quote the value; a cancelled call stays a cancellation.
|
||||
- Action log: a `type_secret` entry records `{"secret": "<handle>"}` and
|
||||
counts as an input for the witness's edit and near miss, as `type` does.
|
||||
Every string the log keeps, member names included, has each secret typed
|
||||
on the server replaced by `<secret:<handle>>`.
|
||||
- Results and records: every string in each build tool's text content and
|
||||
structured content, errors included, and in `witness.json`'s record, has
|
||||
each secret typed on the server, in each text spelling below, replaced by
|
||||
`<secret:<handle>>`. Images pass as they are. After this server uses a
|
||||
declared secret, automatic task drafting is withheld before it runs; the
|
||||
capture remains available for a manually written task and export. Check
|
||||
descriptions redact complete known values before shortening them. Ordinary
|
||||
text is never redacted merely because it resembles part of a secret. The
|
||||
host redacts the app's stderr and capture progress before quoting their end.
|
||||
- Export scan: before writing a bundle on the host, REA searches each file's
|
||||
path and bytes for every secret typed on the server and every other one the
|
||||
folder holds, whatever its permissions, in these spellings: as it is,
|
||||
escaped in JSON, UTF-16LE and UTF-16BE, lower- and upper-case hex of its
|
||||
UTF-8, base64 in either alphabet of the characters that depend on the
|
||||
value alone at each of the three byte alignments, and URL-encoded with
|
||||
upper- or lower-case escapes and with `+` for a space; and the same inside
|
||||
a gzip file, decompressed up to 64 MiB. A bundle holding one is refused as
|
||||
an invalid request naming each secret's handle and the files, each value
|
||||
in a file's name shown as `<secret:<handle>>`, and nothing is written to
|
||||
the folder. A gzip file that expands past 64 MiB, which the scan cannot see inside, is refused by name when known secrets are checked.
|
||||
- The skill asks the person for a secret's file instead of the secret, types
|
||||
it only into a masked field, and stops when an export finds a secret.
|
||||
- Withheld state: files under the owned paths that changed after checkpoint
|
||||
`pre-sign-in` up to `post-sign-in`, by the capture's recorded changes, and
|
||||
those `withhold` names, are withheld. With only one of the two checkpoints
|
||||
the export is refused, and so is a window in which a walk, from
|
||||
`pre-sign-in` to `post-sign-in`, stopped at its entry limit, could not list
|
||||
a directory or check a path, or left a change unconfirmed, since it may
|
||||
have missed a file the sign-in wrote. The draft leaves the withheld files
|
||||
out and lists them as `withheld_files`; a task check naming one is
|
||||
refused. An export is refused, too, for a dconf key of the app that the
|
||||
window changed and the seed holds other than before it, since the class
|
||||
seeds dconf keys and cannot withhold them, unless the withheld state is
|
||||
seeded with consent. Each withheld file present at
|
||||
the seed is left out of it and becomes a `SecretStr` field of the class's
|
||||
`Settings`, named as Python takes an argument and distinct within the app,
|
||||
which `env.toml`'s `[settings]` sets to `env:REA_<APP>_<FILE>`, so a
|
||||
deploy without the variable is refused with its name. At first boot,
|
||||
before `keep_initial`, the class writes each from its setting, the file's
|
||||
bytes in base64, mode `0600`; `data/get` serves it neither as a part nor in
|
||||
the views, and `data/reset` restores it. The README names each variable and
|
||||
how to fill it. A file larger than 48 KiB is refused. The CLI copies the
|
||||
withheld files to `--withheld-copy`, outside the bundle, and the build host
|
||||
keeps each one's base64 as the secret `rea-<app>-<file>`, or the first
|
||||
`rea-<app>-<file>-<n>` holding no other value (`0600`), never replacing a
|
||||
secret file, named in the export's `withheld_files`.
|
||||
- The export refuses a seed file whose bytes equal a withheld file's, by
|
||||
SHA-256, naming both files; a backup that differs from the withheld file is
|
||||
not caught, so the agent trashes backups before `seed`.
|
||||
- Witness: `start_build_computer` from a bundle takes `settings`, each
|
||||
`REA_*` variable mapped to a handle, whose value, up to 64 Ki characters,
|
||||
REA puts in the deploy's environment only.
|
||||
- Consent: `record_build_consent` keeps the person's words, kind `licence` or
|
||||
`seed_sign_in`, with the computer, `source: "relayed"`. The export writes
|
||||
every consent into the bundle's `consent.json`. `seed_sign_in: true` seeds
|
||||
the withheld files instead, refused unless a `seed_sign_in` consent was
|
||||
recorded; the CLI refuses `--seed-withheld` without one in `--consent`.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Redacting images: screenshots and the witness's recording show whatever
|
||||
the screen shows, so a secret stays unseen only in a field that masks it.
|
||||
- Finding a value inside a zip archive's compressed entries, or a token an
|
||||
app derives from a secret, such as a session token after a sign-in.
|
||||
- Keeping the secrets folder from the building agent's own shell on the same
|
||||
host; the client's permission rules do that.
|
||||
- Asking the person through the client itself: the agent relays their
|
||||
words, so a consent is only as true as the agent's relay.
|
||||
- Withholding state outside the owned paths, which the bundle never seeds.
|
||||
@@ -0,0 +1,40 @@
|
||||
# Tasks
|
||||
|
||||
- [x] Record the outcome, requirements and non-goals.
|
||||
- [x] Handles, value rules, spellings, the scan and redaction in
|
||||
`buildSecrets.ts` (secret files, export scan; `buildSecrets.test.ts`).
|
||||
- [x] Read, list and keep a handle's file under the ownership and permission
|
||||
rules (secret files; `BuildSecretFiles.test.ts`).
|
||||
- [x] Type a secret by its handle with `type_secret`, REA shaping its result
|
||||
and refusals (`type_secret`; `computerActions.test.ts`,
|
||||
`buildSecretsMcp.test.ts`).
|
||||
- [x] Redact typed values in the action log, the witness record and every
|
||||
build tool result (action log, results and records;
|
||||
`DesktopBuildActionLog.test.ts`, `buildWitness.test.ts`,
|
||||
`buildSecretsMcp.test.ts`).
|
||||
- [x] Scan the bundle for every secret before writing it, and refuse one
|
||||
that holds any (export scan; `buildSecretsMcp.test.ts`).
|
||||
- [x] Document the tools, the skill and the build computer guide.
|
||||
- [x] Run the KeePassXC build, export and witness on an arm64 host and record
|
||||
it in `verification.md`.
|
||||
- [x] Withhold the sign-in window's files and those named: the class's
|
||||
settings, `env.toml`, the README, the draft and the task admission
|
||||
(withheld state; `appWithheld.test.ts`, `DesktopExportWithheld.test.ts`,
|
||||
`ExportedAppPython.test.ts`).
|
||||
- [x] Keep withheld files as secrets on the host, supply a bundle's settings
|
||||
to its witness and record consent (withheld state, witness, consent;
|
||||
`buildWithheldMcp.test.ts`).
|
||||
- [x] Preserve unmarked token-shaped values and scan declared handles.
|
||||
|
||||
- [x] Run the KeePassXC and Typora withheld-state builds and record them in
|
||||
`verification.md`.
|
||||
- [x] Fix the review's gaps: refuse a sign-in window a walk may have missed a
|
||||
change in, and dconf keys the window changed; refuse a gzip file too
|
||||
large to check; keep each withheld file under a handle of its own; name
|
||||
settings Python takes (withheld state, export scan;
|
||||
`appWithheld.test.ts`, `DesktopExportWithheld.test.ts`,
|
||||
`DesktopBuildSecrets.test.ts`, `buildSecretsMcp.test.ts`,
|
||||
`buildWithheldMcp.test.ts`).
|
||||
- [x] Withhold automatic drafting before it runs after a declared secret;
|
||||
preserve the capture and manual task export. Redact full check values
|
||||
before shortening descriptions, without matching partial secret prefixes.
|
||||
@@ -0,0 +1,152 @@
|
||||
# Verification
|
||||
|
||||
## Tests
|
||||
|
||||
- `src/domain/desktop/buildSecrets.test.ts`: handles; values too short, too
|
||||
long or holding a control character; each spelling found, base64 at every
|
||||
alignment in both alphabets and a gzip file's inside included; a near miss
|
||||
and unrelated bytes not found; text and JSON redacted, member names too;
|
||||
the start of a value each of REA's cuts leaves, a draft value's, a
|
||||
reference's, a view's and a check's, hidden at any length and through an
|
||||
XML or JSON escape, as a string, a JSON member and a result's JSON text;
|
||||
ordinary text ending in `…`, such as `Please…`, left whole; an unclosed
|
||||
quote before 64 KiB of escaped quotes scanned in linear time.
|
||||
- `src/application/desktop/DesktopBuildOutputRead.test.ts`: a secret the
|
||||
app's stderr or the capture's progress holds, redacted before the quote of
|
||||
their end cuts it.
|
||||
- `src/desktop/BuildSecretFiles.test.ts`: the folder from `XDG_CONFIG_HOME`
|
||||
or `~/.config`; a `0600` or `0400` file read without its final line break;
|
||||
a file others can read, a symbolic link, a linked folder, a missing file
|
||||
and values it cannot type refused, no refusal quoting the value.
|
||||
- `src/domain/desktop/computerActions.test.ts`, `buildWitness.test.ts` and
|
||||
`src/application/desktop/DesktopBuildActionLog.test.ts`: `type_secret`
|
||||
takes only `secret`, maps to `computer_type` and counts as an edit; the log
|
||||
keeps the handle and redacts a typed value.
|
||||
- `tests/boundary/mcp/buildSecretsMcp.test.ts`, over MCP with a fake driver:
|
||||
the driver receives the value as `text` while no result holds it or an
|
||||
image; `screenshot`, a file others can read and a missing file are
|
||||
refused; a driver refusal quoting the value shows REA's words; a later
|
||||
refusal quoting it shows the handle; `witness.json` records the handle and
|
||||
a `type` holding the value redacted; and an export whose bundle holds a
|
||||
secret's value is refused, naming its files with the value redacted, and
|
||||
writes nothing, as is one holding a gzip file that expands past 64 MiB.
|
||||
|
||||
Each of these failed against the code before the change.
|
||||
|
||||
## KeePassXC on an arm64 build host
|
||||
|
||||
KeePassXC 2.7.6 from the Ubuntu 24.04 archive, on an arm64 Ubuntu 24.04 host
|
||||
with agentenv-framework 0.9.1431 and a REA server whose `XDG_CONFIG_HOME`
|
||||
held one `0600` file, `keepassxc-master`, with a made-up 30-character
|
||||
password.
|
||||
|
||||
- Build computer: a new database's password and its confirmation were typed
|
||||
with `type_secret`; each result read `Typed the secret keepassxc-master`
|
||||
with `applied: "yes"`, and the screenshot afterwards showed 30 dots in each
|
||||
field. `type_secret` with `screenshot: true` was refused. The database was
|
||||
saved to `Documents/e-test.kdbx`, `seed` marked, a setting changed and
|
||||
`end` marked.
|
||||
- Export: with a second secret file holding `keepassxc`, a string the bundle
|
||||
holds in its paths and files, the export was refused naming that handle
|
||||
and ten files, `envs/<secret:e-probe>/env.toml` among them, and no folder
|
||||
was written. With that file removed, the bundle of 10 files was written.
|
||||
- Witness, in a computer of the bundle: the seeded database opened locked,
|
||||
`type_secret` and Return unlocked it, and seed, after edit, near miss and
|
||||
after reset all held. `witness.json` records the action as
|
||||
`{"secret": "keepassxc-master"}`.
|
||||
- Leaks: every request, result, the driver's and REA server's logs,
|
||||
`witness.json`, the recording and the bundle (131 files) held the password
|
||||
in none of the spellings the export searches, UTF-16 included; nor did
|
||||
either computer's `docker logs` or any file in either container. A probe
|
||||
file holding the password's hex and UTF-16 was found by the same scan.
|
||||
|
||||
## Withheld state and consent
|
||||
|
||||
The real-provider observations below predate removal of shape-based credential
|
||||
classification. They describe that earlier build and do not verify current behavior.
|
||||
|
||||
### Tests
|
||||
|
||||
- `src/domain/desktop/appWithheld.test.ts`: the owned files changed in the
|
||||
window, and those named; a window missing a checkpoint or out of order, or
|
||||
one a walk may have missed a change in; a path outside the owned paths;
|
||||
settings, variables and handles, a long path hashed and like paths kept
|
||||
apart, and settings that are neither Python keywords nor alike in any
|
||||
order.
|
||||
- `src/application/desktop/DesktopExportWithheld.test.ts`: a withheld file
|
||||
left out of the seed, declared a secret setting from `env:`, copied aside
|
||||
and named in the README; seeding it refused without a consent and done with
|
||||
one, `consent.json` shipped; a check on it refused; the draft leaving out
|
||||
the window's files; dconf keys the window changed refused unless the seed
|
||||
holds them as before it or they are seeded with consent.
|
||||
- `src/application/desktop/DesktopBuildSecrets.test.ts`: a kept file's
|
||||
handle that names a path refused, nothing written outside the folder.
|
||||
- `src/desktop/BuildSecretFiles.concurrent.test.ts`: an export never given
|
||||
the handle of another whose different bytes are still being written.
|
||||
- `tests/boundary/application/buildExportGzipScans.test.ts`: a gzip seed
|
||||
file decompressed once for its known-secret and size checks.
|
||||
- `src/desktop/ExportedAppPython.test.ts`: `_write_withheld` writes the
|
||||
decoded bytes `0600` and `_views` leaves the file out.
|
||||
- `tests/boundary/mcp/buildWithheldMcp.test.ts`: the named file's bytes kept
|
||||
as a `0600` secret and supplied to a witness's deploy by handle, a variable
|
||||
other than `REA_*` refused; a later build's bytes kept under a handle of
|
||||
their own, an earlier build's secret left as it was; consent recorded and
|
||||
required for `seed_sign_in`, and the sign-in window passed to the draft and
|
||||
the export; one sign-in checkpoint alone refused.
|
||||
|
||||
Each of these failed against the code before the change.
|
||||
|
||||
### KeePassXC on an arm64 build host
|
||||
|
||||
- Build: `pre-sign-in` marked, a database created with its password typed by
|
||||
handle and saved, `post-sign-in` marked, which acknowledged
|
||||
`Documents/e-test.kdbx` among its changes, then `seed`, a setting changed
|
||||
and `end`. The draft listed `withheld_files: ["Documents/e-test.kdbx"]`,
|
||||
and showed the KeeShare key KeePassXC generated as
|
||||
`<credential:private-key>`.
|
||||
- Export: refused with `seed_sign_in` and no consent. Without it, the seed
|
||||
held only `keepassxc.ini`; `env.toml` set `documents_e_test_kdbx` to
|
||||
`env:REA_KEEPASSXC_DOCUMENTS_E_TEST_KDBX`; agentenv's `_declare` read the
|
||||
setting as a required `writeOnly` string; the README named the variable;
|
||||
and the host kept the database's base64 as the `0600` secret
|
||||
`rea-keepassxc-documents-e-test-kdbx`.
|
||||
- Deploy without the variable: refused at the probe with
|
||||
`Unresolved env:REA_KEEPASSXC_DOCUMENTS_E_TEST_KDBX reference`.
|
||||
- Witness, from a copy of the bundle with `settings` naming that handle: the
|
||||
computer wrote `Documents/e-test.kdbx`, mode `0600`, byte for byte the kept
|
||||
file; the agent opened it and unlocked it with `type_secret`; seed, after
|
||||
edit, near miss and after reset held, and the file was still there after
|
||||
the reset.
|
||||
- Leaks: no host file of the run but the secret's own, 146 in all, held the
|
||||
password in any spelling; neither bundle held the database's bytes; and
|
||||
neither computer's logs nor files held the password.
|
||||
|
||||
- The same build, export and witness ran again on the final code with a new
|
||||
password: every stage held, and 124 host files, both bundles and both
|
||||
computers held neither the password nor the database's bytes.
|
||||
|
||||
### Typora 1.14.9 on an arm64 build host
|
||||
|
||||
- Installed from `typora_1.14.9_arm64.deb` by URL and SHA-256, on its trial.
|
||||
Its licence file was `~/.config/Typora/rXMW4iG3Bl`, hex of
|
||||
`{"SLicense":""}`; it was `mAxvdiPNmi` on an amd64 host, so the name
|
||||
differs by machine. Typora writes it at first launch, before any
|
||||
checkpoint, so the export named it in `withhold`: it was left out of the
|
||||
84-file seed, declared as `REA_TYPORA_CONFIG_TYPORA_RXMW4IG3BL`, and kept
|
||||
as the secret `rea-typora-config-typora-rxmw4ig3bl`.
|
||||
- Booted from the bundle's image with a made-up licence in the setting, the
|
||||
initial state the class keeps before the app starts held the made-up file,
|
||||
mode `0600`; Typora then found no valid licence and wrote an empty one over
|
||||
the live file, which `data/reset` would put back.
|
||||
- A witness through `start_build_computer` failed agentenv's first-boot
|
||||
probe (`P4 a click in frame space hits its cell`), also for a bundle of the
|
||||
same capture exported without withholding, so no stage ran.
|
||||
|
||||
## Limits of this verification
|
||||
|
||||
- Only a masked field was used: a field that shows its text shows a typed
|
||||
secret in screenshots and in the recording.
|
||||
- A deploy refused for want of a variable leaves agentenv's build of that
|
||||
bundle failed; a later run needs `agent-env env build` or a fresh copy of
|
||||
the bundle.
|
||||
- The person's consent was relayed in a test; no person was asked.
|
||||
@@ -28,23 +28,50 @@ and the recording and writes the record as Evidence.
|
||||
out of every walk. A start returns once the capture reports the window
|
||||
open; a refused or early-ended start stops the capture and reports its
|
||||
output.
|
||||
- `start_build_capture` takes `state_paths`, at most 16 files or folders in
|
||||
the home, relative to it, after `~/` or absolute, without `..` and not the
|
||||
home itself; the controller resolves each under the computer's home, both
|
||||
as named and with its links followed (a path not there yet through its
|
||||
nearest existing folder), refuses one outside it or in `~/.rea-build`
|
||||
either way before launching anything, and passes each as named to the
|
||||
capture as `--state-path`. A selected file is a document, or the app's own
|
||||
state under a hidden folder of the home as named, before links, or when it
|
||||
is a lock the app holds, such as LibreOffice's `.~lock.<name>#`.
|
||||
- Acknowledgement: `capture-desktop-application` reports, beside each progress
|
||||
message, an `event`: `window_open`; `checkpoint` with its name, trigger,
|
||||
time, entries walked, changes and retained files and bytes, once it is
|
||||
taken, the baseline, `stop` and `exit` included; and `checkpoint_refused`
|
||||
with the reason. `mark_build_checkpoint` writes `checkpoint <name>` and
|
||||
waits for the event naming it, returning its counts. Names follow a narrow
|
||||
pattern, without the capture's own names; a name already taken is refused.
|
||||
time, entries walked, changes and retained files and bytes, and up to ten
|
||||
changed files, home-relative, those under a selected path first, then
|
||||
those the app held open, caches and browser-engine storage last, with a count
|
||||
of the rest, once it is taken, the baseline, `stop` and `exit` included;
|
||||
and `checkpoint_refused` with the reason. `mark_build_checkpoint` writes
|
||||
`checkpoint <name>` and waits for the event naming it, returning its counts
|
||||
and changed files, both `null` when the REA in the computer predates them
|
||||
and its event leaves them out. Names follow a narrow pattern, without the capture's own
|
||||
names; a name already taken is refused.
|
||||
- `stop_build_capture` sends `stop`, waits for the exit status, reads the
|
||||
capture's Evidence and, when `seed` and `end` were acknowledged, runs
|
||||
`describe-desktop-application-task --seed-checkpoint seed --end-checkpoint
|
||||
end` and returns the changed files, their net change and suggested checks.
|
||||
A draft with no files carries `notes`, coded `no_change`,
|
||||
`unowned_changes` (up to five changed home paths with their roles, and a
|
||||
count of the rest), `uncheckable_changes` (dconf databases whose app keys
|
||||
were read and changed, which no check reads; a version kept without its
|
||||
bytes is unreadable, not empty), `unreadable_changes` (dconf
|
||||
databases that changed but could not be read, with the read `error`) and
|
||||
`no_document`; a drafted file whose suggestions are thin carries one
|
||||
naming its `file`, coded `by_position`, `view_state_only`, `long_text`,
|
||||
`cut_view` or `unreadable_view`.
|
||||
- `export_build_environment` writes the agent's task under `~/.rea-build`,
|
||||
runs `export-desktop-application` with it and the same checkpoints into a
|
||||
new folder there, reports a refused task with the export's own reason,
|
||||
lists the bundle with sizes and SHA-256, fetches it through the driver's
|
||||
`data/get` in answers of at most 8 MiB, checks each file and writes the
|
||||
caller's new or empty folder through the safe output tree.
|
||||
caller's new or empty folder through the safe output tree. The export
|
||||
leaves lock files the app holds while it runs out of the seed, but never a
|
||||
document or selected path, listing them in its limitations and README; a
|
||||
start from a bundle whose computer never gets ready names the files its
|
||||
seed holds by a profile lock's name, as a document lock or as a
|
||||
`<file>.lck` beside a seeded file.
|
||||
- `check_build_task` reads the one app's `data/get` through the card's
|
||||
child URL, takes the state views beside its files and evaluates the task's
|
||||
checks with `evaluateTaskChecks`, one result per check. With `stage`, the
|
||||
@@ -106,6 +133,74 @@ and the recording and writes the record as Evidence.
|
||||
fails on what the seed's view shows. The controller writes a folder's file
|
||||
list to a file that REA reads through `data/get`, so a large bundle's list
|
||||
is not cut at the 1 MiB of a command's output.
|
||||
- Gaps of the build batches: an archive request takes up to 16
|
||||
`extra_packages`, archive package names validated as its `package` is,
|
||||
installed beside the app and listed in `start_build_computer`'s result
|
||||
(a `.deb` request's `dependencies` are listed there too), for a runtime
|
||||
piece the app needs that its package does not install (MyPaint's SVG icon
|
||||
loader `librsvg2-common`, which GTK only recommends; a Java 17 for
|
||||
Freeplane, whose launcher refuses noble's Java 21). The export takes them
|
||||
as repeatable `--extra-package` and installs them beside the app, and the
|
||||
build export passes them, and a `.deb` request's `dependencies` too, so a
|
||||
`.deb` apt also offers no longer loses them when it is installed by name.
|
||||
The limitations and the README name them, leaving out only what the
|
||||
bundle installs anyway: the app's own package and, when it is installed
|
||||
from its `.deb`, the dependencies the `Packages` line names. A package the
|
||||
captured `.deb` lists only as one alternative stays, since apt may pick
|
||||
another, such as `openjdk-17-jre | java-runtime`.
|
||||
- Gaps of the third batch's GnuCash build: the build bundle installs
|
||||
`dconf-cli`, so the capture reads the app's dconf settings, such as
|
||||
GnuCash's "Show tips at startup" unticked before `seed`, and the seed
|
||||
keeps them; an export whose dconf database changed by the seed but could
|
||||
not be read names it, with the read error, in its limitations. A
|
||||
`<file>.lck` or `<file>.LCK` beside a file the capture recorded in the
|
||||
same folder, as GnuCash's `household.gnucash.LCK`, is a lock left out of
|
||||
the seed; a lone `notes.lck` is seeded.
|
||||
- Gaps of the fourth batch: a desktop entry that is not reverse-DNS names
|
||||
the environment whole, without a trailing version, so `glabels-3.0` gives
|
||||
`glabels` rather than `0`, in the build computer and the export alike. The
|
||||
capture launches the app with `LIBC_FATAL_STDERR_=1`, so a glibc abort's
|
||||
reason reaches the app-exit error. A `.<file>.lock` or `.<file>.lck` beside
|
||||
its file, as Grisbi's `.household.gsb.lock`, is a lock too, left out of the
|
||||
seed and its text seeds; a lone `.notes.lock` is seeded. A seeded
|
||||
LibreOffice `registrymodifications.xcu` ships without its `RecoveryList`
|
||||
items, which started an Impress bundle into document recovery, and a
|
||||
limitation and the README name the file. A checkpoint ranks caches and
|
||||
browser-engine storage last under a selected folder too, unless named
|
||||
themselves, so LibreOffice's icon cache no longer fills `changed_files`.
|
||||
- Gaps of the fifth batch: a checkpoint names first the files the app's
|
||||
window titles have named so far, which the session now hands each
|
||||
checkpoint, so a document saved and no longer held open (Gnumeric, LyX,
|
||||
Tiled) leads; then files selected themselves; then those held open, under
|
||||
a selected folder or in state directories; then the rest; then caches and
|
||||
browser storage, which now include a whole `QtWebEngine` profile and
|
||||
Chromium's `Visited Links`, `Platform Notifications` and `user_prefs.json`.
|
||||
Example prompts name the app, and the export's limitations say when a
|
||||
task's prompt names neither the app's title, environment nor package: a
|
||||
solving agent's shell cannot see the computer's files. The unowned paths
|
||||
limitation counts files or folders.
|
||||
- Gaps of the published bundles: app-state logs are retained because their
|
||||
names alone do not distinguish diagnostic output from user history or
|
||||
database writes. Locks remain excluded under the lock ownership rules.
|
||||
LibreOffice's recovery list items are found with the shared XML parser and
|
||||
cut by their source ranges, so quoting, spacing, comments and CDATA cannot fool the match,
|
||||
and a registry that is not well-formed ships unchanged.
|
||||
- Gaps of the seventh batch: a window title names a file only by its whole
|
||||
name, or its `~/` or absolute path, never by a folder of a path it shows,
|
||||
and an extensionless name only standing alone; files under `~/.cache` and
|
||||
dconf's databases are never named. CherryTree's title, which shows
|
||||
`/home/user/Documents`, made `~/.cache/dconf/user` a second document, so
|
||||
its bundle opened none; the state role and the checkpoint ranking share
|
||||
the fix. VYM's `<map>.vym.lock` beside the map is a lock too, while a
|
||||
project's `Gemfile.lock` beside its `Gemfile` stays seeded.
|
||||
- Gaps of the eighth batch (Poedit): a `*.lock` or `*.lck` directly in the
|
||||
home and Lucene's `write.lock` anywhere are locks; a lock or log never
|
||||
becomes an owned path, is never named among the unowned paths, and makes
|
||||
no folder count as held open, so neither the capture nor the export points
|
||||
`state_paths` at the home. A seed file keeps its permission bits at the
|
||||
seed where the capture recorded them, through the module's `SEED_MODES`,
|
||||
so a `0600` file an app checks boots `0600`; a file the capture never saw
|
||||
change has no recorded mode.
|
||||
- The witness reads the build computer's bounded action log: its stage rules
|
||||
use the log's count and the last applied action of each kind, and the
|
||||
record holds the entries the log keeps, `actions_dropped`, and a
|
||||
|
||||
Loaded 100 of 914 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user