Compare commits

...
Author SHA1 Message Date
Kaoru0822andClaude Opus 5.5 abd99a4ce7 fix(javascript): keep selected-input filesystem failures typed
A selected directory that is readable but not searchable passed the R_OK
selection check, then every entry lstat failed and the result became a
generic artifact I/O failure. The selection owner now checks search
permission for directories and reads the selection metadata inside its
classifier, so EACCES/EPERM from realpath, lstat or access is a host
access denial with the selected path and system code.

Host filesystem failures that no narrower owner classifies no longer
drop their facts: EMFILE/ENFILE become a retryable capacity constraint,
and other errno failures keep artifact I/O with the host message and
system_code, syscall and path diagnostics.

Fixes #6116
Fixes #5991

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 04:09:35 +00:00
Kaoru0822andClaude Opus 5.5 4a4bbab3c3 fix(cli): keep committed evidence bundle receipts after cancellation (#6221)
Summary delivery with --evidence_output wrote the bundle, then let the
command's close/cancellation check replace the result. A SIGINT/SIGTERM
during staging cleanup after commit returned typed cancellation without
the receipt, and a persistent staging cleanup failure after commit was
rewrapped as a provider cleanup error that dropped published_path.

Every --evidence_output command now selects its view first and publishes
through publishEvidenceDelivery, the owner inspect-managed-members already
used. Post-commit cancellation keeps {path, bytes} under
details.diagnostics.evidence_bundle; incomplete cleanup keeps
details.published_path and bytes; a cleanup retry that succeeds returns
the normal receipt; pre-commit cancellation creates nothing and names
the command's operation.

Fixes #6095

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:32:26 -07:00
Kaoru0822andClaude Opus 5.5 e5d2805b42 fix(javascript): keep unmapped captured runtime scripts unknown (#6214)
A captured script whose bytes matched no static digest was reported as
high-confidence unmatched even when no automatic or caller-declared
mapping applied to its location in any static layer. The matcher now
computes mapping presence once while locating candidates and shares one
no-candidate classification between the captured-source and source-free
branches, so an unmapped location stays unknown with
no-authorized-location-mapping and is not counted as unmatched.

Fixes #6061.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:32:10 -07:00
morluto 6f28b3633b Merge remote-tracking branch 'origin/main' into codex/legacy-cleanup-followup-20261022 2026-10-22 11:11:42 +08:00
morluto c0eb612780 refactor(web): share retained text artifact metadata 2026-10-22 11:11:42 +08:00
morluto 27dc9735e4 refactor(managed): reuse the member comparison input contract 2026-10-22 11:11:42 +08:00
morluto 51e0df97e9 refactor(javascript): own application node merging in the graph domain 2026-10-22 11:11:42 +08:00
Kaoru0822andClaude Opus 5.5 292fd532c9 fix(ghidra): retry retained language catalog closes before admission (#6210)
The language catalog kept failed .ldefs closes in a module-global set that
only a later catalog read retried, and the provider returned a cleanup error
bound to no owner. Registry admission retries provider close before profile
resolution, so the retained handle was never retried and the original error
stayed incomplete forever.

Read definitions through the provider's caller-owned inspection scope with the
shared regular-file owner used by the seed and extension readers. A failed
close is retained as an exact lease in that scope, provider close and the next
catalog admission retry it, and the translated error is bound to the lease so
confirmed release reopens the same registry.

Fixes #6133

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:10:25 -07:00
Kaoru0822andClaude Opus 5.5 aa7d960ef5 fix(process): settle owned cleanup with the launcher's own exit proof (#6205)
* fix(process): settle owned cleanup with the launcher's own exit proof

When owned process-group verification fails while the supervised
launcher is still mid-exit, the supervisor now waits up to the kill grace
for its own child-exit observation and verifies once more after it
arrives. Verification is not repeated when the exit was already observed
before cleanup started, so there is no new evidence and the original
failure is kept. Nothing is signaled based on the wait.

Fixes #6134

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(process): bound Hopper session cleanup attempts by exit evidence

The fake Hopper launcher exits after its shutdown acknowledgement. When
the supervisor first observes that exit during a failed verification, it
verifies once more, so the first close makes one or two attempts depending
on timing. The test now asserts that bound. Later session retries, made
after the exit was already observed, make exactly one attempt each.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:10:07 -07:00
郭立 Guo Li 0b7213c890 perf(mcp): defer analysis runtime after catalog discovery (#4424)
Serve build-recorded default compact and explicit full catalogs, then materialize canonical analysis handlers on first use. Keep transport, Evidence delivery, profile identity and caller choices consistent. Share sealed MCP server ownership between eager and deferred lifecycle paths.

Validate 125 focused cases, schema/contract repeats, negative controls, builds/static/docs checks and latest-main integration. Record 72 real SDK task trials with independent Rust metadata oracles and whole-family resource bounds; disclose shifted first-RPC cost and unchanged catalog tokens. Qualify the real Rizin small-target debug lifecycle separately. Automated review findings addressed; Codex review unavailable due repository usage limits.
2026-10-22 03:07:31 +00:00
morluto 63fe0eb5db refactor(electron): reuse retention and capture contracts 2026-10-22 10:57:27 +08:00
morluto ddce4bb446 refactor(javascript): centralize source coordinate operations 2026-10-22 10:57:27 +08:00
morluto dd3497e133 refactor(javascript): reuse argument binding lookup 2026-10-22 10:46:25 +08:00
morluto 4f54379831 refactor(json): reuse shared parser at CLI and shape boundaries 2026-10-22 10:46:25 +08:00
morluto d77bc0e8a0 refactor(cli): share analysis snapshot option contract 2026-10-22 10:33:38 +08:00
morluto 527ade245a refactor(views): derive layout summary fields from source contract 2026-10-22 10:33:29 +08:00
morluto dbcec4cf56 refactor(javascript): share result binding projection and facts 2026-10-22 10:33:18 +08:00
morluto 34fd7bdf7d refactor(reference): share resource failure projection 2026-10-22 10:19:28 +08:00
morluto 81ab0ddc95 refactor(managed): derive verification declaration facts from their owner 2026-10-22 10:19:16 +08:00
morluto 306ca984bc refactor(electron): share observed process and window schemas 2026-10-22 10:19:07 +08:00
morluto dd46a13dec refactor(config): share HTTP listener port contract 2026-10-22 10:18:57 +08:00
morluto ce5bc8cb01 refactor(domain): consolidate projection and verification digests 2026-10-22 10:11:02 +08:00
morluto b88bdfccd2 refactor(evidence): share profile and completion digest owner 2026-10-22 10:10:58 +08:00
morluto 34aa22d0aa refactor(javascript): use shared canonical identity primitives 2026-10-22 10:10:55 +08:00
morluto 719d56ebfe fix(evidence): preserve provider execution provenance across workflows 2026-10-22 10:02:31 +08:00
morluto 87c8086fc1 refactor(managed): reuse canonical JSON digest owner 2026-10-22 09:52:58 +08:00
morluto eab4e47916 refactor(ghidra): share session startup observation checks 2026-10-22 09:52:49 +08:00
morluto db87917daa refactor(native): use canonical deadline defaults 2026-10-22 09:52:40 +08:00
morluto 183b4d4e7e refactor(managed): share metadata token schema 2026-10-22 09:33:58 +08:00
morluto 00819258a7 refactor(browser): separate bundle state from AST inspection 2026-10-22 09:33:58 +08:00
morluto c465ff5a81 refactor(evidence): share canonical ASCII ordering rules 2026-10-22 09:21:54 +08:00
morluto 1ac7ce3f3b refactor(native): share call observation outcome schema 2026-10-22 09:21:54 +08:00
morluto 55f5c8db69 refactor(kuna): centralize installation cancellation projection 2026-10-22 09:21:54 +08:00
morluto 5b0373db11 refactor(browser): map artifact failures at one boundary 2026-10-22 09:21:54 +08:00
morluto 73be86c39e fix(android): decode guardian output as UTF-8 streams 2026-10-22 09:11:44 +08:00
morluto 8dbe92a4a3 refactor(reference): centralize source inventory rules 2026-10-22 09:11:44 +08:00
morluto 5a28a147f1 fix(hopper): preserve streamed Unicode lease owner identities 2026-10-22 09:11:44 +08:00
morluto 13a8640204 fix(browser): observe fetch settlement after synchronous abort 2026-10-22 09:03:51 +08:00
morluto 09b29436f4 refactor(snapshot): share persisted execution projection 2026-10-22 09:03:51 +08:00
morluto 421d527bfe Merge remote-tracking branch 'origin/main' into codex/legacy-cleanup-followup-20261022 2026-10-22 08:52:56 +08:00
morluto 24bd2b989a refactor(browser): derive comparability once per capture pair 2026-10-22 08:52:56 +08:00
morluto b2fad362f2 fix(browser): stop expired work and release deadline resources 2026-10-22 08:52:56 +08:00
morluto 247c8f4eab refactor(javascript): own property capture translation 2026-10-22 08:52:56 +08:00
morluto adfde012ec refactor(readiness): share canonical stage validation 2026-10-22 08:52:56 +08:00
Jay-Alexander Elliot 57fd3ea5d8 feat(cli): summarize managed members with durable Evidence paging (#5167)
Fixes #5148.

Add opt-in durable managed member summaries and authenticated paging while preserving complete default output, original Evidence, cleanup ownership and queued cancellation.

Verified with bounded real Newtonsoft/Redux/Rust tasks, independent oracles, 556 focused tests and the expanded domain gate; paired token estimates and latency tradeoffs are recorded in experiments/analysis-efficiency/managed-cli.md.
2026-10-22 00:43:30 +00:00
morluto d8948efb81 refactor(mcp): bind Electron provider failures at registration 2026-10-22 08:40:36 +08:00
morluto 3966c92c71 refactor(ghidra): derive reference facts from shared schema 2026-10-22 08:40:36 +08:00
morluto 1fbfbf74ef refactor(gdb): own command record snapshots and stream groups 2026-10-22 08:40:36 +08:00
morluto 2604059961 refactor(process): share decoded NDJSON framing 2026-10-22 08:35:20 +08:00
morluto 6b44e35bec refactor(managed): own successful PE inspection identity 2026-10-22 08:35:20 +08:00
morluto 20bf7d957f refactor(setup): reuse desired registration per document snapshot 2026-10-22 08:35:20 +08:00
morluto c9f95eaf90 refactor(javascript): own graph Evidence envelope validation 2026-10-22 08:27:39 +08:00
morluto a2805bc934 refactor(managed): share artifact and token identity schemas 2026-10-22 08:27:39 +08:00
morluto b7529304f0 refactor(browser): centralize shared CDP observation facts 2026-10-22 08:27:39 +08:00
morluto 22c4b528d2 Merge remote-tracking branch 'origin/main' into codex/legacy-cleanup-followup-20261022 2026-10-22 08:20:30 +08:00
morluto 1158dc2a94 refactor(process): own worker frame wait lifecycle 2026-10-22 08:20:30 +08:00
morluto 2765fc12bb refactor(browser): share composed artifact cleanup ownership 2026-10-22 08:20:30 +08:00
gensokyo-dev 18669641e9 test(browser): select a bounded service-worker setup deadline (#6186) 2026-10-22 08:16:34 +08:00
morluto cdd718ffb0 refactor(inputs): own absolute path validation in shared contracts 2026-10-22 08:13:46 +08:00
morluto c5c5ff45aa refactor: import shared limits and projection helpers from their owners 2026-10-22 08:13:46 +08:00
morluto 5da3b7c393 refactor(asar): centralize read failure and cancellation semantics 2026-10-22 08:13:46 +08:00
morluto 2451e187be test(prompts): isolate capture admission regression 2026-10-22 07:51:42 +08:00
morluto 5e6529521c Merge remote-tracking branch 'origin/main' into codex/legacy-cleanup-followup-20261022 2026-10-22 07:49:01 +08:00
morluto 7cec547ecc fix(prompts): suggest only admitted process capture evidence 2026-10-22 07:49:00 +08:00
morluto c1a0561bf3 refactor(mobile): retain inventory sources at the projection boundary 2026-10-22 07:48:39 +08:00
morluto fafc1881b5 refactor(managed): return singular admitted evidence records 2026-10-22 07:48:39 +08:00
morluto a59abe932e refactor(evidence): centralize comparison identities and source recording 2026-10-22 07:45:47 +08:00
morluto 452e3ccad1 refactor(javascript): own source range validation once 2026-10-22 07:45:47 +08:00
8413ec08f7 fix(process): report the effective regex heap and uncertain signal retry (#6099)
* fix(process): report the effective regex worker heap

Node gives --max-old-space-size, including NODE_OPTIONS, precedence over
the worker's 128 MiB resourceLimits request. Name that effective
old-generation heap and stop saying the request has no runtime override.
The matching deadline stays a fixed cap.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): keep SIGXCPU and SIGXFSZ retries uncertain

The signal does not prove the retained rlimit was exhausted, so an
unchanged retry may succeed. Project that retry as possible instead of
saying it fails the same way.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): leave percentage heap overrides unestablished

--max-old-space-size-percentage takes precedence over the absolute flag
in either order. Node computes that MiB from startup memory, which a
later read does not recover, so the effective heap stays unknown instead
of the 128 MiB request or an absolute flag.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): read launch NODE_OPTIONS, not process.env

A preload can rewrite process.env.NODE_OPTIONS after V8 has applied the
original flags, and those flags are not copied into execArgv. Use the
initial environment block when it can be read, and leave the effective
heap unestablished when that provenance cannot be recovered.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): leave env-file heap overrides unestablished

--env-file and --env-file-if-exists can supply NODE_OPTIONS when that
variable was absent from the initial environment. The file is not in
/proc/self/environ, so a missing entry is not the 128 MiB request.
An initial NODE_OPTIONS is still parsed, because Node does not let the
file replace it.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): leave --max-heap-size old generation unestablished

A positive --max-heap-size or --max_heap_size sets the total heap, not the
old generation, and can stay below the 128 MiB worker request when an
old-space flag is also present. The effective old generation stays
unestablished while that value is in effect. Zero or empty clears it.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): leave config-file heap options unestablished

--experimental-config-file and --experimental-default-config-file can
apply a heap percentage from a file that is not launch provenance. The
effective old generation stays unestablished when either flag is present,
including beside an absolute --max-old-space-size.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): read launch exec argv from the command line

process.execArgv can be cleared after V8 applies --max-old-space-size.
Linux recovers those tokens from /proc/self/cmdline and leaves the heap
unestablished when that vector cannot be separated from the program entry.
Heap probes compare pinned absolute limits instead of a percentage of host memory.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): leave a title-overwritten command line unestablished

process.title and --title replace /proc/self/cmdline with the title.
A buffer without a program entry is not an empty option list, so the
heap stays unknown instead of the 128 MiB request. The command-line
probe does not read /proc off Linux.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 07:40:14 +08:00
morluto 603a7d022c refactor(process): share capture evidence admission 2026-10-22 07:37:21 +08:00
morluto b2dc45006d refactor(cli): share registered command traversal 2026-10-22 07:37:21 +08:00
morluto 1828cf87a0 refactor: remove redundant contract and syntax definitions 2026-10-22 07:37:21 +08:00
morluto a73eac190b refactor: remove obsolete forwarding APIs and unify CI contracts (#6181)
* refactor: remove obsolete internal forwarding APIs

* refactor(ci): centralize failure classification contracts
2026-10-22 07:30:54 +08:00
0e5c511c01 fix(electron): follow absolute symlinks that stay inside the framework (#3587)
* fix(electron): follow absolute symlinks that stay inside the framework

An absolute symlink target is now passed to relativeInside(root,
target), and a null result still ends the walk as an escape. When the
target lies inside the root, resolved is cleared and the root-relative
pieces are queued on pending, which replaces the path walked so far with
that absolute target. Later hops stay under the hop limit and the
existing lstat containment checks. Provider tests now cover an absolute
Versions/Current that stays on in-framework version B and matches the
relative bundle's resolved path and SHA-256, an absolute Current outside
the framework, and an absolute in-framework link whose next hop leaves
the framework; those last two still surface an escape error.

Fixes #3380

* test(electron): cover absolute framework symlink cycles

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-22 07:21:37 +08:00
2e6b38cef0 feat(environment): render more read tools from the state and describe responses (#5352)
* feat(environment): render more read tools from the state and describe responses

Keep main's environment serving and fold in coverage for non-entity reads,
response summaries, and MCP tool annotations.

Squashed rebase of #5352 onto main.

* fix(environment): keep rendered documents and quoted samples inside their budgets

A recorded body of exponential numbers can render past 256 KiB and turn a
working read into a state size error, so that document stays a recorded replay.
Description samples are measured after JSON quoting, and the replay-fallback
catalog check uses a tool count the longer response descriptions still separate.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(environment): pin the replay card this branch serves

The replay-only card test pinned main's 11,131-byte card. This branch's descriptions name each tool's recorded responses, so the card it serves is 12,818 bytes; the pin and its name follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 07:08:44 +08:00
d7ca93cc2c fix(artifacts): name the ASAR header admission budget (#6172)
Keep the 16 MiB ASAR header/index ceiling fixed and report that budget,
the lack of a runtime override, and that source selection does not bypass
header admission.

Refs #5910

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 06:33:09 +08:00
Afloat 82e4e032df fix(artifacts): complete positional ZIP reads (#4414)
fix(artifacts): complete ZIP positional reads
2026-10-22 06:13:24 +08:00
Abdul Samad Siddiquiandmorluto ca2ca16146 fix(dotnet): reject unfinished CIL prefix chains (#4416)
* fix(dotnet): reject unfinished CIL prefix chains

* test(dotnet): cover unfinished prefixes in fat method bodies

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-22 06:13:10 +08:00
xjh 14c4c2a1d7 fix(managed): preserve observed method header differences (#3814) 2026-10-22 06:12:55 +08:00
Hemang VarshneyandHemang Varshney 4842f23765 fix(source): retain CommonJS requires spelled as exact no-substitution templates (#4511)
* fix(source): retain CommonJS requires spelled as exact no-substitution templates

Admit expression-free template arguments at the CommonJS require gate and
read their single cooked quasi through the shared exact-literal reader.
Scope is the require path only: static ESM template declarations keep their
parse failures and dynamic import() keeps the explicit unknown/partial
<dynamic-import> relationship with no invented target.

Refs: #4382

* fix(source): admit TypeScript-wrapped exact require arguments via the shared literal reader

Address review: the require gate matched the outer AST node, so
runtime-transparent TS wrappers (as const, !, satisfies) around exact
strings or expression-free templates were still silently omitted even
though readExactJavaScriptLiteral unwraps them. Remove the gate and let
the shared exact-literal reader own argument exactness; computed
arguments remain silent and dynamic import() behavior is unchanged.

Refs: #4382

---------

Co-authored-by: Hemang Varshney <218273197+hemv-857@users.noreply.github.com>
2026-10-22 06:12:42 +08:00
7721d59e1a fix(adb): normalize absent installer package sentinels (#4073)
* fix(adb): report a null installer declaration as an absent installer

Package Manager prints its String fields by concatenation, so a package
without a recorded installer shows `installerPackageName=null` in
`dumpsys package`. The projection treated only an empty value as absent
and forwarded the text "null" as a present installer identity, which a
consumer cannot tell apart from a package literally named "null" (#3943).
`versionName` is printed the same way and had the same gap.

The parser now maps the empty value and the `null` sentinel of both
String fields to the nullable result's null at the producing boundary;
a reported installer such as com.android.vending is kept unchanged.

Validation: parser unit tests for the sentinel, empty and missing
installer lines and the absent version name, plus a provider-level
regression through the inspect_adb_package operation; three of them fail
on main and pass here. The issue's four CLI controls through
`rea inspect-adb-package` against a stub adb return JSON null for the
sentinel, empty and missing cases and keep com.android.vending. Typecheck,
lint and module boundaries pass.

Closes #3943

* fix(adb): keep the null sentinel handling to the installer field

Review feedback on #4073: a manifest can declare the literal string
"null" as android:versionName, and dumpsys prints it exactly like an
absent value, so mapping versionName to null would turn a real version
into absence. Only installerPackageName, where no package can carry that
name, treats the printed null as the absent installer. The test for the
version name now pins the retained text.

* test(adb): establish permission inventory in null-installer fixture

Main now reports partial coverage when the requested-permission
inventory is not established (9534e42ec). Give the null-installer
fixture a requested permissions section so it still checks a
complete projection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 06:11:49 +08:00
76dbc32f39 fix(environment): bound state reads and retain cleanup ownership (#6158)
* feat(environment): extract the initial state a capture's reads observed

Add the environment-state analysis view. From the parents the environment
manifest accepts, it extracts the data the capture's reads observed before
the first related write: entity types with an identity field (proved by a
path parameter or inferred from an identity name), entities with their
recorded values and provenance, documents for written non-entity paths, and
a render plan per read tool that is kept only when it reproduces the tool's
latest initial recordings from the state; every other read tool is a
recorded view with the reason. The Evidence is always inferred.

Response-body decoding moves to a domain owner shared with replay, exact
JSON parsing moves to the owner of the exact-number policy, the manifest and
state views share parent admission and record grouping, and
projectAnalysisView takes its accumulators as one object.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): bound state at redacted writes; infer identity only from items

A scenario write whose URL was redacted has no request line, so it was
dropped and reads after it counted as initial state. Such a successful
write now joins the timeline with an empty path, whose root relates to
every type, so it ends every type's state; a limitation counts them.

A list whose recordings were all empty passed the "every listed item
carries it" check vacuously and published an identity field nothing
showed; it now needs at least one item, else the view stays recorded
as no-identity.

A value that differed between two request lines of one item tool, such
as a query variant, was called volatile, and the gate then substituted
each recording's own value; only repeats of one request line now show
volatility, so differing lines go through fields-differ.

List membership is compared only while a list can still be the whole
collection, and merged entities are indexed by type and collection once,
so paged captures no longer cost pages times entities (8,000 pages of
40,000 entities: 5.7 s to 0.23 s).

Docs and the tool contract say scenario state keeps the capture's
redaction markers and how redacted writes bound it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep first sightings, one list pointer and linear field unions

Entities took the order of the first plan observed, and item plans run
before list plans, so a complete list read before its detail reads came
out reordered and lost "all" membership; each entity now keeps its
earliest recorded sighting.

A list plan reused the first recording's pointer for later recordings,
so a later response that was itself an entity wrapping a list was read
as that list; every recording must now locate the same list.

The field union scanned its ordered list for every key, quadratic in an
object's width; a set now answers membership.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep post-write values and partial lists out of the initial state

A value that changed between repeats of one request line was named
volatile whenever no write under the type's own root lay between, so a
write under another root (for example POST /api/dashboards/db before a
second GET /api/search) left its effect in the initial state. Any
recorded write between the two observations now leaves every tool of the
type recorded with reason fields-differ instead.

A list was published with membership "all" even when a total or count
envelope member exceeded the number it listed. Such a counter now makes
the membership "recorded".

Also drop a stale doc comment on ObservedEntity.order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(environment): scope item-shaped and deleted written paths out of documents

State documents are held only for list-shaped paths a POST, PUT or PATCH
tool writes. Reads of item-shaped written paths and of paths that are only
deleted stay recorded views; the guide now says so and the spec defers them
to a later increment of #4933.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): count writes in flight when a value changes between reads

The volatility check compared write start positions with the two reads,
so a write already in flight when the earlier read started was missed and
its effect was named volatile. A write now counts when its interval
overlaps the span from the earlier read's start to the later read's end.

The check also ran once per changed field and scanned every write. It now
runs once per pair of observations, answered by a binary search over the
writes in timeline order and the latest end among each prefix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): catch cross-tool changes across writes; read only item totals

A value that changed across a write was caught only between repeats of
one tool's request line, so a list read before a write and an item read
after it put the post-write value into the initial state. Changes are
now classified per entity in timeline order after observation: across
any recorded write, a change between repeats of a line or between two
lines of the type rewrites the type (every tool recorded as
fields-differ); with no write between, a repeat's change is volatile.
The classification lives in environmentStateMerge.ts.

Any numeric member whose name contained "total" or "count" counted as
an item total, so total_pages, account_id or page_count made complete
lists partial. Item totals are now members whose name tokens include
total or count and none of page, pages or per; a string of digits counts
as a number; and a set has_more, next or next-page token member also
marks the list partial.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep post-write observations out of initial state

* fix(environment): retain field provenance and bound state inference work

* feat(environment): serve tool calls from the environment state

`environment-serve --state <state.json>` serves an environment from the
initial state an environment-state view extracted. Read tools whose views
are state-backed answer from a live state store: item views render the held
entity into the recorded envelope, list views render the collection or the
recorded members, and document views return the held value; a missing entity
or one lacking a required field is refused, and requests the state cannot
answer fall back to their recordings with the reason. The /agentenv data
plane implements data/reset, data/add (a rea-state/v1 document as a data
part, base64 bytes, a file:// path or an https URL, validated and replaced
atomically) and data/get, and the card advertises those operations and an
intake declaration. Stage 1 is read-only: write tools are not served in
state mode. Without --state nothing changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(environment): record verification after merging the state view's review fixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(environment)!: serve the environment state by default

environment-serve derives the environment state at startup by running the
environment-state view in-process on the capture with the manifest's
template rules, so an environment comes with its state and a user supplies
nothing extra. The derived Evidence is the same one inspect-analysis-view
produces by hand. --state is removed; --replay-only serves exactly the
stateless replay of main. When the state cannot be derived, or its catalog
does not fit the discovery budget, the server starts in replay mode, logs
the reason and reports it in the stop summary's `state`. Exported bundles
serve the state by default too: export derives it the same way, so the
verifier's tool count and checked answer match what is served, and the
README describes the served mode.

BREAKING CHANGE: environment-serve answers read tools from the derived
state and does not serve write tools unless --replay-only is given; the
stop summary reports `state` instead of `state_evidence_id`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): bound data-plane replies, keep batch order, cancel intake on stop

- One /agentenv response is held to 64 MiB: replies are measured as they
  are produced and one past the budget becomes a -32000 error stating it.
- Every message of a batch enters the arrival-order queue on arrival, so
  another request's reset never lands between them.
- Stopping the server, or a caller leaving, cancels the active download
  and answers queued calls `cancelled` without running them.
- file:// URIs name only this host: another host or a network share is
  refused before anything is opened.
- A loaded view value may not give an entity another identity.
- List answers refuse a member lacking a field every recording carried,
  as item answers do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep bodies too deep for the state's nesting out of the state

A recorded body at the JSON depth limit was accepted by extraction, then
nested a few levels deeper as a document or entity value, so sealing the
state Evidence threw and environment-serve and environment-export stopped
instead of falling back. stateBodyJson, the one rule extraction and
serving share, now treats a body nesting deeper than the limit minus 16
levels as unusable, so its tool stays a recorded view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): measure data-plane replies before building them

83fcc739 bounded one /agentenv response to 64 MiB, but it still
serialized each reply whole before measuring it, so a batch of data/get
calls on a large state built every refused reply in full only to drop
it. Each reply is now measured in bounded JSON parts (the shared
jsonParts encoder), its parts kept only while it fits; a reply past the
budget is counted for its exact reply_bytes but never assembled. A test
checks that a refused read is never handed to JSON.stringify whole and
that its reply_bytes is exact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): release batch replies as they are encoded; judge exact numbers by value

answerBatch kept every settled reply in its pending array until the
batch ended, so a batch alternating data/add and data/get held each
loaded state alive; each reply now leaves the queue as it is encoded.

The exact-number policy judged a number by its recorded spelling, so a
state loaded with 1e20 came back from data/get as
100000000000000000000, which data/add refused, breaking the promise
that data/get output loads back unchanged. A number is exact only when
both its recorded spelling and the one serialization writes are safe,
so integers from 2^53 below 1e21 are refused in any spelling; replay
keeps such bodies as recorded text. A domain test checks that every
accepted number is accepted again once written back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep room for refusals and framing in the reply budget

The response budget counted accepted replies only: a budget error that
replaced a reply, and a batch's brackets and commas, were not charged,
so near 64 MiB later refusals pushed the body past the advertised
limit. Every reply still to come now keeps room for its own budget
error, and a batch keeps room for its framing, so a refusal always fits
and the body never passes the budget. Reply ids and which messages are
answered come from one place shared by the replies and the reserve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): refuse a loaded state that data/get would write past the intake limit

data/add measured only the document it was given, while data/get
writes the state back with the members a document may omit (types, the
state Evidence id, view fields and record citations). A document just
under 32 MiB could therefore load and be reported larger than any intake
accepts, breaking the data/get then data/add round trip. replace now
measures the state as data/get writes it, part by part, and refuses it
past the limit, leaving the state unchanged. The limit moves to the
state document module, so the application store can read it; the
intake re-exports it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep merged export checks on the shared test graph

Main's export tests installed module mocks for the whole services
project, which reuses one module graph. A tarball read failure then
missed its importer, and a one-shot heap mock could be taken by another
file. Read those through bindings the tests replace for one case.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(environment): keep a state file whose close failed owned until it closes

A file:// data/add that could not close its descriptor dropped the handle,
and an admission failure whose cleanup close failed dropped its owner, so
nothing could retry the close or report it.

The read now runs through withOwnedRegularFile, and a failed close is
retained in a server-lifetime ArtifactResourceScope. The next file read
retries it first and answers -32000 while it is still open; inline and
https documents still load. Closing the served environment retries it again
and rejects with the unfinished close.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): attempt all state cleanup on close

* fix(environment): bound wide state JSON traversal

* fix(environment): scope cached state reply sizes to requests

* fix(domain): preserve JSON depth diagnostic guidance

---------

Co-authored-by: Edgar Arakelyan <edgar.arakelyan@scale.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 06:06:36 +08:00
Mohith DK f23066f0da fix(reconstruction): fall back to a kind-based title for blank graph labels (#6137)
Fall back to a kind-based obligation title when a graph label is blank

A whitespace-only application observation or semantic node label passed through ?? as the obligation title, and the ledger schema (trimmed, min length 1) then rejected the whole ledger. Use trim() || so a blank label takes the generated title.

Closes #6126
2026-10-22 05:53:42 +08:00
Abel YagubyanandAbelo9996 cbbd317fb5 fix(process): index late scenario events in validation issues (#6160)
Co-authored-by: Abelo9996 <Abelo9996@users.noreply.github.com>
2026-10-22 05:53:22 +08:00
Abel YagubyanandAbelo9996 d54c4345d3 fix(browser): report zero decoded bytes for undecodable gRPC-web text (#6159)
Co-authored-by: Abelo9996 <Abelo9996@users.noreply.github.com>
2026-10-22 05:53:13 +08:00
bdf0be87c6 fix(mcp): name response-byte and startup ceilings in recovery (#6005)
* fix(mcp): name response-byte and startup ceilings in recovery

Name REA_MCP_MAX_RESPONSE_BYTES, its effective value, the 10485760 byte
floor, and process restart when the stdio response budget is hit, and
state that the setting does not raise Node's string ceiling. Name fixed
MCP startup phase budgets when those deadlines fire, and keep Codex's
30 second startup figure as client guidance.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(mcp): distinguish string ceilings and keep dossier recovery

Name REA's reserved string limit separately from Node's ceiling, restore
detail:summary discovery for an oversized complete evidence bundle, and
apply the doctor deadline sentence when binary_session itself times out.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(mcp): keep retained SDK errors inside the text budget

Quoted SDK validation diagnostics expand when recovery JSON is escaped
into MCP text. Shorten only that preview so the retained-evidence
reference still arrives as parseable error content.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(mcp): keep export advice when a summary exceeds the response budget

An oversized get_evidence_bundle summary no longer repeats detail: summary.
export_evidence_bundle still writes the retained bundle outside one MCP frame,
including when a larger byte budget cannot raise the string ceiling.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style(mcp): format the SDK diagnostic preview return

oxfmt rejected the fitted-preview ternary in EvidenceMcpServer.ts, which failed Static checks and the CI required gate.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 05:48:56 +08:00
0155b89953 fix(browser): name web-bundle budgets and recover web deadlines (#6036)
* fix(browser): name web-bundle budgets and recover web deadlines

Name the existing heap, per-script, and total web-bundle phases, and reject a per-script deadline above the total. Promote capture, CDP command, source-map decode, and source-map fetch deadlines at today's defaults. Name DevTools timeoutMs, and state that discovery, cleanup grace, byte budgets, and Electron hook retention have no runtime override.

Refs #5910

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): apply selected web deadlines to the owning phase

Keep HTTP and browser-socket discovery on the fixed discovery deadline so a
short command_timeout_ms starts at the handshake. Apply scenario
command_timeout_ms to launch startup and the primary connect session, and
keep service-worker restoration on the fixed 5000 ms grace. Omit
command_timeout_ms from recovery text when the operation does not accept it.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): retain scenario commands that finish after their deadline

A timed-out scenario command stays owned so cleanup can close a late
browser or context and restore a mutation that lands after the deadline.
Child storage replies use that deadline, scenario recovery names
command_timeout_ms in the capture JSON, and the session test connection
implements beginCleanupGrace.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): keep child command timeouts as the public failure

A nested command such as Page.enable that is delivered but never answered
was stored as protocol_error, hiding the command name, selected deadline,
and recovery. Store the typed timeout and assert that public error.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): keep runtime cleanup on the fixed grace

Switch runtime restoration to the cleanup grace before the first send so a
short command_timeout_ms cannot fail an otherwise successful observation.
Stop advertising command_timeout_ms on list_browser_targets, which never
bounds a post-discovery command.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(browser): prove a short command deadline cannot fail runtime cleanup

Drive restoration through the runtime fixture. A cleanup command that
outlives command_timeout_ms still succeeds, and a stalled restoration
names the fixed 5000 ms grace.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): name the effective source-map decode deadline

codecBudgetLimitation reported a fixed 20-second deadline after a
caller selected decode_timeout_ms. Result and Evidence limitations
now name that effective millisecond deadline.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): separate handshake and target-attach deadlines

A browser-level Target.attachToTarget no longer shares the WebSocket
handshake budget. Blocked service-worker attachment keeps discovery on
its fixed deadline and applies command_timeout_ms to the later handshake
and attach.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): name the web-bundle resource each runtime exhausts

Bun ignores the V8 old-space flag. A Windows Job reports the process
commit limit, and other Bun hosts no longer suggest raising max_heap_mb.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): cite the browser-socket discovery message budget

WebSocket discovery enforces the 64 MiB protocol budget. Timeout
recovery no longer advertises the 8 MiB HTTP document budget.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): bound the blocked service-worker check before discovery

The first registration check has its own fixed 10s deadline. Discovery,
handshake, and Target.attachToTarget stay on their separate deadlines.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(browser): name the operand that stopped web-bundle admission

Host heap pressure no longer claims the fixed result budget is exhausted.
A Windows Bun allocation before the commit limit still names that limit.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 05:47:38 +08:00
166fb0820f feat(environment)!: serve the environment state by default (#5351)
* feat(environment): extract the initial state a capture's reads observed

Add the environment-state analysis view. From the parents the environment
manifest accepts, it extracts the data the capture's reads observed before
the first related write: entity types with an identity field (proved by a
path parameter or inferred from an identity name), entities with their
recorded values and provenance, documents for written non-entity paths, and
a render plan per read tool that is kept only when it reproduces the tool's
latest initial recordings from the state; every other read tool is a
recorded view with the reason. The Evidence is always inferred.

Response-body decoding moves to a domain owner shared with replay, exact
JSON parsing moves to the owner of the exact-number policy, the manifest and
state views share parent admission and record grouping, and
projectAnalysisView takes its accumulators as one object.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): bound state at redacted writes; infer identity only from items

A scenario write whose URL was redacted has no request line, so it was
dropped and reads after it counted as initial state. Such a successful
write now joins the timeline with an empty path, whose root relates to
every type, so it ends every type's state; a limitation counts them.

A list whose recordings were all empty passed the "every listed item
carries it" check vacuously and published an identity field nothing
showed; it now needs at least one item, else the view stays recorded
as no-identity.

A value that differed between two request lines of one item tool, such
as a query variant, was called volatile, and the gate then substituted
each recording's own value; only repeats of one request line now show
volatility, so differing lines go through fields-differ.

List membership is compared only while a list can still be the whole
collection, and merged entities are indexed by type and collection once,
so paged captures no longer cost pages times entities (8,000 pages of
40,000 entities: 5.7 s to 0.23 s).

Docs and the tool contract say scenario state keeps the capture's
redaction markers and how redacted writes bound it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep first sightings, one list pointer and linear field unions

Entities took the order of the first plan observed, and item plans run
before list plans, so a complete list read before its detail reads came
out reordered and lost "all" membership; each entity now keeps its
earliest recorded sighting.

A list plan reused the first recording's pointer for later recordings,
so a later response that was itself an entity wrapping a list was read
as that list; every recording must now locate the same list.

The field union scanned its ordered list for every key, quadratic in an
object's width; a set now answers membership.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep post-write values and partial lists out of the initial state

A value that changed between repeats of one request line was named
volatile whenever no write under the type's own root lay between, so a
write under another root (for example POST /api/dashboards/db before a
second GET /api/search) left its effect in the initial state. Any
recorded write between the two observations now leaves every tool of the
type recorded with reason fields-differ instead.

A list was published with membership "all" even when a total or count
envelope member exceeded the number it listed. Such a counter now makes
the membership "recorded".

Also drop a stale doc comment on ObservedEntity.order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(environment): scope item-shaped and deleted written paths out of documents

State documents are held only for list-shaped paths a POST, PUT or PATCH
tool writes. Reads of item-shaped written paths and of paths that are only
deleted stay recorded views; the guide now says so and the spec defers them
to a later increment of #4933.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): count writes in flight when a value changes between reads

The volatility check compared write start positions with the two reads,
so a write already in flight when the earlier read started was missed and
its effect was named volatile. A write now counts when its interval
overlaps the span from the earlier read's start to the later read's end.

The check also ran once per changed field and scanned every write. It now
runs once per pair of observations, answered by a binary search over the
writes in timeline order and the latest end among each prefix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): catch cross-tool changes across writes; read only item totals

A value that changed across a write was caught only between repeats of
one tool's request line, so a list read before a write and an item read
after it put the post-write value into the initial state. Changes are
now classified per entity in timeline order after observation: across
any recorded write, a change between repeats of a line or between two
lines of the type rewrites the type (every tool recorded as
fields-differ); with no write between, a repeat's change is volatile.
The classification lives in environmentStateMerge.ts.

Any numeric member whose name contained "total" or "count" counted as
an item total, so total_pages, account_id or page_count made complete
lists partial. Item totals are now members whose name tokens include
total or count and none of page, pages or per; a string of digits counts
as a number; and a set has_more, next or next-page token member also
marks the list partial.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep post-write observations out of initial state

* fix(environment): retain field provenance and bound state inference work

* feat(environment): serve tool calls from the environment state

`environment-serve --state <state.json>` serves an environment from the
initial state an environment-state view extracted. Read tools whose views
are state-backed answer from a live state store: item views render the held
entity into the recorded envelope, list views render the collection or the
recorded members, and document views return the held value; a missing entity
or one lacking a required field is refused, and requests the state cannot
answer fall back to their recordings with the reason. The /agentenv data
plane implements data/reset, data/add (a rea-state/v1 document as a data
part, base64 bytes, a file:// path or an https URL, validated and replaced
atomically) and data/get, and the card advertises those operations and an
intake declaration. Stage 1 is read-only: write tools are not served in
state mode. Without --state nothing changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(environment): record verification after merging the state view's review fixes

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(environment)!: serve the environment state by default

environment-serve derives the environment state at startup by running the
environment-state view in-process on the capture with the manifest's
template rules, so an environment comes with its state and a user supplies
nothing extra. The derived Evidence is the same one inspect-analysis-view
produces by hand. --state is removed; --replay-only serves exactly the
stateless replay of main. When the state cannot be derived, or its catalog
does not fit the discovery budget, the server starts in replay mode, logs
the reason and reports it in the stop summary's `state`. Exported bundles
serve the state by default too: export derives it the same way, so the
verifier's tool count and checked answer match what is served, and the
README describes the served mode.

BREAKING CHANGE: environment-serve answers read tools from the derived
state and does not serve write tools unless --replay-only is given; the
stop summary reports `state` instead of `state_evidence_id`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): bound data-plane replies, keep batch order, cancel intake on stop

- One /agentenv response is held to 64 MiB: replies are measured as they
  are produced and one past the budget becomes a -32000 error stating it.
- Every message of a batch enters the arrival-order queue on arrival, so
  another request's reset never lands between them.
- Stopping the server, or a caller leaving, cancels the active download
  and answers queued calls `cancelled` without running them.
- file:// URIs name only this host: another host or a network share is
  refused before anything is opened.
- A loaded view value may not give an entity another identity.
- List answers refuse a member lacking a field every recording carried,
  as item answers do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep bodies too deep for the state's nesting out of the state

A recorded body at the JSON depth limit was accepted by extraction, then
nested a few levels deeper as a document or entity value, so sealing the
state Evidence threw and environment-serve and environment-export stopped
instead of falling back. stateBodyJson, the one rule extraction and
serving share, now treats a body nesting deeper than the limit minus 16
levels as unusable, so its tool stays a recorded view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): measure data-plane replies before building them

83fcc739 bounded one /agentenv response to 64 MiB, but it still
serialized each reply whole before measuring it, so a batch of data/get
calls on a large state built every refused reply in full only to drop
it. Each reply is now measured in bounded JSON parts (the shared
jsonParts encoder), its parts kept only while it fits; a reply past the
budget is counted for its exact reply_bytes but never assembled. A test
checks that a refused read is never handed to JSON.stringify whole and
that its reply_bytes is exact.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): release batch replies as they are encoded; judge exact numbers by value

answerBatch kept every settled reply in its pending array until the
batch ended, so a batch alternating data/add and data/get held each
loaded state alive; each reply now leaves the queue as it is encoded.

The exact-number policy judged a number by its recorded spelling, so a
state loaded with 1e20 came back from data/get as
100000000000000000000, which data/add refused, breaking the promise
that data/get output loads back unchanged. A number is exact only when
both its recorded spelling and the one serialization writes are safe,
so integers from 2^53 below 1e21 are refused in any spelling; replay
keeps such bodies as recorded text. A domain test checks that every
accepted number is accepted again once written back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep room for refusals and framing in the reply budget

The response budget counted accepted replies only: a budget error that
replaced a reply, and a batch's brackets and commas, were not charged,
so near 64 MiB later refusals pushed the body past the advertised
limit. Every reply still to come now keeps room for its own budget
error, and a batch keeps room for its framing, so a refusal always fits
and the body never passes the budget. Reply ids and which messages are
answered come from one place shared by the replies and the reserve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): refuse a loaded state that data/get would write past the intake limit

data/add measured only the document it was given, while data/get
writes the state back with the members a document may omit (types, the
state Evidence id, view fields and record citations). A document just
under 32 MiB could therefore load and be reported larger than any intake
accepts, breaking the data/get then data/add round trip. replace now
measures the state as data/get writes it, part by part, and refuses it
past the limit, leaving the state unchanged. The limit moves to the
state document module, so the application store can read it; the
intake re-exports it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep merged export checks on the shared test graph

Main's export tests installed module mocks for the whole services
project, which reuses one module graph. A tarball read failure then
missed its importer, and a one-shot heap mock could be taken by another
file. Read those through bindings the tests replace for one case.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(environment): keep a state file whose close failed owned until it closes

A file:// data/add that could not close its descriptor dropped the handle,
and an admission failure whose cleanup close failed dropped its owner, so
nothing could retry the close or report it.

The read now runs through withOwnedRegularFile, and a failed close is
retained in a server-lifetime ArtifactResourceScope. The next file read
retries it first and answers -32000 while it is still open; inline and
https documents still load. Closing the served environment retries it again
and rejects with the unfinished close.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-22 05:04:57 +08:00
Diya 3dbe314ada fix(javascript): preserve source-map preparation capability errors (#6149) 2026-10-22 04:24:31 +08:00
xiaofeilovecodingandxiaofeilovecoding f5acf82a78 fix(native): retain decoded zero-address Swift class references (#6069)
Co-authored-by: xiaofeilovecoding <fxy850328059@gmail.com>
2026-10-22 04:18:25 +08:00
morluto a721c42c07 fix(cancellation): bind retained errors to cleanup owners
Carry the capture handle cleanup lease through retry results and bind composed export failures to it. Bind aborted binary retirement errors to the failed close so successful later cleanup reveals the original cancellation.

Validation: 46 focused tests passed; npm run check passed. Four regression assertions fail on the original source. Full suite and real-provider workflows were not run.
2026-10-22 04:17:14 +08:00
087813fb88 fix(cancellation): preserve caller abort reasons through late finalization (#6143)
* fix(cancellation): preserve caller abort reasons through late finalization

Caller aborts that arrived during final provider, cleanup, or protocol
handling were dropped or replaced by I/O, cleanup, or success results.
Each affected path now samples the caller signal after its owner has
settled and returns AnalysisCancelledError carrying the exact
signal.reason, keeping any completed partial Evidence or cleanup state.

- Web script export: keep the exact reason for an interrupted output
  write, and honor a cancellation fact recorded before a retried
  capture close succeeds.
- Native value tracing and Hopper regex search: check the signal after
  the final provider reply or regex worker settles.
- Apple asset catalog: stop assetutil with SIGTERM so cancellation
  settles only after the helper exits.
- CDP observation: end an armed window on a fatal protocol failure.
- ADB bugreport: prefer cancellation over the staging-removal output
  error when the caller aborted.
- JavaScript recovery: check the signal after provider success.
- export-web-scripts CLI: run under command cancellation and forward
  the signal into the export workflow.
- Objdump and Rizin CLI: report cancellation after cleanup completes.
- Binary session: keep cancellation primary when previous-client
  retirement fails after abort.

Fixes morluto/rea#6042
Fixes morluto/rea#6043
Fixes morluto/rea#6048
Fixes morluto/rea#6049
Fixes morluto/rea#6057
Fixes morluto/rea#6060
Fixes morluto/rea#6078
Fixes morluto/rea#6080
Fixes morluto/rea#6108
Fixes morluto/rea#6111
Fixes morluto/rea#6115

* fix(cancellation): keep caller reasons through export rollback and commit

- Rollback failure after a caller abort now returns AnalysisCancelledError
  with the exact signal.reason, attaching the rollback failure as cleanup
  and retaining any published result as partial observation.
- A capture close retry that succeeds after abort returns cancellation
  instead of the stale cleanup diagnostic.
- An abort that lands during the final output commit returns cancellation
  carrying the completed manifest as partial observation.
- Apple assetutil stop test: abort and await the run in finally so a
  timed-out wait does not leave the child running, and skip on Windows
  where the JavaScript SIGTERM handler cannot run.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 35b247e9-c793-4b8f-979a-807c27112cf5

* fix(cancellation): bind export cancellations to cleanup and caller reasons

- A rollback-failure cancellation is bound to the retained cleanup lease,
  so a later successful close clears cleanup_incomplete instead of
  reporting a residual directory that no longer exists.
- mapExportFailure wraps the caller's own AnalysisCancelledError reason
  under export_web_scripts rather than returning it as the export's error.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 35b247e9-c793-4b8f-979a-807c27112cf5

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Copilot-Session: 35b247e9-c793-4b8f-979a-807c27112cf5
2026-10-22 04:15:16 +08:00
Alex GorevskiandCopilot 4e28166626 fix(cancellation): preserve caller abort reason in cancellation errors (#6144)
* fix(cancellation): preserve caller abort reason in cancellation errors

Several application, provider, and MCP boundaries constructed
AnalysisCancelledError, ArtifactReaderFailure, or
DetachedPgpSignatureError for an already-observed or newly-observed abort
without passing the caller's signal.reason as the error cause. The typed
result then reported cancellation with an undefined reason even though the
exact object supplied to AbortController.abort(reason) was still available.

Pass signal.reason as the cause at each producing cancellation site:
JavaScript artifact reconstruction and file abort checks, derived MCP
operation checkpoints, detached PGP verification, ASAR listing admission,
Dart AOT inspection and its provider guard, evidence-file analysis views,
binary layout and recorded crash admission, WASM inspection admission,
and the Kuna shared assembly-index wait.

Cancellation classification and cleanup behavior are unchanged.

Fixes morluto/rea#5935
Fixes morluto/rea#5944
Fixes morluto/rea#6100
Fixes morluto/rea#6101
Fixes morluto/rea#6110
Fixes morluto/rea#6113
Fixes morluto/rea#6121
Fixes morluto/rea#6131
Fixes morluto/rea#6132

* test(cancellation): assert the exact caller reason identity

Copied reasons satisfied toMatchObject, so the tests would pass even if the
caller's abort reason were replaced by a structurally equal copy. Capture the
rejection and assert the cause is the same object.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 35b247e9-c793-4b8f-979a-807c27112cf5

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 35b247e9-c793-4b8f-979a-807c27112cf5
2026-10-22 04:11:15 +08:00
JohnandClaude Opus 5.5 7ffae5a791 test(artifacts): cover fixed input-size recovery for Rust and IL2CPP (#6148)
#5633 gave Rust and IL2CPP input-size refusals input-allowance recovery
through fixedAllowanceOptions, but no public CLI check covered either
command, and IL2CPP had no remediation assertion at all. Add both
commands to the CLI input-limit matrix.

Go and WASM still carried a duplicated hand-written copy of the same
advice. They now use the shared "input" allowance recovery, so all four
commands name their fixed allowance from one owner.

The matrix also asserted not.toContain("evidence reply"), which the new
"evidence-reply" wording passes only because of the hyphen. Assert the
absence of the old advice text instead.

Fixes #5405

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 04:10:46 +08:00
KIEU TRONG KHANG 2aadcf7d04 fix(electron): report rejected CLI arguments with issue details (#5036)
* fix(electron): report rejected CLI arguments with issue details

Pass schema validation issues and submitted input to inputError in list-electron-targets and inspect-electron-page commands, matching the structured diagnostics returned by browser commands.

Fixes #3865

* test(electron): assert exit code 1 on rejected CLI arguments
2026-10-22 04:08:52 +08:00
amyanger b0a554cc3a fix(browser): read SAZ archives with zero-byte HTTP members (#5453)
Fiddler writes a zero-byte raw/NN_s.txt (or _c.txt) for a session that
never got that message. The decoder passed it to the HTTP parser, which
found no header/body separator and rejected the whole archive, so no
session could be read even with --record.

Report a zero-byte request or response member as null, like a missing
member, keep it in location.members, and add a per-record limitation
that says only that the stored member is empty. Non-empty malformed
members are still rejected.

Fixes #5411
2026-10-22 04:08:42 +08:00
lyly 414ad52b20 fix(objc): validate direct protocol enumeration input (#4405) 2026-10-22 04:08:31 +08:00
Peter 3cfdc585b4 fix(mcp): keep analyze_function progress strictly increasing (#3460) 2026-10-22 04:08:20 +08:00
The one -NiuandKaoru0822 4fe88a7e3f fix(browser): reserve the initial scenario step id from action inputs (#3493)
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-22 04:08:11 +08:00
jayinversandmaxazure f4cabe535f fix(wasm): pass glue filenames to the JavaScript parser (#4485)
associateWasmGlue selected the unnamed-source parser mode even though
the selected glue filename was already an adapter argument, so valid
JavaScript such as `n===0?H=>({start:H.startY}):H=>({start:H.startX})`
was read with the TypeScript grammar (conditional arrows as a return
type) and the whole glue file failed parsing, losing every .wasm
literal reference after it. Pass the filename so .js glue parses with
the JavaScript grammar, matching the general filename-aware parser
boundary from #3782. The unnamed-source fallback policy itself is
unchanged.

Adds a regression test asserting the conditional-arrow fixture parses
completely and retains the ./module.wasm reference (line 2, column 6,
local-path-candidate, static-literal) while the plain fetch control
stays working; reverting the fix fails the new test.

Fixes #4474

Co-authored-by: maxazure <maxazure@gmail.com>
2026-10-22 04:08:00 +08:00
keeponlightandkeeponlight 6bc4ec3a74 fix(electron): block moveToApplicationsFolder during active capture (#3471)
Co-authored-by: keeponlight <20103260+keeponlight@users.noreply.github.com>
2026-10-22 04:07:48 +08:00
The one -Niu 1dcaa77693 fix(browser): retain the null console argument in selected console text (#3479) 2026-10-22 04:07:37 +08:00
ShuaixinHuang 0da36910dc docs(artifacts): clarify unsupported DMG extraction (#5555)
* docs(artifacts): clarify unsupported DMG extraction

* fix(cli): keep the WASM command timeout optional

* fix(cli): preserve WASM timeout help metadata

* test(pe): reuse compiled CLI startup for resource acceptance

* fix(cli): use upstream exact-optional timeout semantics
2026-10-22 04:07:28 +08:00
Danish Rafie Ekaputra 55c3129224 docs(browser): reconcile HTTP discovery wording with browser sockets (#3484) 2026-10-22 04:07:18 +08:00
dbd556043c fix(providers): name JEB, IDA, and one-shot command deadlines (#6014)
* fix(providers): name JEB, IDA, and one-shot command deadlines

Wire JEB catalog discovery to REA_JEB_MCP_TIMEOUT_MS, name the IDA
registration timeoutMs, and add command_timeout_ms for one-shot objdump
and rizin. Debugger, Frida, and Cutter caps stay fixed and say so.

Refs #5910

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(providers): pass remaining deadlines and name the cap that fired

Catalog discovery now sends the JEB budget still remaining to the SDK on
connect and every tools/list page. Objdump and rizin preflight share one
command_timeout_ms across stat and digest; the command still receives that
budget again. Architecture Evidence keeps a selected timeout, and Frida and
Rizin name the capture limit that actually stopped output.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(frida): preserve non-timeout device lookup failures

getDeviceById is a lookup deadline only when Frida rejects with
"Device not found" after the wait. A device-manager or backend failure
stays a capability error. Align the assertions that still expected the
previous capacity and capture sentences.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 04:01:02 +08:00
Peter G b28f6c0953 fix(reference): retain inventories with empty module specifiers (#3497) 2026-10-22 03:57:38 +08:00
Jiwon | 지원 3220e17b8b fix(snapshot): count newly retained workflow bindings on import (#4428)
AnalysisSnapshotCache.stage counted new direct entries but never
incremented for new workflow entries, so a snapshot carrying only a
trace_feature binding reported 0 new entries while retaining it.

Count a workflow binding when its query ID is new, matching direct
entries; replacements and capacity-refused bindings stay uncounted.

Fixes #4377
2026-10-22 03:51:32 +08:00
Vinícius Andrade cc4ed5b904 fix(ida): keep omitted callee truncation markers unknown (#4286)
* fix(ida): keep omitted callee truncation markers unknown

Modern headless callees pages may omit more. The runner treated every
page that was not explicitly capped as complete coverage, so
trace_call_path could return not_reached when callee completeness was
unproven. Map omitted more to unknown coverage and keep the observed
callee rows. Explicit more: false remains complete.

Fixes #3988

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

* test(ida): keep omitted callee truncation from becoming not_reached

Assert that an x86 callees page without more reports unknown
relationship coverage and that trace_call_path to an unlisted goal
stays unknown instead of not_reached.

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

---------

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>
2026-10-22 03:51:22 +08:00
Vinícius Andrade 126b6e20d4 fix(ida): retain analysis profile in partial operation evidence (#4645)
* fix(ida): retain analysis profile in partial operation evidence

Pass the session analysis profile commitment to createEvidence when IdaSessionClient.#failure retains partial observations after a failed operation.

Refs #3992

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

* test(ida): cover analysis profile retention in partial operation evidence

Verify that failed IDA operations retain a supplied AnalysisProfileCommitment on partialObservation and projected error details while leaving unprofiled sessions null.

Refs #3992

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

* test(ida): align analysis profile provider with IDA adapter identity

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>

---------

Signed-off-by: Vinícius DS Andrade <95101505+viniciusdsandrade@users.noreply.github.com>
2026-10-22 03:51:12 +08:00
Wade 8fe8622e09 fix(evm): reject repeated byte-string keys in Solidity metadata (#4024)
cborg's rejectDuplicateMapKeys compares Map keys by identity, and each byte-string key decodes to its own Uint8Array, so a terminal metadata map with the same byte key twice was reported as decoded. Compare the root map's scalar keys by kind and value and report a repeat as not-decoded, like repeated text keys.
2026-10-22 03:51:02 +08:00
Vishal Tambi 1a945ce9ff fix(cli): reject an empty JavaScript application path (#5265) 2026-10-22 03:50:52 +08:00
Wade d8199ab6af fix(javascript): keep Vite dependency slots after a spread unknown (#4023)
The __vite__mapDeps table indexer mapped a spread element to one unknown slot, so every later entry kept a definite index even though the spread can add any number of elements. A call such as __vite__mapDeps([0, 2]) over ["./first.js", ...["./middle-a.js", "./middle-b.js"], "./last.js"] then resolved index 2 to last.js instead of middle-b.js. Keep only the entries before the first spread; indexes from the spread onward stay unknown.
2026-10-22 03:50:42 +08:00
ShuaixinHuang f6e4e0296f fix(native): remove completed signing capture limitation (#5548)
* fix(native): remove completed signing capture limitation

* fix(cli): keep the WASM command timeout optional

* fix(cli): preserve WASM timeout help metadata

* test(pe): reuse compiled CLI startup for resource acceptance

* fix(cli): use upstream exact-optional timeout semantics
2026-10-22 03:50:31 +08:00
4c20744f1c test(update): isolate CLI subprocess deadlines (#5019)
test(update): isolate CLI command deadlines

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 03:50:18 +08:00
Prasad Navale 3dce8326c9 docs(errors): include Omarchy and current host-support messages in error catalogue (#5078) (#5278) 2026-10-22 03:50:08 +08:00
Prasad Navale fd64b1c240 docs(cli): include Kuna in supported doctor providers (#4624) (#5011) 2026-10-22 03:49:57 +08:00
Prasad Navale d2015e94f3 docs(setup): clarify prebuild-install warning from optional dependencies (#4881) (#5012) 2026-10-22 03:18:41 +08:00
7fdf7a5b79 docs(go): clarify cumulative build-info search budget (#2731)
* fix(go): retain build info in later ELF data segments

* test(javascript): retain unknown shadowed parameter provenance

* fix(go): bound overlapping build-info searches

* test(release): select the runnable preflight job

* fix(ci): isolate Linux Hopper process fixture inventory

* fix(comparison): recheck historical calls-only changes (#2223)

* fix(comparison): preserve incomplete function call evidence

Keep missing, unknown, partial and unresolved call relationships unknown in function comparisons and reconstruction claims. Aggregate IDA caller and callee coverage without overwriting uncertainty.

Validate with 144 focused tests, typecheck/lint, docs checks and test discovery. Real providers were not verified; the full headless IDA session suite requires unavailable Windows native controls.

* fix(comparison): recheck historical calls-only changes

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>

* docs(go): expose cumulative build-info scan budget

* chore: retain upstream MCP test formatting

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-authored-by: Lucien <164857476+dakjdakd@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-22 03:18:31 +08:00
Iven Koo 7cdf8bc5cf test(native): assert failed-callee call identities and edge caps (#2888)
* fix(native): attempt failed value trace selectors once per invocation

* test(native): assert failed-callee call identities and edge caps
2026-10-22 03:18:21 +08:00
Vishal Tambi 465e1a1f36 test(sqlite): keep incomplete cleanup primary over late cancellation (#5365) 2026-10-22 03:18:10 +08:00
Christopher Pruijsen f3537db34f fix(setup): treat empty COPILOT_HOME as unset (#5047)
`copilotDirectory` used nullish coalescing, so `COPILOT_HOME=""` produced
the relative path `mcp-config.json`. Setup then planned and wrote the
GitHub Copilot CLI registration into the current working directory, not
`~/.copilot/mcp-config.json`, and doctor looked for it in the same wrong
place.

Use `||` like the sibling client homes (CODEX_HOME, KIMI_CODE_HOME,
GROK_HOME, XDG_CONFIG_HOME), and as #2686 did for DSH_HOME.
2026-10-22 03:18:01 +08:00
Dragoloneandgensokyo-dev 48e7470041 fix(evm): trim hex carrier whitespace in linear time (#5200)
The hex carrier trimmed outer ASCII whitespace with a global
start|end-anchored regex. For an invalid carrier with a long interior
whitespace run, the end branch was retried at every position of the run,
so rejection took quadratic time (about 18 s for a 200 KB run) and a few
hundred KB could exhaust the worker deadline instead of returning the
documented invalid-format error. Trim with index scans over the same
ASCII whitespace set.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-22 03:17:50 +08:00
2947a77507 fix(engines): keep format ceilings fixed and recover the EVMole deadline (#6088)
* fix(engines): keep format ceilings fixed and recover the EVMole deadline

Promote the owned EVMole worker wall clock to timeout_ms and name it in
recovery. Fixed CPU, byte, and address-space refusals in this theme say
the adjustable deadline does not raise them.

Refs #5910

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(engines): recover the allowance that refused the request

Model capacity recovery follows a structured limit instead of message text,
and the shared header ceiling no longer names Safetensors. Firmware signal
errors keep captured tool output, oversized reports do not suggest an
intermittent rerun, and NativeAOT hydration budget exhaustion explains the
fixed parser allowance on the partial report.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 03:06:59 +08:00
ae09e3fe70 fix(native): recover macOS command deadlines (#6059)
* fix(native): recover macOS command deadlines

Promote native_command_timeout_ms (default 60000), native_ui_deadline_ms
(default 180000), and pwntools_timeout_ms (default 30000) as validated
per-call settings. Keep cpuSeconds, byte allowances, LLDB grace, and plist
probes fixed, and say those caps have no runtime override.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(native): report the deadline that actually expired

Pass the selected native command timeout through xcrun resolution, thread
the pwntools deadline into pwndbg failures, and state the selected UI
deadline apart from the fixed wait-step cap. SIGXFSZ and EFBIG recovery
names the file-size allowance.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(native): honor the selected deadline on helper stages

The UI helper compile and capture subprocesses used fixed 60s and 30s
exec timeouts, so a longer native_ui_deadline_ms still failed as a generic
provider error. Preparation timeouts reported the 60000 ms default instead
of the selected native_command_timeout_ms.

Memory resource-constraint recovery names memory again, and the Darwin
plist CLI expectation matches the byte-counted input allowance.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 02:59:27 +08:00
Ulises Millán 67a6477f01 fix(cli): label reconciliation input failures as application workflow errors (#5668)
Closes #5436
2026-10-22 02:53:27 +08:00
Oke Iyanuoluwa EnochandClaude Opus 5.5 3dde9a5e1c ci(windows): run remaining Windows-only path admission cases in the lane (#5807)
Three test files have cases that run only on Windows
(skipIf(process.platform !== "win32") / describe.runIf(win32)), but the
windows-curated job runs an explicit file list that did not name them,
so CI never executed those cases:

- src/contracts/sessionPathInputs.test.ts (Windows absolute path forms)
- tests/boundary/filesystem/directAnalysisSnapshotReplay.test.ts
  (snapshot replay through a junction and before native admission)
- tests/boundary/mcp/rawBinaryMcp.test.ts (saved reads across a
  junction and a noncanonical Windows path)

Add them to the lane and the package change scope, and guard the
entries in curatedWindowsLane.test.ts.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 02:52:11 +08:00
Shakti 07fd426e9a fix(apple): preserve asset catalog caller cancellation reason (#6055)
* fix(apple): preserve asset catalog caller cancellation reason

* test(apple): cover asset catalog cancellation checkpoints
2026-10-22 02:51:11 +08:00
gensokyo-dev 0583fc69be perf(javascript): query selected source-to-bundle facts (#6128)
Select completed source-to-bundle mappings and candidates through the shared view owner, preserve reference-file provenance, and retain full Evidence. Reuse bounded JSON reading, heap admission, and cancellation before session writes.

Verified public Redux Toolkit source/map facts with an independent oracle, equivalent CLI/MCP workflows, focused negative controls, and complete CI/review. Historical paired SDK context estimates fall about 64%; timing/resource tradeoffs and final verification receipts are recorded without a general speedup or actual model-token claim.

Fixes #6112.
2026-10-21 18:45:50 +00:00
a0214e0e0e fix(javascript): name heap and semantic ceilings (#6022)
* fix(javascript): name heap and semantic ceilings

Refs #5910. Heap exhaustion names max_heap_mb with its effective value,
range, and next-analysis worker restart. Semantic ceiling coverage names
the four max_semantic_* arguments. Wakaru and transfer ceilings say this
release has no runtime override.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): distinguish adjustable ceilings from fixed limits

The effective transfer file ceiling and the parent result budget follow
the CLI/MCP process heap, so recovery names NODE_OPTIONS instead of
denying an override. A provenance report over 8 MiB keeps the fixed
allowance guidance, and the Wakaru deadline says an unchanged retry may
hit it again.

Refs #5910

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): keep Bun OOM and checkpoint heap controls distinct

Bun heap-exhaustion exits no longer claim the ignored max_heap_mb V8
old-space limit. Checkpoint decode names the parent heap and Node
NODE_OPTIONS, the same control as the parent result budget.

Refs #5910

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): name semantic ceilings without claiming both were reached

Truncated semantic retention names the total and per-file controls as
effective ceilings. Callers only know that retention was truncated, so
the limitation no longer says both ceilings were reached.

Refs #5910

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): name only the semantic ceiling that stopped retention

Semantic ceiling limitations claimed both the application total and the
per-file control whenever either one truncated the graph. Record which
offered budget stopped node and unknown retention, and name only those
controls. Coverage limits still list both effective values.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): require a value in the NODE_OPTIONS heap example

A bare --max-old-space-size is an illegal V8 flag and prevents Node from
starting. Parent-heap and transfer-ceiling recovery now share
--max-old-space-size=<MiB>, and the Kuna heap remediation uses the same
complete form.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): limit the old-space placeholder to NODE_OPTIONS recovery

The review covers the CLI/MCP NODE_OPTIONS example and the transfer-ceiling
copy. The Kuna heap-headroom sentence stays unchanged.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 02:44:14 +08:00
01788bac86 fix(android): name the JADX deadline and recover apktool decode (#6024)
* fix(android): name the JADX deadline and recover apktool decode

JADX operation timeouts now name REA_JADX_OPERATION_TIMEOUT_MS, the
effective milliseconds, the 1..2147483647 range, and that a change applies
on the next process start. Apktool decode accepts decode_timeout_ms,
omitted means 600000, and a timeout names that key. ADB deadlines and
apktool and Java version probes stay fixed and say there is no runtime
override.

Refs #5910

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(android): derive capture recovery from the fixed allowance

Main now stores a fixed allowance instead of a prebuilt remediation
string. Apktool and adb capture refusals keep the no-runtime-override
sentence in that allowance name, including that decode_timeout_ms does
not raise the apktool output cap.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(apktool): observe a real decode deadline and process cleanup

A hanging interpreter launcher and its pipe-holding child stay alive
until decode_timeout_ms elapses. The provider then reports
provider_timeout with completed cleanup, and both processes are gone.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-22 00:31:43 +08:00
gensokyo-dev aa51e43439 perf(mcp)!: default to compact input schema advertisements (#5975)
Use compact MCP input advertisements by default while preserving explicit full, canonical validation, output contracts and complete Evidence. Require an explicit selected catalog for runtime identity and honor both profiles in CLI status.

Real ripgrep/Zellij SDK tasks, independent ELF oracle, actual client trials, profile parity workflows and CI are recorded in experiments/analysis-efficiency/mcp-input-catalog.md. SDK token estimates improve; actual Codex token savings and general latency/memory gains are not established.

Refs #5861

BREAKING CHANGE: MCP input advertisements default to compact. Set REA_MCP_INPUT_SCHEMA_PROFILE=full for complete advertised guidance and nested constraints.
2026-10-22 00:17:11 +08:00
gensokyo-dev 01ee6551b4 fix(ci): use one heap snapshot for JavaScript admission (#6081)
Read the V8 limit and used heap together for initial admission, checkpoint
decode and remaining result capacity. Remove the duplicated second heap/RSS
observation while preserving every reserve and ceiling.

Make the controlled parent-capacity fixture internally consistent and test
both unchanged usage and a later one-MiB collection. Real worker/transfer
coverage still retains static/module facts and declines only the large graph.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-22 00:15:25 +08:00
d8a9673fc4 fix(process): name the Swift compile deadline (#6071)
Name REA_SWIFTC_COMPILE_TIMEOUT_MS, its effective milliseconds, the
1..2147483647 range, and the omitted 120000 ms default when a Darwin
ownership-helper compile times out. A change applies after REA restarts,
on the next ownership-helper compile.

Producer SIGXCPU and SIGXFSZ recovery says REA retains the tighter
inherited limit. Agent-visible fixed caps in this theme say this release
has no runtime override. Numbers are unchanged.

Refs #5910

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 23:46:29 +08:00
gensokyo-dev f86206535f fix(ci): validate artifact MCP replies against named schemas (#6021)
Bind artifact lifecycle and analysis calls to their advertised named SDK
output schemas, sharing discovery per connection and rebinding on reconnect.
Reject schema overrides and ambiguous catalogs, preserve request options,
and retain primary failures while attempting all owned cleanup.

Add real-stdio boundary regressions for malformed output, discovery reuse,
reconnection, schema ambiguity, override rejection and timeout preservation.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-21 23:28:12 +08:00
Kaoru0822andClaude Opus 5.5 8e3bf56e11 fix(electron): record actions skipped after a failed action (#6023)
An Electron scenario stopped at the first failed or cancelled action and
returned no record for the remaining declared actions, so
normalized_result.actions could not account for the whole scenario.

Record every remaining action as cancelled with a not-executed error, the
representation browser scenarios already use. Both runners now share one
helper for that error, which also distinguishes a stop caused by request
cancellation from one caused by an action failure.

Fixes #5943

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 08:06:25 -07:00
Kaoru0822andClaude Opus 5.5 dc53c11f6d fix(process): keep structural capture issues alongside semantic ones (#6020)
parseProcessCapture re-threw only the custom (semantic) schema issues as a
TypeError whenever any existed, discarding structural issues found in the
same parse. Throw the schema's ZodError instead so every issue is retained
and describeValidationFailure reports the first issue with the remaining
count. Reconstruction obligation candidates now use that same formatter
instead of the raw error message.

Fixes #5957

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 08:05:30 -07:00
Kaoru0822andClaude Opus 5.5 d4c637f4cf fix(browser)!: keep malformed console argument inventories unknown (#6016)
* fix(browser)!: keep malformed console argument inventories unknown

An omitted, null, or non-array Runtime.consoleAPICalled args inventory now
reports argument_types as null, text capture as unavailable, and
console_events as invalid_protocol_value instead of a complete empty
inventory. Malformed argument elements keep their CDP position as
"unknown", so retained text values keep their original argument_index.

Call-site attribution now uses the frame at position zero: a malformed top
stack frame is no longer replaced by its caller. Console events are
excluded and request initiator locations are null, both reported as
invalid_protocol_value.

BREAKING CHANGE: console event argument_types may now be null, and
console text_capture.status may now be "unavailable", when the CDP
producer omits or malforms the argument inventory.

Fixes #5934

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(browser): report malformed WebMCP registration stacks as incomplete

topCallFrame now owns the omitted-versus-malformed decision for the whole
stack value: an omitted stack has no call site, while a non-object stack,
non-array callFrames, or a malformed top frame is malformed. WebMCP
discovery keeps the tool with a null registration_source but records
webmcp_tools invalid_protocol_value, so capture comparisons stay unknown
instead of confirming a changed source. Console and initiator stacks use
the same rule.

Refs #5934

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 08:01:45 -07:00
Kaoru0822andClaude Opus 5.5 4dfa1c67dc fix(capture): keep excluded MIME protobuf applicability partial (#6012)
* fix(capture): keep excluded MIME protobuf applicability partial

Automatic protobuf framing treated an explicitly excluded, conflicting or
unavailable Content-Type the same as a known-absent one, so a selected body
was skipped and coverage still upgraded to complete. Body metadata now
reports whether MIME applicability is established; an unresolved non-empty
body adds a record limitation and keeps protobuf_coverage partial. HAR uses
its required mimeType, falling back only to a visible header value.

Fixes #5926

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(capture): compare repeated Content-Type declarations by essence

Repeated Content-Type headers that differ only by case, whitespace or
parameters declare the same media type, yet the raw-string comparison
collapsed them to an unknown value and the new applicability check
reported partial coverage. Body metadata now compares media-type
essences and owns automatic framing selection, so the consumer no longer
re-parses the raw value; framing lookup ignores inherited properties.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 07:58:31 -07:00
Kaoru0822andClaude Opus 5.5 1f92c77398 fix(adb): report an unparsed push checksum as unverified (#6010)
fix(adb): derive push digest source from the parsed device digest

A zero-exit sha256sum whose output held no recognizable digest produced
device_sha256: null with device_digest_source: "device_sha256sum" and
dropped the not-device-side-verified limitation. The push receipt now
takes one tagged device digest, so the source can only name sha256sum
when a digest was parsed; unrecognized output reports "unavailable",
the unverified limitation, and the raw command output. The sha256sum
parser moves to AdbShellOutput and accepts GNU's escaped-name prefix.

Fixes #5924

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 07:56:38 -07:00
Kaoru0822andClaude Opus 5.5 2319166c2e fix(reconstruction): keep complete contradictions beside incomplete entries (#6009)
The obligation ledger flattened every contradiction entry for an obligation
into one Evidence list, so one entry naming absent Evidence suppressed a
sibling entry whose Evidence was all present. Group whole manifest entries
and evaluate each one: any complete entry still reports `contradiction`,
while absent references from any entry stay visible as
`contradiction-evidence-missing`.

Share the ready packaged-process request fixture with the CLI boundary test,
which now covers both entry orders through the public command.

Fixes #5925

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 07:54:37 -07:00
Kaoru0822andClaude Opus 5.5 63b43b69bb fix(javascript): refuse Webpack loaders that can fall off the end (#6007)
* fix(javascript): refuse Webpack loaders that can fall off the end

The bootstrap integrity proof accepted any loader whose explicit returns
all yielded the module's exports. A loader with no returns, or with only
the cache-hit return, passed vacuously even though its miss path returns
undefined, so a bundled `n(45840).BrowserWindow` became an exact Electron
window.

Require that the loader body cannot complete normally before the proof
checks its returns, so the bundled-call identity stays unresolved while
the literal require("electron") reference is preserved.

Fixes #5958

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(javascript): cover finally completion in Webpack loader proofs

Group the loader completion-path cases in their own suite and add
focused finally cases: a completing finally keeps a falling-through
catch unproven, a finally returning another value stays unresolved, and
a finally returning the exports proves the loader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(javascript): keep IPC checks for unresolved Webpack loader cases

Share the unresolved-identity assertion so the completion-path cases
also reject directly attributed IPC observations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 07:53:42 -07:00
Kaoru0822andClaude Opus 5.5 c8d3f8f8ec fix(firmware): keep a missing producer report distinct after exit 0 (#6008)
* fix(firmware): keep a missing producer report distinct after exit 0

A firmware engine that exits 0 without writing its requested report now
fails with the observed report state (missing, empty, invalid_json,
oversized, not_regular_file), the command, arguments, exit status and
captured output, plus report-specific recovery instead of generic
`rea doctor` advice. REA still does not retry or substitute an empty
result.

Fixes #5876

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(firmware): keep missing-report recovery from replaying removed paths

The recorded command arguments name REA's private workspace, which is
removed after the attempt. Recovery now presents them as provenance and
tells callers to replace every private path when reproducing the run.
Cover the oversized and not_regular_file report states.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 07:52:40 -07:00
Kaoru0822andClaude Opus 5.5 4423b6fff2 fix(process): reject finite trace variants that only reorder unordered members (#6006)
Duplicate-variant validation keyed each finite trace by its JSON form, which
preserves the member order of unordered tokens that matching treats as a
multiset. Key traces by the observations they accept instead: sort unordered
members and expand a token that repeats one event into that event's sequence,
keeping token positions and multiplicities significant.

Fixes #5916

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 07:52:06 -07:00
Kaoru0822andClaude Opus 5.5 5df59ee1fd fix(errors): name fixed plist decode allowances instead of host memory in recovery (#5860)
fix(errors): derive fixed-allowance recovery from a typed refusal field

inspect_plist refused a binary plist above its fixed 64 MiB decode
estimate, or nested deeper than 128 levels, with resource "memory" and no
recovery, so the shared presentation told the caller to add worker or
host memory. Neither raises that allowance. The 64 MiB source-size refusal
likewise got the worker file-size advice for evidence replies.

AnalysisResourceConstraintError now carries a typed fixedAllowance
{ name, kind }. fixedAllowanceOptions sets it instead of a prebuilt
string, and the presentation derives the recovery from it, so every
existing fixed-allowance producer moves to the same field. Operation
re-attribution, IDA startup re-attribution and explicit redaction copy the
field through one resourceConstraintRecovery helper; redaction still
applies to the allowance name.

The plist decode, nesting and input refusals use the field. A nesting
refusal now reports maximum_nesting_depth instead of the decode byte
limit it did not exceed.

Fixes #5847

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 07:51:46 -07:00
Kaoru0822andClaude Opus 5.5 6d356b8434 test(ci): keep module mocks in isolated test projects (#5886)
* test(ci): keep module mocks in isolated test projects

A module mock registered after another file in the same worker loaded the
module never applies, so a mocking test in a project that shares one module
graph passes or fails with file scheduling. That is how the environment
export source tests failed on hosted runs until c324d31b4 removed their
mocks.

Guard the rule: every tracked test using vi.mock or vi.doMock must belong
to an isolated project. Move the last shared-graph case,
DirectAnalysisStatFailure, which mocks node:fs/promises, into process-global
beside the other module-mocking workflow tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(pe): share one compiled CLI process across PE resource inspections

The acceptance test started a fresh CLI process for each of its fixtures
inside one 30 s test deadline. Hosted runs took 24-27 s and c324d31b4 timed
out. Every inspection there reads no stdin and sets no deadline, so use the
fixture's file-scoped compiled CLI process. Local time drops from 8.5 s to
about 3.9 s with the same assertions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 05:51:24 -07:00
gensokyo-dev c538a843cb fix(ci): keep Windows ACL observation in SID form (#5941)
Observe private-runtime ACL ownership, trustees and rule count from one SID
rule collection. Guard the account-name presentation member through the owning
PowerShell type and verify that guard is installed. Keep the original15s probe
deadline and every ACL/readonly assertion.

Record bounded phase diagnostics and document the observed failure boundary.
The repeated historical timeout cause is unconfirmed; no retry or deadline
increase is presented as a fix.

Validation: complete current-head CI passed40 jobs with one source-only skip;
real Windows typecheck, curated/native controls, package and Node24/22 checks
passed. PowerShell7.5.2 API/parser experiment and278 routing regressions passed.
Full evidence: https://github.com/morluto/rea/actions/runs/39599008194

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
2026-10-21 20:43:56 +08:00
Kaoru0822andClaude Opus 5.5 25e1a24a3e fix(reconstruction)!: summarize obligation ledgers by cited Evidence authority (#5875)
summary.by_evidence_authority bucketed each obligation's source_state, so a
shipped-artifact and a controlled-replay ledger returned the same summary and
the promised authority breakdown was unanswerable.

Derive the buckets from authority_references[].authority using the Evidence
authority vocabulary owned by the Evidence schema. An obligation counts once
under each distinct authority it cites, so counts can exceed total. Keep the
source-state histogram under its own name, by_source_state. The readiness
example now derives its summary from the same owner function instead of
hand-writing buckets.

BREAKING CHANGE: summary.by_evidence_authority keys are now Evidence
authorities (shipped-artifact, controlled-replay, historical-reference,
external-service, analyst-inference) instead of source states. The previous
state counts move to the new required summary.by_source_state. Ledger closure
digests change accordingly.

Fixes #5838

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 05:12:55 -07:00
Kaoru0822andClaude Opus 5.5 705058f3e2 fix(javascript): count one IPC observation per site-resolved channel (#5810)
* fix(javascript): count one IPC observation per site-resolved channel

A send with a local constant channel was recorded twice: once unresolved
by the syntax pass and once resolved by wrapper substitution, because
duplicates were keyed on the channel. A channel the call site determines
now resolves that observation in place. A channel supplied through a
wrapper argument stays a candidate beside the unresolved observation.
Invocation identity now follows the call that supplies the wrapper's
literal arguments, so one wrapper call reached through several entries
is recorded once.

Fixes #5710

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(javascript): keep wrapper invocations distinct while removing repeats

Taking the nearest literal call as invocation identity collapsed separate
outer calls that pass different handlers through one wrapper call. Entry
identity is restored, and a finding is a repeat only when an identical
finding was reached through the same trailing local calls. A registration
replaces its unresolved source observation only when the site also
determines its handler, so a parameter handler keeps the generic source
registration beside per-invocation candidates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(javascript): compare site-determined IPC handlers by value

In-place resolution compared handler representations, so a constant
channel with a named local handler (recorded as an identifier by the
syntax pass and as its function by substitution) stayed counted twice.
The handler is now site-determined when it evaluates to the same function
in the site's lexical environment. A replaced observation also removes
the syntax pass's unknown-channel contribution, so a fully resolved file
is no longer reported as partial.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(javascript): keep closures over invocation values as distinct IPC handlers

A handler node created in different wrapper activations may capture
different values, so the same function node alone does not prove the call
site determines the registration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(javascript): guard optional call paths in closure handler test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(javascript): decide IPC handler identity from activation captures

A closure is one site-determined handler only when it reads no binding of a
function this trace activated, such as a wrapper parameter or factory local.
Unused bindings in the activation no longer split a known listener, and
closures over outer-call values stay distinct when a shorter entry traced
the same wrapper call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(javascript): treat implicit captures and bundle modules precisely in IPC handler identity

An arrow handler reading its enclosing function's arguments or this captures
that activation. A bundle module factory runs once per module load, so its
bindings are shared by every trace rather than per-invocation captures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(javascript): attribute an arrow handler's inherited context to its owner

An arrow inherits this and arguments from the nearest non-arrow function, so
an activated arrow inside that owner does not make the handler depend on
the traced call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(javascript): skip suffix scans for per-invocation IPC handlers

Check activation capture before scanning recorded call chains, keep the
chains of capture-dependent handlers out of the index, append chains in
place, and treat an arrow's inherited super and new.target as captures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(javascript): supersede nested-entry IPC records and share module-init factories

A shorter entry traced alone no longer swallows the outer calls that invoke
the same wrapper sequence: the first fuller path takes over its record and
separate outer calls stay distinct invocations. A factory activation called
at module scope runs once per load, so its closure is shared unless the
trace itself makes that call. The resolver now owns bundle module-factory
recognition instead of an environment marker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 05:06:50 -07:00
Kaoru0822andClaude Opus 5.5 35d6d5bb0a fix(artifacts): admit ZIP archives after unclaimed leading bytes (#5803)
* fix(artifacts): admit ZIP archives after unclaimed leading bytes

ZIP recognition required the archive at byte 0, so a ZIP behind a
script or self-extractor stub was refused as an unsupported binary
format although standard readers accept it. Target resolution and root
inventory now locate a trailing single-disk ZIP from its end record,
central directory and first local header, whether member offsets include
the leading bytes or not. Leading bytes any executable header family
claims keep their executable route.

Fixes #5732

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(artifacts): share the root ZIP family across recognition paths

The trailing-ZIP fallback named a stub-prefixed root `.app` archive
`zip`, while root inventory and the leading-signature route name it
`app-pack`. The root mapping now lives once in `zipRootPackageFormat`
and both target resolution routes and root inventory use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 05:06:28 -07:00
Kaoru0822andClaude Opus 5.5 5b014a739e fix(adb): report unrecognized package rows from resolve-adb-packages (#5874)
resolve_adb_packages marked coverage partial when pm list packages printed
unrecognized rows, but dropped the rows themselves and could still emit a
limitation describing an unparsed_lines field the result never carried.

ADB parsers now own unrecognized-line facts as a bounded sample (first ten)
plus the exact total, and a single provider projection derives
unparsed_lines, coverage, and the truncation limitation from those facts for
every parsed listing and the package search. The resolver result schema now
carries unparsed_lines, matching list_adb_packages through CLI and MCP.

Fixes #5843

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 05:06:11 -07:00
Kaoru0822andClaude Opus 5.5 ce1f4b1bba fix(artifacts): report unknown inventory traversal in inspection coverage (#5867)
fix(artifacts): keep unknown inventory traversal out of complete inspection coverage

Artifact inspection derived its coverage status only from always-zero
omission counts, so an inventory substep with unknown container-entry
traversal (for example, an omitted FIFO) yielded
complete-within-substeps. Analysis-view summaries also exposed the
inventory's typed source_coverage only for PCK and PyInstaller roots.

Derive the inspection status from the inventory substep's coverage
(unknown traversal is partial), and carry the producer's source_coverage
plus the traversal-unknown caveat in every artifact summary. Hash-count
fields keep their existing format gating.

Fixes #5837

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 04:59:09 -07:00
Kaoru0822andClaude Opus 5.5 d124809950 fix(android): report a rejected relative JADX JAR instead of an unset one (#5862)
A supplied non-absolute REA_JADX_MCP_JAR was folded into the unset case,
emitting not_configured with jar_configured: false and dropping the
caller-selected value. The JAR parser now keeps the two outcomes distinct:
unset stays not_configured, while a supplied non-absolute value (including
an empty string) fails with open_options_invalid, jar_configured: true, the
exact rejected jar_path and the absolute-path requirement. CLI, MCP and
doctor derive their output from that one boundary result.

Fixes #5844

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 04:57:55 -07:00
Kaoru0822andClaude Opus 5.5 7f9a492a8d fix(signals): report unknown decoder help IDs as invalid input (#5858)
inspect_signal_decoders turned sigrok's explicit missing-decoder refusal
into execution_failure with rea doctor advice, while decode_signal_recording
already reported the same refusal as invalid_request on decoders.

The sigrok selector classifier now owns the unknown-ID match for both
selections: help names the decoder field and points to catalog discovery,
decoding keeps decoders/annotations. The provider passes each producer
command's caller selection to that one owner instead of per-call closures.
Installed decoders that fail to load and refusals naming other IDs remain
provider failures. The real-sigrok verifier now asserts the typed refusal
for both operations.

Fixes #5849

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 04:57:28 -07:00
Kaoru0822andClaude Opus 5.5 c2bee63e99 fix(evidence): clear staged write cleanup state after a confirmed retry (#5852)
The atomic JSON writer reported a failed staging-directory release as
cleanup state on the returned EvidenceFileError or AnalysisCancelledError,
but never bound that error to the retained staging lease. A later scope
retry that removed the stage could not clear the error, so
`rea evidence-export` (and other writers sharing the scope, such as
--evidence-output delivery) kept reporting cleanup_incomplete and a
retained resource after cleanup had completed.

Bind each staged-output cleanup failure, and each admission retry
failure, to its exact leases so confirmed release restores the primary
outcome. Export recovery now reads that bound state instead of a local
close flag. A retry that still fails keeps the error incomplete with the
same retained stage.

Fixes #5842

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 04:57:08 -07:00
gensokyo-dev 905cbaf239 perf(ci): use tsrs and reduce PE acceptance startup (#5795)
Use pinned tsrs on supported development hosts while retaining stable official
TypeScript on Windows and unsupported platforms. Partition compile/typecheck
caches by actual compiler and qualify fallback hosts for compiler inputs and
lifecycle hooks.

Reduce PE acceptance startup through the existing bounded compiled CLI. Retain
upstream named MCP definitions, every fixture/assertion and the original 30s
deadline. Verify that browser transport loss preserves the observed target.

Validation: full qualification and real host lanes in
https://github.com/morluto/rea/actions/runs/39590450889 ; 450 focused regressions
passed with two documented conditional skips. All 1724 production emit files
match SHA-256 and size across both compilers. Current-head Codex/Greptile review
found no actionable issues. Measurements and limitations are in the PR.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
2026-10-21 19:47:52 +08:00
gensokyo-dev 33f912919d perf(apple): reuse retained Interface Builder graph validation (#5885)
Reuse successful owning-schema validation only for exact immutable Evidence snapshots, preserve current parent binding and complete source facts, and collect only requested document pages.

Verify real XLD CLI/MCP workflows and archived connector UIDs, including complete pre-change baselines for both admission sizes and a wrong-baseline negative control.

Fixes #5855.
2026-10-21 19:44:05 +08:00
gensokyo-dev aa53c06538 feat(firmware): make analysis deadlines recoverable per call
Expose per-call firmware analysis budgets with exact recovery guidance, shared
CLI/MCP validation and retained actual settings. Keep publication and fixed
resource policy independent; preserve typed interruption and one captured-output
owner through command and one-shot cleanup.

Fixes #5851. Executed verification, real-provider limits, known baseline issues
and authorized readiness override are recorded in #5863.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-21 19:25:22 +08:00
Kaoru0822andClaude Opus 5.5 bcfcd8b6e2 fix(sqlite): attribute generated-column evaluation failures to the selection (#5879)
* fix(sqlite): attribute generated-column evaluation failures to the selection

A selected virtual generated column whose expression needs a function the
read-only connection lacks (or raises an SQL error for a sampled row) was
classified by the worker's catch-all as a malformed database and projected as
an invalid_format issue on `path`.

Row reads now attribute SQLITE_ERROR from selected cells by probing each
selected virtual generated column over the sampled rows, and report a
typed capability_unavailable refusal naming the table, each failing column
with SQLite's message, and the remaining columns to select. Other causes,
including corruption, TOOBIG and NOMEM, keep their classification.

Fixes #5719

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(sqlite): recommend only probed-readable columns after evaluation failures

Record every per-column probe failure with its own reason, discover stored
columns outside an inventory-scope selection without decoding unrelated
malformed names, and present recovery as the structured columns selection
instead of shell-quoted command text built from database-supplied names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 04:08:49 -07:00
gensokyo-dev efab044f30 feat(gpu): inspect static CUDA and HIP code objects (#5813) 2026-10-21 19:06:44 +08:00
647717c050 perf(javascript): reuse the source-analysis worker within a process (#5819)
* perf(javascript): reuse the source-analysis worker within a process

Each analyze-javascript-application call started a new Node worker.
That startup, not fixture IO or the shared CLI session, dominated the
slow loader-review and factory-completion files.

Park one healthy worker on the artifact resource scope and on the CLI
process. Stop it when the scope, session, or one-shot process ends.
Do not reuse after failure, cancellation, or a different heap or timeout.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(cli): close the JavaScript worker when dispatch throws

Minimal dispatcher runtimes now export a no-op closeCliJavaScriptResources,
and CLI dispatch plus output rendering always await that cleanup. A dispatch
failure and a cleanup failure are both reported.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(artifacts): report close-hook failures with retained cleanup

When retained cleanup and the scope close hook both fail, the close error
keeps both causes and both resource labels. The pending owners and the hook
stay registered so the next close retries each path.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): stop a replaced analysis worker before the next one starts

A heap or timeout change now closes the parked worker before constructing
its replacement. The scope retains that process only when the close fails.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style: format worker-reuse close and launch helpers

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(cli): report a failed JavaScript worker shutdown before exit

Share one in-flight close and drop the CLI scope only after it succeeds,
so a later caller retries a worker that is still owned. The one-shot
exit callback writes that failure and exits non-zero, while a closed
stdout pipe still exits 141.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): keep a worker parked during an overlapping limit change

Claim the scope slot only when it is still empty after the replaced
worker closes. A concurrent analysis that parked another healthy worker
keeps that process, and the extra worker is closed through its own port.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(artifacts): run later close hooks when an earlier hook fails

Run every registered close hook on each close. One failure is returned
unchanged, and several failures are aggregated so a later hook is not
skipped.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): fail a limit change when the previous worker stays alive

A failed close used to be retained and then ignored, so MCP could return
a successful analysis while the old process and its replacement were
both owned. The request now fails before the replacement is constructed,
and the still-live worker stays owned for a later close.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 19:01:20 +08:00
morluto c76edbebbe test(pe): bind acceptance calls to advertised MCP definitions
Pass the exact named tool descriptors to SDK callTool for PE resource inspection and session inventory. Avoid full-catalog validator compilation while retaining SDK output validation, every CLI/MCP scenario, cleanup, and the unchanged 30-second deadline.

The complete focused test passed locally in 7.1 seconds versus 11.0 seconds before this change; host load and CPU/memory costs were not controlled or measured. check:ci passes.
2026-10-21 18:58:50 +08:00
morluto c324d31b45 test(environment): verify export failures through the real CLI
Remove shared-module mocks for input reads, heap statistics, and tarball streaming. Exercise actual file changes and real V8 heap admission in fresh CLI processes; keep only selected-descriptor syscall fault injection for the pathless EIO case.

Reproduced the four hosted source failures with a preloaded module graph and found the same flaw in the adjacent tarball test. The preloaded control now passes 17 cases; 32 focused tests, all 1,739 service tests (2 skips), and check:ci pass. Snapshot, cleanup, identity, and error projection coverage is retained.
2026-10-21 18:26:58 +08:00
Cursor Agentandmorluto 5eebe2fdf8 test(cli): treat omitted exactOptional inputs as optional
The advertised-schema check parsed undefined on each field.
exactOptional rejects that value and still accepts a missing key, so
inspect-wasm-artifact looked required for commandTimeoutMs.

Judge omission with an object parse that leaves the key out. The
advertised required list already matched that parse for every other
primary command.

Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 18:14:39 +08:00
Edgar ArakelyanandClaude Opus 5.5 ea3534759f feat(analysis-view): share templated positions across manifest tools (#5664)
* docs(specs): plan a template rule that shares templated positions

Record the outcome, requirements, non-goals, plan and tasks for
prefix-variance, an opt-in environment-manifest rule that templates a
literal segment with the parameter another tool already uses at that
position, so a session's writes to one entity share the read's template.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(analysis-view): share templated positions across manifest tools

Add the opt-in prefix-variance template rule. It runs after the other
opt-in rules and templates a literal at a position that another tool,
of any method or segment count, templates by one of those rules after
the same preceding parts, when the literal is one of that parameter's
observed values or carries a digit and is spelled like one. The
parameter takes the shared parameter's name, tools that now match merge,
and a merged position keeps a tool's own rule when one templated it.

A write to the one entity a session edited, such as
PATCH /api/v1/collections/0RZ576QZQA5KG, becomes
patch_collections_by_collection_id on the read's template instead of a
literal single-entity tool.

Tool naming moves to its own module, and the three comparing passes
share the 32-segment split. Manifests that do not list the rule are
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(analysis-view): drop the unused ManifestRule alias

Parameters now type their rule as a format rule, a shared opt-in rule
or prefix-variance, so nothing reads the union alias.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(specs): record the prefix-variance checks and corpus results

Record the gates, and the 50 showcase captures with and without the
rule: identical output without it, 25 write and 34 read tools templated
with it, and the write tools the write-plan branch serves on top.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(analysis-view): share positions with digit-free generated identifiers

prefix-variance accepted an unobserved literal only when it carried a
digit, so a generated identifier that happened to hold none stayed a
literal tool: an n8n workflow id such as FkMwxmXNGaGVsXFG, whose reads
then never joined the item view. A literal now also qualifies when every
value observed at the position has one length of eight or more characters
and the literal has that length and uses only their character classes.

Across the 50 showcase captures this templates 10 more read tools in
Memos and n8n and no words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(specs): record five environments rebuilt end to end with the rule

Five randomly drawn environments rebuilt on VMs with the rule and the
write-plan branch: smoke, retrieval and write tasks for two models, and
the same calls against the live applications. Record the results, the
misses and their causes, and the corpus numbers after the fixed-length
clause.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(analysis-view): share a position with the parameter that observed the literal

A shared position folded every donor's values into the earliest donor's
parameter. With an opaque-token read before sibling-variance reads at
the same position, a PATCH of /api/items/b2 qualified on the sibling's
evidence but became /api/items/{uid} instead of joining the item read's
/api/items/{item_id}. Each position now keeps one donor per naming rule
with its own values, and a literal takes the donor that observed it,
else the earliest one it is spelled like.

Each donor's spelling (length and character classes of its values, and
its fixed-length family) is summarised once per position, so a literal
is checked in time independent of how many values were observed, rather
than copying and rescanning them for every candidate.

A family now forms from one observed value, as the requirement says, so
a digit-free id of the same length shares a position that only one
opaque-token or after-uid-literal tool supplied. The 50 showcase
captures give the same tools as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(specs): record the prefix-variance review round

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(analysis-view): bound the spelling summary of shared positions

spellingSummary classified every observed value with three full-size
replaceAll copies and a set per distinct character, so a donor holding
a multi-megabyte segment cost unaccounted memory and time in finish().
Characters are now classified in one pass, and a value longer than 128
characters takes no part in spelling comparisons: it shares a position
only as an exactly observed value. The 50 showcase captures give the
same tools.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 18:11:51 +08:00
morluto 19f2969c56 fix(ci): align omission and browser transport assertions
Check property absence in an object instead of treating explicit undefined as omission, preserving Zod exactOptional semantics and WASM timeout bounds. Update real-browser disconnect verification to require transport_disconnected and reject an invented crash event.

Reproduced the CLI catalog failure on d9767eb48; 37 focused tests and check:ci pass. Real-browser verification runs on hosted CI; Chrome was not launched locally.
2026-10-21 18:07:21 +08:00
d9767eb48f test: assert Result reasons instead of bare ok checks (#5821)
Malformed DOS MZ, raw-binary entry, EVM limit, and Ghidra handshake
cases only checked Result.ok. Name the producer error, or the admitted
language and compiler, so a different failure cannot keep the test green.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 18:00:31 +08:00
Shreyash Patange f5410bdc4c fix(apple): keep scalar facts when object-table entries share a record (#5806)
Binary plist object tables may list one object offset more than once;
plistlib reads each entry independently. The scalar scanner marked any
repeated offset as incomplete metadata, which made the number projection
drop every exact decimal in the archive. A keyed archive whose entries
10 and 11 share an Int64 9007199254740993 reported both as observed
9007199254740992 and rounded an unrelated 2^60+3 sibling, with only the
generic incomplete-metadata caveat.

A repeated valid offset carries the same source facts as its first
visit, so observe it once and continue. Offsets that fail to parse still
mark metadata incomplete. Shared 16-byte integers and dates are rewritten
once in the decoder copy, which every entry then reads; the overlap plan
already treats one shared offset as one span. Keyed archives and
Interface Builder decoding share this scanner.
2026-10-21 17:51:24 +08:00
gensokyo-dev f801b2fbfd feat(sqlite): make worker deadlines adjustable with recovery guidance (#5818)
Expose a per-call SQLite worker deadline with exact CLI/MCP recovery controls,
parent-owned execution metadata and historical unknown preservation. Keep fixed
resource limits and cleanup admission intact. Share typed cleanup composition
with one captured-output owner and preserve the timeout after cleanup resolves.

Fixes #5812. Follow-up tracking: #5808. Existing CLI test-oracle failure: #5845.

Verified 155 SQLite tests (3 skipped), static/docs/discovery checks, six real
CLI/MCP pairs and 13 actual Codex sessions including four corrected deadline
recoveries. Three pre-dispatch discovery failures remain explicit, not passes.
Review findings include real retained-cleanup and fixture ownership regressions.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-21 16:45:46 +08:00
gensokyo-dev 5241597594 perf(rust): query selected dependency facts from retained Evidence (#5815)
Add optional package/edge selection and summaries through shared retained Evidence, preserving complete delivery and parent identity.

Fixes #5802
2026-10-21 16:12:04 +08:00
gensokyo-dev a5f982de8d feat(wasm): make command deadlines adjustable with recovery guidance (#5798)
Expose the existing WABT command deadline as an optional validated per-call CLI/MCP budget, preserving its 30000 ms default and fixed safety allowances.

Retain selected execution profiles in success and rejected-module Evidence. Keep typed timeout recovery through cleanup failures without duplicating command output or making incomplete cleanup retryable.

Verified focused tests, real WABT CLI/MCP workflows and actual Codex recovery/blocked controls; detailed measurements and qualification limits are recorded in issue #5797. Merge uses the explicitly authorized maintainer override with pending CI and unchecked human-review attestations disclosed on PR #5798.

Closes #5797

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-21 15:00:05 +08:00
morlutoandCursor Agent ea24207b57 perf(ci): pack each test tier from its own timing history (#5799)
* perf(ci): pack each test tier from its own timing history

Fast shards were still ordered with the latest full-suite timing artifact,
which stayed stale across compiled-CLI session reuse. Publish and download
test-timings-fast and test-timings-full separately, and keep the legacy
artifact as a fallback until a tier has its own history.

* perf(ci): drop the shared timing-history fallback

Shard lookup now reads only the artifact for the current tier. A missing
artifact leaves history unset instead of packing from the old test-timings
file.

* test(ci): look up fast history when only full timings exist

The empty-history case now requests the fast tier against a full-tier
artifact and checks that the fast lookup ran and returned nothing. A
missing tier stays a separate test that does not query.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-21 14:58:17 +08:00
morluto 6b7d429491 fix(apple): decode Swift conformance type references
Decode direct Objective-C class names separately from nominal descriptors, retain indirect class bindings as partial facts, and preserve readable protocol and witness evidence when related bytes are unavailable.

Validated with 98 focused tests, check:ci, docs:check, and named-schema CLI/MCP replays of compiler-produced imported-class and struct fixtures plus an inert kind-3 control. The fixtures were inspected statically, never executed.

Fixes #5738
2026-10-21 14:50:57 +08:00
morluto 5891bfb302 fix(browser): retain precise observation termination facts
Distinguish CDP session detachment, observed crashes, and transport loss. Preserve the observed window alongside the original typed coverage-stop failure and unconfirmed cleanup.

Validated with 40 focused boundary tests, check:ci, docs:check, and the real Chrome public CLI/MCP verifier on macOS. Browser timing comparison remains incomplete because unchanged-main fixture readiness was intermittent.

Fixes #5756
2026-10-21 14:50:32 +08:00
morluto d672cc2399 fix(apple): preserve binary plist scalar source facts
Decode native binary plists from bounded owned source bytes before conversion can erase scalar values. Share scalar preflight and isolate overlapping decoder records while retaining exact integers, date uncertainty, and original bytes. Refuse numeric payloads that read structural table bytes, and avoid retaining projection metadata when callers only need structural validation.

Closes #5701
Closes #5703
Closes #5705
Closes #5782
Closes #5783
Closes #5792
2026-10-21 14:09:29 +08:00
gensokyo-dev 25bea07b42 fix(model): preserve unsupported GGUF version diagnostics (#5789)
Preserve unsupported GGUF version bytes and both UINT32 interpretations without inventing byte order at the shared parser. Keep existing layout support, typed errors, evidence identity, scoped reads and resource limits.

Validation: 78 focused tests, full static/architecture and documentation checks, real CLI/MCP version controls and an independently checked public model. Latest-head Codex found no issues; Greptile is 5/5 and all review threads are resolved.

Some CI remained pending at merge qualification. Merge under the human owner's explicit standing bypass authorization does not claim the full CI suite passed.

Fixes #5749.
2026-10-21 05:59:18 +00:00
Kaoru0822andClaude Opus 5.5 bd8d73ab1d fix(environment): report later bundle write failures as host failures (#5581)
* fix(environment): report later bundle write failures as host failures

Only destination admission now refuses the selected directory as invalid
input. A path failure on a nested bundle file after admission, such as a
host pathname-length limit, is reported as an output failure that names the
host cause and the absolute failed path, with recovery guidance for the
partial folder it leaves in place.

Fixes #5522

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): name the host-refused path in export permission failures

A permission failure after earlier bundle files were written was reported
as access denied for the bundle root, so the documented failed path was
lost. The refusal now names the absolute path the host reported, falling
back to the root, and keeps the root as `output_directory`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): attribute pathless bundle write failures to their file

Descriptor operations such as `write` and `fsync` fail without a path, so
a disk-full failure after earlier files named only the bundle root. The
bundle writer now attributes such failures to the file it was writing.
Host-write recovery is applied only to actual host failures; an integrity
refusal keeps its own message without disk-space advice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): attribute package tarball read failures to the tarball

The destination-write attribution also caught failures from reading the
admitted package tarball during the copy, so a source `EIO` named the
destination file and advised freeing disk space. Host failures are now
attributed by direction: tarball reads name the tarball with read
recovery, bundle writes name the file being written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(environment): state which export failures name a path

The export documentation and host-write message promised a failed path
for every later write failure, but a directory sync at commit time fails
without one. They now promise the failed bundle file or package tarball
when the failure is on one, and only the cause for a folder sync.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 22:55:05 -07:00
Kaoru0822andClaude Opus 5.5 0cfef92ae1 fix(desktop): classify rejected desktop roots as target failures (#5577)
inspect-desktop-application reported a regular-file, missing or read-denied
root as artifact_operation_failed/execution_failure, leaving the ENOTDIR,
ENOENT or EACCES cause only in message text.

DirectoryArtifactReader now marks root admission and root-open failures with
DirectoryArtifactRootFailure. DesktopApplicationReader, which owns the caller's
selection, maps a non-directory root to unsupported_target and host failures to
the shared BinaryTargetError (target_unavailable, or access_denied with
read-access recovery), keeping any partial observation. Child-entry failures
and other DirectoryArtifactReader consumers are unchanged.

Fixes #5513

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 22:54:40 -07:00
Kaoru0822andClaude Opus 5.5 b81431d7ff fix(artifacts): report a stable symlink loop as a path resolution failure (#5571)
ELOOP raised while resolving the caller-selected path (access/realpath)
is a symbolic link loop or over-deep chain in that path, not evidence of
a change. Classify filesystem failures by resolution stage so only ELOOP
from opening the canonical path with symbolic links rejected keeps the
"target changed while being opened" reason. The structured code,
category and retryability are unchanged.

Fixes #5521

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 22:54:28 -07:00
4a7a4b5744 fix(hopper): preserve caller abort reasons on cancellation (#5780)
* fix(hopper): preserve caller abort reasons on cancellation

Hopper cancellation dropped the caller's abort reason, and the typed
error treated an explicit undefined cause as omission. Retain the exact
reason at the request queue, startup, socket, and launcher boundaries.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style(hopper): format launcher cancellation return

oxfmt rejects the wrapped abort return in HopperApplicationLauncher.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 13:53:02 +08:00
Kaoru0822andClaude Opus 5.5 4dfe3464b2 fix(signals): report rejected sigrok selectors as invalid input (#5570)
sigrok-cli refusals of a caller-supplied decoder ID or annotation class
were reported as execution_failure with "Run `rea doctor`" advice, which
has no sigrok check. Recognize the observed sigrok-cli 0.7.2 refusals at
the provider boundary only when the rejected name matches a caller
selector, and report invalid_request naming the decoders or annotations
argument, retaining the captured output and pointing to
inspect_signal_decoders. Other non-zero exits stay provider failures.

Fixes #5515

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 22:52:33 -07:00
Kaoru0822andClaude Opus 5.5 c1e04bf8c0 fix(sqlite): name the selected path in malformed-database errors (#5564)
The owned worker inspects only a private snapshot, so its format reason
cannot name the caller's selection. Project path-scoped worker rejections
with the selected database path so distinct malformed inputs report their
own source, matching the documented failure contract.

Fixes #5520

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 22:52:18 -07:00
a00e4ac363 fix(apple): refuse invalid binary dates and unknown sub-millisecond instants (#5786)
* fix(apple): refuse invalid binary dates and unknown sub-millisecond instants

Reachable binary plist dates must use marker 0x33. Other type-3 markers are
malformed and are no longer projected as observed timestamps. A valid float64
date stays known only when it is exactly the canonical millisecond instant;
other finite instants remain typed unknown dates with a counted limitation.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): share one decoder copy and bound binary date payloads

Wide-integer rewrites and unrepresentable date payloads now share the
single parser-input copy already reserved by the decode budget. Reachable
date markers and payloads must end at the offset table even when other
decoder-bounds checks read trailing bytes.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(apple): refuse out-of-region dates through the keyed reader

Decoder-bounds date truncation is now asserted on decodeKeyedArchiveBytes,
the path that selects those bounds.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 13:48:50 +08:00
morluto d36cb61210 fix(ci): declare the native fixture compiler for Knip 2026-10-21 13:36:46 +08:00
morlutoandCursor Agent 0ad42752d3 perf(test): reuse one compiled CLI for the remaining hot command files (#5784)
Go, IL2CPP, dylib resolution, and application-workflow tests were still
starting a compiled CLI for every command. They now reuse one process
per file. Warm focused runs dropped from 40s, 46s, 35s, and 21s to
14s, 21s, 20s, and 2s.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-21 13:34:37 +08:00
morluto dcdab56acb fix(test): use eligible bundle targets for UI availability 2026-10-21 13:33:15 +08:00
morluto 5af8fe702b fix(test): use owned cleanup for npm invocation fixtures 2026-10-21 13:30:36 +08:00
gensokyo-dev 7d8e4e4338 perf(model): avoid decoding omitted GGUF strings (#5781)
Validate omitted GGUF strings without materializing discarded text while preserving full UTF-8 checks and retained Evidence. Record real-model costs and workflow coverage; preserve failed experiment receipts through cleanup.

Fixes #5774.
2026-10-21 13:26:13 +08:00
Jeff 7c6c25dda7 fix(artifacts): report target applicability in session discovery (#5763)
* fix(artifacts): report target applicability in session discovery

* fix(artifacts): preserve resolved target applicability facts

* fix(target): retain bundle metadata for explicit formats
2026-10-21 12:59:27 +08:00
Jeff 89b1941c8e fix(native): preserve mixed-slice signature observations (#5765)
* fix(native): preserve mixed-slice signature observations

* fix(native): retain signature facts when slice inspection fails

* fix(native): accumulate known slice observations before failure
2026-10-21 12:59:10 +08:00
71b696582b perf(test): reuse one compiled CLI for export-binding parity (#5679)
* perf(test): reuse one compiled CLI for export-binding parity

The slow export-binding cases each spawned the compiled CLI three times.
One warm process now serves those JSON commands from a single command
instance, so startup and retained registrations are paid once per file.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style(test): format the warm CLI session

oxfmt --check rejected the session and its worker.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): report warm CLI shutdown, deadlines, and exit status

A compiled CLI session that needed a signal after stdin closed reported
success. A command that never answered left later checks waiting, and a
failure recorded only on process.exitCode was returned as status 0.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): close the warm CLI worker when a status check fails

The failure-then-success case only closed the compiled worker after both
assertions passed. Register the close with the test so a failed check still
stops the child.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): retain a timed-out compiled CLI worker until it exits

A request deadline cleared the child before SIGKILL was observed. The next
command could start a replacement, and close could miss the original process.
Retired workers stay owned until exit, and a failed stop remains for a later
close to retry.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): reject a compiled CLI launch that close interrupts

Closing during the ready handshake detached the child before the launch
promise settled. The queued command then waited on the startup timer.
Close now rejects that startup before the child is detached.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 12:57:04 +08:00
43ac3d1857 fix(windows): retain native handles when close is unconfirmed (#5772)
* fix(windows): retain native handles whose close is unconfirmed

CloseHandle failure no longer drops the numeric value. A still-open handle
stays owned and can be closed again; a value missing from the handle table
is dropped and never closed again; unreadable liveness blocks another close
until a probe says the value is open.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(process): keep scratch until inherited pipes close

Lock the execFileOutput settlement contract: an inherited-pipe descendant
holds the caller's scratch root until it exits, and destroying the readers
is not process-family completion.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(windows): retry admitted file closes before runtime removal

A failed private-file close stays on the runtime that opened it. Runtime
removal closes that same wrapper before the tree walk, including when the
read that opened the file has already returned.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(windows): resume a close after part of the owner is released

A runtime whose directory handle is already released continues with its
parent handles instead of walking that invalid root. A process whose
settlement was already observed retries process close alone, without kill
or poll against the released job.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(process): signal only an owned inherited-pipe descendant

Skip the descendant SIGKILL after pipe settlement. On an earlier failure,
signal only when the process command line still contains that test's path.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(windows): do not close a handle again after a failed close

An open liveness probe can observe a reused numeric value. After CloseHandle
fails, drop the value only when the handle table no longer contains it, and
do not call CloseHandle on that number again.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(windows): stop using a close-blocked pipe for I/O

A broken pipe whose CloseHandle fails stays owned, but its numeric value
may have been reused. Later polls and stdin writes treat that pipe as
ended instead of reading or writing the number.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 12:56:36 +08:00
morluto fa8b87c470 fix(il2cpp): validate generic-container extents before index widths
Validate the fixed 16-byte version-39 records before using their count to select the serialized index width. Reject contradictory count and byte extents while preserving valid zero, one and 300-record controls.

Validation: 89 focused reader/provider/compiled CLI and stdio MCP tests; check:ci; seven reproduced CLI and SDK-validated MCP cases with unchanged fixture hashes. Version-specific source and independent parser evidence distinguish fixed records from compressed indices. Synthetic metadata only; no real-game or target-execution qualification.

Fixes #5751
2026-10-21 12:55:35 +08:00
Matt Van Horn afa5da745e feat(artifacts): inspect and extract PyInstaller archives 2026-10-21 12:48:29 +08:00
morluto 22d5a40a2e fix(pe): inspect resource records at their declared offsets
Remove unsupported DWORD alignment refusals from resource data entries and adjacent directory tables. Preserve original record locations, UTF-16 name alignment, bounds, mapping, overlap checks and payload hashes.

Validation: 49 focused parser/provider/filesystem/lifecycle and compiled CLI/stdio MCP tests; check:ci; independent pefile agreement for the reported layout, padded control and PE32/PE32+ word-aligned directories. Public CLI and SDK-validated MCP retain truncated-input refusals and unchanged source hashes. Synthetic static inspection only; Windows loading was not tested.

Fixes #5750
2026-10-21 12:46:29 +08:00
gensokyo-dev 264862bf2e fix(ida): preserve registration recovery facts in readiness
Fixes #5771.

Preserve the configuration owner's parsed registration settings and remediation in IDA readiness, retain caller-selected paths, and distinguish configuration selection from validity and live connection. Verified with 84 relevant tests, CLI/MCP negative-case parity, static/docs gates, independent source review and repeated actual Codex recovery tasks. No real IDA engine/GUI analysis qualification.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-21 12:41:50 +08:00
044f180222 test(cli): accept opaque Kuna doctor run tokens (#5677)
* test(cli): accept opaque Kuna doctor run tokens

The doctor cancellation fixture parsed REA_PROCESS_RUN_ID as a UUID.
Kuna version probes publish rea-kuna-version-<uuid>, so both signal
cases failed before checking cancellation. Accept that opaque token
and keep the JADX ownership check on a UUID.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(cli): require the Kuna doctor run token

An omitted REA_PROCESS_RUN_ID disappears from the ready JSON. The Kuna
cancellation case now rejects that record unless runId is a non-empty
ownership token. JADX still requires a UUID.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 04:37:26 +00:00
morluto 3b67b362aa fix(apple): explain present rejected dylib candidates
Derive unresolved findings from stored candidate paths and outcomes while preserving weak, lazy and conditional load consequences. Document not-loadable and platform-mismatch outcomes and later-path resolution.

Validation: 126 resolver/CLI/MCP tests, check:ci, docs:check, and seven compiled CLI plus SDK-validated stdio MCP fixture cases. Source-built and mutated inert Mach-O inputs retained identical hashes; no target execution or dyld runtime comparison.

Fixes #5747

Fixes #5694
2026-10-21 12:34:05 +08:00
gensokyo-dev f1126ff7bf fix(wasm): retain actionable provider configuration diagnostics
Fixes #5767.

Retain exact WABT version-probe output and tool identity, including nonzero command failures, and provide condition-specific configuration recovery. Verified with 54 focused tests, the final 51-case real WABT CLI/MCP lane, actual Codex recovery trials, and independent source reviews. No provider installation, target execution or admission relaxation.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-21 12:25:28 +08:00
morluto 3a0e91dd91 chore: integrate concurrent main changes with the dylib fix
Preserve the upstream WAT framing optimization alongside the qualified dylib fix. The combined tree passes 14 compiled dylib CLI tests and the full check:ci gate.
2026-10-21 12:06:06 +08:00
morluto 90062c0922 fix(apple): trace legacy macOS dylibs with implicit platforms
Apply dyld’s implicit macOS compatibility rule only for a root executable with observed macOS platform and a supported candidate CPU type. Retain the absent platform fields as raw facts and expose the derivation on the candidate. Traverse the selected dylib and report missing required children; preserve unknown platform coverage and the later known fallback graph in other contexts.

Validation: 144 source/reader tests, 14 compiled CLI tests, 18 schema tests, full check:ci and docs:check passed. Four source-built app variants passed CLI and SDK-validated stdio MCP checks with unchanged fixture digests. No fixture executable or Apple dyld comparison was run. Independent review resolved a library-root authority gap before integration.

Sixteen cold/warm task-cost observations are retained locally with sampling limits; the catalog adds 66 bytes. Actual model tokens and maximum-sized inputs were not measured; no speedup is claimed.

Closes #5696
2026-10-21 12:04:29 +08:00
gensokyo-dev 70835d3d5f perf(wasm): skip payload text during WAT framing
Fixes #5760
2026-10-21 12:04:05 +08:00
ccfaf520b7 perf(test): reuse one compiled CLI process per JavaScript application file (#5676)
* perf(test): reuse one compiled CLI process per JavaScript application file

analyzeJavaScriptDirectory CLI cases were still starting a fresh process
after stdio MCP reuse. Keep one compiled process for the same child
environment so later cases skip Node and CLI startup.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): bound shared CLI worker lifetime

Retire a worker that reports a fatal failure before resolving that command,
and wait for it to exit before the next command starts. Join a session frame
once its bytes are complete instead of copying the unfinished buffer on every
chunk. Restart the shared process after 32 commands or a reported 1 GiB
resident set so one file does not keep a single heap high-water mark.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): retire a shared CLI worker after a transport failure

A malformed session frame rejected the command and sent SIGTERM without
clearing the worker. signalCode stays unset until the process exits, so the
next queued command could write to that same process. Transport failures now
use the fatal-reply retirement path and the queue waits for that exit.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 12:02:15 +08:00
gensokyo-dev bbbd208743 fix(pcap): preserve frames with empty protocol stacks (#5762)
Preserve valid empty TShark protocol stacks at the shared parser, retain frame and other fact inventories, and cover malformed producer output and mixed-frame ordering.

Validated with focused source/boundary tests, full static checks, docs checks, real Linux CLI/MCP and a mixed-interface public HTTP pcapng. Latest-head Codex found no issues; Greptile is 5/5 and its test-coverage thread is addressed. Remaining queued CI was bypassed under the human owner's explicit authorization; this does not claim that the full CI suite passed.

Fixes #5734.
2026-10-21 04:00:16 +00:00
morluto c19c2d6723 fix(native): separate container facts from Go metadata admission
Move ELF, PE and Mach-O container parsing into a shared native owner. Go alone selects and validates Go build-info sections, so unrelated malformed Go metadata no longer blocks Rust dependency or IL2CPP inspection. Remove the superseded Go-specific container representation and migrate all consumers. Adapted from draft PR #5510 without asserting human PR readiness.

Validation: 51 compiled CLI/MCP acceptance tests across Rust, Go and IL2CPP; 186 shared-reader tests; full check:ci passed. Three public synthetic-file probes reproduce the baseline Rust refusal and validate the fixed SDK-advertised MCP output, artifact digests and unchanged bytes. The exact zero-address nonallocated ELF case now succeeds for Rust while Go still reports invalid_format. No target execution or real compiler-artifact qualification was performed; no performance improvement is claimed.

Closes #3398
2026-10-21 11:58:15 +08:00
morluto 08f4ba99ce test(process): share lineage fixtures to restore the duplication gate
Extract repeated process rows, environment transitions and exact lineage expectations while retaining all identity, replacement-read and cancellation cases. Clean main exceeded the configured 3.5% duplication limit at 3.521867%; this refactor passes at 3.499188% without changing the limit.

Validation: 72 focused process-ownership tests and the full check:ci gate passed. Independent source review found no assertion or coverage loss. No runtime behavior changes.
2026-10-21 11:56:36 +08:00
df8b4d8a5a fix(process): token-check identityless exit-refresh replacements (#5675)
* fix(process): token-check identityless exit-refresh replacements

A launcher-exit refresh could drop a reparented grandchild that was absent
from the prior snapshot and report cleanup complete, or publish a verified
empty lineage, without reading its run token.

Fixes #5206

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): re-read identityless refresh rows when relations change

Lineage refresh classified every pre-existing process as a newcomer, and it
skipped a row after caching its first parent and group. Seed the exclusion
set from the initial snapshot and read a row again when that relation changes.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style: format files oxfmt rejects on main

Repo-wide format:check fails on these two files at current main. Align them
so the process-ownership fix can pass the required static check.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): keep owned groups found while confirming exit

An unreadable exit-refresh row used to hide the confirmation table, and
revalidation dropped groups discovered after the plan was built. Both now
stay in the same cleanup, and confirmation reads are bounded.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): reclassify lineage rows when tree membership changes

Initial outsiders and cached refresh rows are read again when a parent,
group, or ancestor move changes launcher-tree membership. Unchanged
initial rows stay unread.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): re-read cached identityless lineage tokens

Parent and group do not identify a process generation. A row whose token
was read is read again on the next refresh, so a reused PID cannot keep
a verified descendant.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): revalidate an owned group that reappears

A group discovered after it was already processed is queued once more.
Another appearance stays unresolved instead of reporting cleanup complete.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): recheck a helper that changes groups during confirmation

The confirmation table can move a token-matched member into a new group.
That row is read again, and cleanup signals the group it belongs to now.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): publish one lineage row when a descendant returns

A refreshed descendant replaces the initial row for the same PID, including
when its group moves away and then returns to the original relation.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): re-read foreign PIDs on the exit confirmation table

A readable foreign token does not identify a process that later reuses
that PID. The confirmation table reads those newcomers again.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): recheck a pre-exit PID whose relation changes

An unchanged pre-existing row stays unread. A prior PID whose parent or
group changed is token-checked, so a reused owned process is not skipped.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): recheck an initial descendant after its token matches

A successful read in the first lineage pass marks that PID token-checked.
A later refresh reads it again, so a reused PID cannot stay verified.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): recheck the launcher on each lineage refresh

A later refresh reads the launcher PID again. A missing or unowned
launcher is unavailable instead of rooting a verified lineage.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): publish lineage from the latest refresh table

A descendant missing from the latest refresh is omitted. A refreshed
launcher whose group or command no longer matches stays unavailable.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(process): cover a refreshed launcher parent mismatch

A same-token launcher whose parent no longer matches the committed
expected parent is unavailable, same as a group or command change.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(process): recheck a token-read helper that returns to its group

A confirmation table dropped a previously matched PID once its parent and
group matched the pre-exit row, so cleanup could signal only the group it
had joined and report success while that helper survived.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 11:43:17 +08:00
morluto 00266efe13 fix(plist): preserve Unicode separators during XML normalization
Use one XML 1.0 line-ending rule in the shared XML boundary and plist source-span owner. Normalize literal CRLF and CR while retaining NEL, line separator and paragraph separator as observed characters. Keep character references, raw scalar locations and prototype-key omission intact.

Validation: 229 XML/plist source tests, 60 adjacent Ghidra/Apktool/SAZ source tests, and 33 compiled CLI/provider tests passed. Full check:ci passed. Real plutil XML and binary fixtures reproduced the baseline loss and passed CLI plus SDK-validated stdio MCP checks with unchanged input digests. Independent source review found no blocker. Binary conversion losses tracked by #5701, #5703 and #5705 remain separate work.

Closes #5702
2026-10-21 11:42:25 +08:00
gensokyo-dev 335c042d16 docs(testing): reference the configured duplication limit (#5758) 2026-10-21 11:26:43 +08:00
morluto d0067ba34a fix(native)!: preserve Swift pointer nullability and import bindings
Resolve relative pointers using field-owned ABI encodings. Keep null, raw, rebased, imported and unknown targets distinct, and retain imported conformance rows with exact Mach-O binding provenance. Decode legacy rebase membership with source-derived memory and work bounds, preserving validated prefix facts when streams are incomplete.

Validation: check:ci, docs:check and build passed; 158 source tests and 20 schema/acceptance tests passed. Ten source-built Apple dispatch variants and four issue-specific CLI/MCP workflows passed without executing targets. Paired cold/warm CLI/MCP cost observations retained locally; model tokens and maximum-sized input runtime were not measured.

Closes #5683
Closes #5685

BREAKING CHANGE: Swift conformance type_name and protocol_name can be null when names cannot be resolved; consumers must use typed type_binding and protocol_binding evidence. MachoImportBinding replaces the former Objective-C-specific binding type and schema.
2026-10-21 08:17:12 +08:00
morluto 9258df02cc test(apple): compare asset catalogs from matching root workflows
Compare explicit bundle-resource CLI and MCP results at the positive empty-inventory offset. Preserve a separate binary-bound MCP assertion with the exact fixture executable digest and complete metadata payload.

Validation: reproduced the stale root-versus-binary parity failure on current main, then passed the macOS public CLI/MCP acceptance case across all five NIB fixtures. Focused lint, formatting and diff checks passed. No target code was executed.
2026-10-21 07:37:36 +08:00
morluto 1502cfbc8c fix(apple): resolve absolute dylib paths inside the selected root
Preserve load-command paths as evidence while passing a separate root-relative lookup path to the bounded tree resolver. Apply the same containment rule to absolute install names and rpath bases, including caller-selected root symlink spellings.

Validation: 140 source tests, full check:ci, docs and runtime build passed. Compiler-built literal, rpath and relative fixtures passed CLI/stdio MCP parity, preserved both dependency edges and left all bytes unchanged. External system paths stayed outside-target; relative control was unchanged. Fixtures were not executed, and actual dyld execution was not qualified.

Closes #5637
2026-10-21 07:37:15 +08:00
morluto 84c89d1107 test(javascript): separate heap pressure from graph admission proof
Match memory failures to the exact source identity instead of graph ordering. Preserve CLI parse, file-evidence, partial-result, later-source and unchanged-input checks across valid memory-pressure outcomes. Use a controlled parent heap envelope with a real owned analyzer to prove module retention and graph rejection independently of host GC timing.

Validation: full check:ci passed; 17 focused tests passed, with the final 4 changed tests rerun successfully. Independent test-strength and isolation review passed. The earlier hosted failure exposed missing graph-only fields; its exact alternate memory stage was not captured.
2026-10-21 07:26:20 +08:00
morluto 0bd14ca16c fix(browser): preserve uncertain main-frame navigation identity
Own CDP frame applicability and identity at the parsed event boundary. Preserve malformed or incomplete main-frame facts, recognize replacement roots, and carry the same document identity through captures, screenshots, timelines, and execution windows.

Validation: full check:ci and docs:check; 763 browser and dispatch tests passed, 6 skipped. Independent source and fixture-lifecycle review passed. Local real-Chrome behavior was not exercised.

Closes #5665
2026-10-21 07:16:47 +08:00
morluto 9dee989a79 fix(native): count Objective-C coverage by class object
Count each admitted unique class or metaclass object at its parsing owner. Preserve emitted metadata, independent class-list scan bounds, partial failures, and truncation.

Closes #5706
2026-10-21 07:01:17 +08:00
morluto f789fd1fd8 fix(native): count Swift vtable coverage in slot units
Count examined and decoded vtable slots in the same population, preserving all returned slots and partial descriptor failures. Document the coverage unit and retain malformed-sibling and unresolved-slot checks.

Closes #5681
2026-10-21 06:56:18 +08:00
morluto ccc7da309d test(mcp): retain distinct Objective-C class observations
Require both fixture addresses and unknown identity coverage when no selected-image binding proof permits coalescing.
2026-10-21 06:45:34 +08:00
morluto 56679dd2ae fix(files): preserve physical read provenance through cleanup
Keep raw physical read diagnostics alongside explicit operation provenance on the same cleanup owner. Preserve provenance after successful close retry for opted-in readers, restore legacy error projections, and prevent borrowed cleanup-shaped failures from authorizing foreign resource retries.

Refs #5686
2026-10-21 06:45:34 +08:00
morluto 52c84f6f58 test(cli): bound ADB MCP validation to the advertised tool
Reuse the exact selected advertised descriptor for SDK output validation instead of compiling the entire cached catalog for every fresh parity-test client. Retain actual catalog discovery, schema validation, and all result assertions under the existing worker heap limit.
2026-10-21 06:23:20 +08:00
morluto 4852c830af fix(native): preserve Mach-O names equal to version
Parse only documented compound otool field labels so valid segment and section names are retained at the owning boundary. Verified real Apple clang fixtures through compiled CLI and stdio MCP without executing the targets.

Closes #5680
2026-10-21 06:19:43 +08:00
morluto 949966712e fix(files): preserve physical read failures across late cancellation
Tag physical read outcomes at the owning boundary and preserve opaque caller cancellation reasons through JSON pipelines and reference imports. Share named bounded-read options across consumers and retain failed cleanup ownership for retry.

Closes #5686
2026-10-21 06:14:03 +08:00
morluto 4d7de00d4c fix(native): coalesce Objective-C class imports by binding identity
Join provider class observations only when selected-image identity and exact import bindings establish equivalence. Preserve distinct observations and unsupported coverage.

Refs #5607
2026-10-21 06:12:21 +08:00
morluto b231c28cf6 fix(hopper): own Mach-O preparation through cleanup retry
Preserve exact selected-image identity and descriptor ownership across preparation, final cleanup, and retries. Keep physical failures and failed cleanup leases observable through provider and launcher boundaries.

Closes #5688
2026-10-21 06:12:09 +08:00
morluto 7dd6941393 refactor(test): share browser and apktool fixture lifecycles 2026-10-21 05:50:50 +08:00
morluto 1bb2fa23de test(apple): match plist provenance to the selected workflow 2026-10-21 05:50:50 +08:00
morluto ab58edcdf5 fix(environment): retain tarball descriptor ownership during export
Use the shared positional reader for both tarball passes so early output refusal cannot close the descriptor ahead of its owner.

Closes #5684
2026-10-21 05:33:35 +08:00
morluto 60956c8c56 fix(ci): run cache retention from its trusted workflow revision 2026-10-21 05:28:08 +08:00
morluto 5518363aa6 test(artifacts): compare matching resource-root workflows 2026-10-21 05:28:03 +08:00
morluto 4108d1363a test(cli): align Kuna readiness and cancellation expectations 2026-10-21 05:27:56 +08:00
morluto 0bc2b42001 fix(browser)!: preserve unknown WebSocket frame facts
Keep malformed or missing CDP opcodes and payload facts unknown, retain observed zero and empty payloads, and avoid false capture differences while preserving independently known facts.

Validation: 59 source tests; compiled public CLI and stdio MCP fake-CDP acceptance; check:fast; docs:check; changed-file formatting. Real Chromium malformed-event behavior was not tested.

BREAKING CHANGE: WebSocket event opcode is nullable and numeric values are restricted to the four-bit protocol range.

Fixes #5666
2026-10-21 05:00:37 +08:00
c38f96fa69 test(cli): keep IPC trace input under the Linux spawn limit (#5673)
* test(cli): keep IPC trace input under the Linux spawn limit

The listener-callsite CLI builds one trace argument from the full
application Evidence document. On 4 KiB-page Linux that string exceeds
MAX_ARG_STRLEN, so spawn throws E2BIG before the command starts. Keep the
document in a file, require the spawned argv to fit the single-argument
budget, and lock that budget through the test process registry.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(process): size the spawn ceiling from ARG_MAX and MAX_ARG_STRLEN

A payload at the single-string limit still fails execve with E2BIG when
the stack shrinks ARG_MAX below the rest of the image. Accept only the
bytes that fit both budgets, and skip that success spawn when the fixed
argv and environment already fill ARG_MAX.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style(test): format files rejected by oxfmt in static checks

check:ci:fast failed format:check on the CLI fixture import and, after
merging main, on the admission test's new command-abort case.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 04:48:33 +08:00
Ulises Millán c4b6aa3061 fix(managed): treat extension-only module scopes as unknown identity (#5674)
Closes #5467
2026-10-21 04:35:45 +08:00
morluto dceefa22cb Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 04:22:27 +08:00
morluto 6a6adf703f fix(resources)!: inspect app resources without an executable
Add a read-only app resource session shared by CLI and MCP. Preserve resource-root provenance without inventing executable identity, reject binary-only snapshots and operations, and retain failed cleanup owners across switches and retries.

Keep filesystem admission failures typed and preserve cancellation ordering from observed cleanup facts. Document resource routing in the packaged investigation skill.

BREAKING CHANGE: resource-only observations may have a null Evidence subject and null executable target digests. Clients must use resource_root and reported per-resource provenance instead.

Refs #5589
2026-10-21 04:22:20 +08:00
de4579e993 fix(observation): keep incomplete cancellation observations (#5644)
* fix(observation): keep incomplete cancellation observations

Service projection treated a retained observation that failed the completed
schema as a malformed completed result. Cancellation became unreadable_output
and the partial was dropped. Incomplete observations now stay on the owner
error, including the exact abort reason.

* fix(observation): drop non-JSON incomplete observations

Keep a retained partial only when projectAnalysisError can serialize it.
Clear a non-JSON partial and record an AnalysisOutputError as a secondary
failure so cancellation and timeout stay the owner error.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(observation): validate incomplete partials without copying

jsonValueSchema.safeParse cloned a JSON-safe partial that projection
copies again. Use jsonValueValidationIssue so the gate only checks.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(ida): expect non-retryable unresolved procedure lookups

Main stops treating invalid_request as retryable. An unchanged missing
procedure stays invalid_request and is not marked retryable.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(observation): share incomplete-observation assertions

The new non-JSON cases repeated the same owner-error checks and pushed
duplication over the 3.5% limit. One expectation helper keeps those
checks without a second copy.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(observation): keep the assertion helper out of the package

The helper imports Vitest. Rename it to a fixture so the production
build excludes it and dist does not import a dev dependency.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(observation): clear non-JSON partials on cleanup primaries

Projection can return the cleanup primary after retry. Clearing only
the wrapper left that primary's partial in place, so projectAnalysisError
threw. The gate now clears every non-JSON partial in the chain.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(observation): freeze retained incomplete observations

A JSON partial stayed a live provider object, so a later mutation could
make projection throw. The gate now keeps one frozen snapshot and still
drops a non-JSON partial without copying it.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* refactor(observation): share web runtime partial retention

Observe and inspect used the same promote-or-keep path. One helper
owns that sequence so the two operations cannot drift.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(observation): snapshot a shared partial once

A cleanup wrapper and its primary can hold the same partial object.
The gate now reuses the first frozen snapshot for that object.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(observation): parse a kept partial once

jsonValueSchema.safeParse validates and copies only a JSON partial.
The gate freezes that copy and no longer walks the same value first.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(observation): share repeated observation fixtures

The incomplete-observation tests repeated the same provider setup and
an empty Electron coverage tail, which pushed duplication over 3.5%.
One coverage fixture and shared assertions bring the tree back under
the threshold.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 04:17:46 +08:00
6b101ff23b fix(errors): preserve caller abort reasons at admission (#5671)
* fix(errors): preserve caller abort reasons at admission

Keep the opaque caller reason on reverse, pcap, and SQLite cancellation,
and leave a recognized physical digest or command failure in place when a
late abort is also observed.

Fixes #5670

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(reverse): keep a foreign digest ABORT_ERR as an adapter failure

Treat ABORT_ERR as cancellation on the command boundary, where that code
already meant an aborted provider process. A digest or stat rejection with
the same code stays a physical adapter failure unless the caller signal
is aborted. Cover aborted command EACCES, ETIMEDOUT, and ABORT_ERR with
and without captured output.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 04:16:44 +08:00
morluto 6389e50337 Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 03:57:03 +08:00
morluto d23be5c089 fix(web): preserve static WebMCP schema property coverage
Reuse the shared object-member owner for literal spreads, retain known property names under unresolved membership, and distinguish complete, partial, unknown, and absent projections. Keep historical coverage omission unchanged and preserve own keys across prototype setters.

Refs #5075
2026-10-21 03:56:35 +08:00
c0cbbf8d50 perf(ci): keep fast built shards under ten minutes (#5652)
* test(acceptance): split competing loader ownership across files

The loader matrix was one 578-second file, which set the floor for any
shard that received it. Three files keep every CLI and MCP case and let
workers overlap them.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* perf(ci): run eight fast built shards under a ten-minute budget

Charge each Vitest project by its resolved worker width so serial
process-boundary files spread as tail time. Fast feedback uses eight
built shards. The npm download cache stays; node_modules is too large
to ship as a shared artifact.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(ci): keep each scheduled file on one worker lane

Dividing a file by maxWorkers dropped its own wall-time floor and could
pack a parallel file onto a serial tail. Place each file whole on a lane,
overlap peers only inside a sequence group, and add later groups after.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* docs(testing): separate the shard budget from workflow time

The ten-minute figure is the built shard job. Classification, build, and
the portable-test merge are measured separately on run 39451548945.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* docs(testing): match fast shard count to lane scheduling

Main still described five shards and half-duration weights. Fast
qualification uses eight shards, and each file keeps its full duration
on one worker.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(ci): seed split loader durations from pre-split history

Timings published before the file split still name one 578-second path.
Until a new file appears in that artifact, share the recorded duration
by the pre-split case counts.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 03:55:40 +08:00
morluto a7d13893a6 Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 03:50:44 +08:00
morluto 1bfa60ac20 fix(cli): preserve caller-selected JSON paths
Keep POSIX symlink-parent traversal at the shared JSON input boundary and forward the selected browser executable without a second lexical normalization. Verify Electron, browser, and Evidence-file consumers through registered commands and the built CLI.

Refs #5103
2026-10-21 03:50:14 +08:00
9d8e780332 ci: keep npm download caches from Turbo snapshot growth (#5655)
* ci: keep npm download caches from Turbo snapshot growth

Per-commit static and portable Turbo snapshots had filled the 10 GB Actions
cache, which is what makes warm npm ci cheap. Trusted static runs now keep two
generations and one download-cache writer per host.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(ci): declare cache retention types for strict checks

Typecheck imports cache-retention.mjs and needs a sibling declaration.
The generation count stays module-private so knip does not report it.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(ci): keep compatible caches and qualification read-only

Npm dedupe deletes a record only when another has the same key, version,
and ref. Cache deletion moves to a follow-up workflow so reusable
qualification can keep its read-only token.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(ci): retain caches after failed default-branch runs

Static and build save Turbo snapshots before later lanes finish. Retention
now follows a failed, timed-out, or cancelled trusted run, not only a green one.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(cli): pass application trace input as a file

The CLI already reads workflow JSON from a path. Putting the full
application Evidence document on argv exceeds the runner argument limit.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(ci): retain deep and Knip snapshots without deleting a repeated id

Fast and deep static checks publish rea-static-deep-v1 and knip-meta-v1
entries per commit. Retention prunes those families with the same two-generation
rule. A cache id listed twice is one record; inconsistent repeats abort
before any delete.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 03:48:14 +08:00
40428da1dd perf(test): reuse one stdio MCP server per JavaScript application file (#5658)
* perf(test): reuse one stdio MCP server per JavaScript application file

Repeated analyzeJavaScriptDirectory MCP cases started a full server for
every case. Share one file-scoped server and compile cache so later cases
skip that startup while CLI cases still launch a fresh process.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): close in-flight shared MCP startup with the file

File teardown waits for a stdio session that is still starting, skips a
server once close has begun, and still closes one registered during that
wait. The later-case reuse test can run without the earlier case.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): keep a failed MCP handshake when cleanup fails

The shared session reports the startup error and carries the cleanup failure
as its cause. A cleanup that failed stays owned and is retried on close
without running a cleanup that already succeeded.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): fail shared MCP cleanup when the rejection has no reason

A cleanup rejection of undefined still fails the drain and stays owned.
Close caches completion only after every retained cleanup succeeds, so a
later close can release it.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(test): keep one MCP server while failed cleanup is retained

A later call retries retained cleanup before opening another server. The
new server starts only after that cleanup succeeds.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 03:46:14 +08:00
morlutoandCursor Agent ef59174c1e fix(errors): name fixed allowances in resource-constraint recovery (#5633)
* fix(errors): name fixed allowances in resource-constraint recovery

Fixed parser, count, report, input, and capture refusals inherited
host-memory, wait-and-retry, or retained-Evidence advice. Producers now
attach allowance-specific recovery, and deterministic capacity caps are
not retryable. IL2CPP reader occupancy stays retryable capacity.

Refs #5556, #5405, #5456, #5459, #5460, #5504, #5505, #5506, #5537, #5628, #5630, #5631, #5632

* fix(il2cpp): keep a closing metadata reader non-retryable

close() stops admission before the active inspection finishes. A second
inspect in that window was projected as retryable capacity. Closing and
closed readers now report capability_unavailable. Occupied readers that
remain open stay retryable.

* fix(errors): align fixed-cap recovery with retained facts

IL2CPP report refusals keep observed source facts instead of denying Evidence. Command-output caps use the capture allowance. Ghidra seed recovery names the limit that was exceeded.

* fix(errors): call byte caps a byte allowance

WASM representation limits and the IL2CPP Ghidra seed-file cap are byte budgets. Their recovery no longer says the exceeded allowance is a fixed count.

* test(ida): keep unresolved procedure lookups non-retryable

Main now treats an unchanged invalid request as non-retryable. The IDA lookup tests follow that projection.

* fix(errors): qualify capture recovery for live output

A fixed capture allowance still rejects the same output. Live captures such as adb logcat can change between requests, so recovery no longer says every unchanged request fails again.

* fix(adb): keep a truncated live capture retryable

Device output can shrink between calls, so an adb capture that exceeds the allowance stays retryable. Deterministic capture and version-output limits stay non-retryable.

* fix(adb): keep truncated mutations non-retryable

Only live observations opt into retrying a capture that exceeded the allowance. Push, install, uninstall, and other mutations stay non-retryable.

* fix(errors): keep live capture recovery off deterministic limits

Artifact-derived capture allowances again say the unchanged request fails. Only volatile adb observations use the live-output sentence.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-10-21 03:45:34 +08:00
53e0943223 fix(javascript): preserve path reasons, module coverage, and property provenance (#5651)
* fix(javascript): preserve selected path host resolution reasons

Classify ELOOP and ENAMETOOLONG while resolving the caller-selected input so the path and host code stay on the invalid-request issue.

Refs #5623

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): count summary coverage in module units

Use the module population for both examined and total counts. Non-module graph nodes remain in the application coverage section.

Refs #5464

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): connect direct property reads to return and argument flow

Record the unwrapped value expression and alias the object projection's read occurrence so a direct member read stays in backward provenance.

Refs #5585, #5648

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): count return wrappers against expression depth

Evaluate the original return expression so erased TypeScript and Flow wrappers stay inside the expression-depth budget. Keep the unwrapped node for identity and value ranges.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): describe ELOOP as unresolved symlink traversal

A host can return ELOOP for a cycle or for a chain past its traversal limit. Keep the selected path and code without asserting that a cycle exists.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(javascript): skip symlink traversal fixtures on Windows

Keep the overlong-name case portable. Windows does not produce ELOOP for these fixtures, matching the other path-failure tests.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(javascript): describe ENAMETOOLONG as a path or component limit

realpath reports that code for a long component and for a long full path. Keep the selected path and host code without claiming only a filename was too long.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style(javascript): format return-depth and object-read changes

oxfmt rejected the return-depth test and the object-read index. No behavior change.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(ida): expect unchanged invalid requests to be nonretryable

The shared projector no longer marks invalid_request retryable. This lookup assertion was not updated with that contract.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 03:45:10 +08:00
b718ad166d fix(doctor): reject unusable Kuna caches and invalid native settings (#5647)
* fix(kuna): reject dangling cache roots in doctor

Treat a cache path as creatable only when no directory entry occupies it.
A dangling symbolic link, including one hidden by a trailing separator,
fails the cache check and clears provider availability while the installation
check and caller-selected registration settings remain.

Fixes #5554
Fixes #5105

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(doctor): admit the same settings native analysis rejects

Project parseConfig failures into scoped engine readiness. Invalid provider
preferences, startup timeouts, and other shared settings now fail the
selected provider and the full audit, while a JEB-only timeout stays outside
that admission.

Fixes #5454

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(doctor): report an invalid log level from doctor

The dispatcher rejected REA_LOG_LEVEL before every command, so doctor never
emitted its readiness check. Doctor now runs and names that setting; other
commands still stop before execution.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(doctor): require log-level failures in every scope

An invalid REA_LOG_LEVEL stops the executable and MCP server before a client
or skill can run, so those scopes now fail readiness too. Other native
admission failures stay limited to a selected provider.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(kuna): strip only the platform cache separator

On Darwin and Linux a trailing backslash is a filename character. Doctor now
removes only the selected platform separator before inspecting the cache path.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(doctor): fail every provider on an invalid Hopper timeout

REA_HOPPER_STARTUP_TIMEOUT_MS is rejected before any native engine starts.
A selected non-Hopper provider now includes the existing timeout check.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style(doctor): format the Hopper timeout regression

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(doctor): fail client scopes on MCP startup errors

A registered client starts the MCP server, and parseConfig rejects every
native admission failure before that server starts. Client readiness now
includes those failures, not only REA_LOG_LEVEL.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 03:44:49 +08:00
morluto 690fc51854 fix(browser)!: preserve unknown console timestamps
Retain absent or invalid Runtime timestamps as null and mark console event coverage incomplete. Preserve observed finite timestamps, including zero, and document the epoch-millisecond clock.

BREAKING CHANGE: console event timestamps may now be null when the protocol does not provide a finite number.

Refs #5656
2026-10-21 03:43:20 +08:00
23196daa11 fix(apple): read LC_LAZY_LOAD_DYLIB_INFO dependency payloads (#5650)
* fix(apple): read LC_LAZY_LOAD_DYLIB_INFO dependency payloads

Parse the linkedit install name for lazy-load info commands, resolve those
edges without traversing them, and stop inspect-macho from treating an otool
dependency list as exhaustive when that payload is omitted.

Fixes #5551
Fixes #5649

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): bound lazy-load payload reads and image offsets

Reuse identical LC_LAZY_LOAD_DYLIB_INFO ranges, cap their combined size,
and reject flag or chain-start offsets outside the slice VM range.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): bound lazy-load string scans and contained reads

Reject payload strings that start in the 24-byte header, validate each
file-offset string once, and reuse payload bytes already read for a
containing range.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): reject cached lazy-load strings outside a payload

Remember each cached string's terminating offset and require that NUL to
fall inside the payload being decoded.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): bound lazy-load payload range lookups

Count containment checks across earlier payload reads and stop at the
existing 16 MiB work limit.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): count every lazy-info string reference

Charge repeated and overlapping LC_LAZY_LOAD_DYLIB_INFO scans against the
16 MiB validation budget, and stop a scan once that budget is exhausted.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): cap retained lazy-info dependency results

Stop after 1024 LC_LAZY_LOAD_DYLIB_INFO commands so a load-command region
full of identical commands cannot become a million traced edges.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): reject a lazy-load path NUL in the final byte

dyld stops the load-path scan before the payload's last byte, so a
terminator in that byte leaves the image malformed.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): keep may-be-missing lazy loads optional

A missing LC_LAZY_LOAD_DYLIB_INFO with the may-be-missing bit is weak, so the lazy finding says dyld continues on first use instead of failing.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* fix(apple): cap lazy-info symbol string references

A payload of distinct one-byte symbol strings stayed under the byte budgets while caching one entry per offset. A slice now stops at 65536 symbol references.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 03:33:07 +08:00
0add6a5aae ci: split fast and deep static checks (#5634)
* ci: split fast and deep static checks

Fast PRs run typecheck, lint, and format before provider admission.
Knip, duplication, architecture guards, and Python stay on the full tier.
Shared-boundary fallbacks keep the Linux x64 baseline, and Turbo jobs
export remote-cache credentials when they are configured.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* ci: keep pull requests from writing the remote cache

Trusted default-branch runs still receive TURBO_TOKEN. Pull requests get an
empty token and remote read-only mode. Knip saves a per-commit cache key so
the next trusted full run can refresh the restored snapshot.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* ci: forward the release cache token and upload deep static reports

Release qualification now passes TURBO_TOKEN into the called workflow.
Labeled pull requests still do not. The deep static job records its task
context and uploads duplication reports after a failed gate.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* style: format the turbo cache policy test

Co-authored-by: morluto <morluto@users.noreply.github.com>

* ci: keep fast checks exclusive and trusted cache writes explicit

Declare the static artifact name and context script so typecheck matches the
implementations. Lock check:ci:fast around dist, and publish the remote cache
only for release qualification or default-branch push, schedule, and dispatch.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* ci: record static task graphs without nesting the artifacts lock

Keep check:ci:fast locked, and point graph recording at the unlocked
check:ci:fast:tasks script so check:pr and check:test can record hashes
while they already hold that lock.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* ci: keep unauthenticated Turbo runs on the local cache

Open pull requests do not receive TURBO_TOKEN, so a remote read mode cannot
authenticate. Those runs now use the local cache. Trusted runs still publish.

Co-authored-by: morluto <morluto@users.noreply.github.com>

* test(ida): treat unchanged invalid requests as nonretryable

Main already stopped marking invalid_request retryable. The pull request
merge runs that projector, while the IDA lookup tests still expected
retryable true. Match the merged behavior.

Co-authored-by: morluto <morluto@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: morluto <morluto@users.noreply.github.com>
2026-10-21 03:29:31 +08:00
morluto 0dbc046ca6 Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 03:28:13 +08:00
morluto 2a0410f171 fix(browser)!: bind session timelines to the observation window
Sample the browser monotonic clock with observation already subscribed, filter historical lifecycle and network facts, and preserve scope and termination handling when event time is unknown.

Bound pre-arm retention using transport-owned wire bytes. Fail closed when the relevant-event buffer fills, and keep unrelated protocol payloads outside that budget.

BREAKING CHANGE: observe_web_session timeline timestamps can be null when the producer supplies no comparable timestamp. Consumers must handle unknown time explicitly.

Refs #5609
2026-10-21 03:27:31 +08:00
gensokyo-dev 4bfdadb7de perf(frida): add retained summaries for session status (#5661)
Add opt-in Frida session status summaries linked to complete retained Evidence. Share canonical session facts across contracts and preserve observed state, source identity and capture truncation.

Validated with native SDK/client workflows, default delivery compatibility, lifecycle and provenance tests. The completed large-history task uses 50.9% fewer estimated request tokens; no general CPU or latency improvement is claimed.

Fixes #5640
2026-10-21 03:21:30 +08:00
morluto 1629266e3c fix(errors): preserve canonical failures and correction details
Retain process input and unexpected failure diagnostics through the shared error projector. Preserve filesystem causes and firmware validation issues, and mark unchanged invalid requests nonretryable.

Use typed stat settlement and parse unknown command failures without losing null or undefined rejection causes.

Refs #5397, #5401, #5402, #5642
2026-10-21 02:03:17 +08:00
morluto b3aadaf474 fix(il2cpp): preserve recognized truncated metadata prefixes 2026-10-21 01:47:09 +08:00
morluto eb7acc70bf fix(native): verify signature snapshots and frame unsigned diagnostics
Bind and recheck the digest-verified snapshot used by codesign, retaining cleanup ownership when its identity changes. Classify unsigned only from the exact operand-framed diagnostic so echoed caller paths cannot turn unrelated failures into signature facts.

Closes #5636
2026-10-21 01:35:44 +08:00
morluto 998882045b Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 01:31:57 +08:00
morluto eb41f358cf fix(model): retain completed GGUF facts on interrupted reads
Keep parser-owned completed metadata and tensor declarations as typed partial Evidence on cancellation or physical read failure. Preserve unknown final identity and digests, exact caller inputs, primary failures, and retained cleanup owners; support inline and retained MCP error delivery.

Closes #5625
2026-10-21 01:31:17 +08:00
gensokyo-dev 17f581ff75 perf(reverse): add retained GDB and objdump summaries (#5614)
Add opt-in retained GDB and objdump summaries using the shared analysis-view layer. Preserve default complete Evidence, ordered records, provenance and completion facts.

Validate real Bash disassembly, whole-client context costs, CLI publication and cleanup; retain the original measured cohorts and explicit coverage limitations.

Closes #5584.
2026-10-21 01:20:52 +08:00
morluto edbd291a28 Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 01:13:13 +08:00
morluto 2b263a7fe9 fix(native): retain Mach-O facts when dyld rejects missing UUID
Admit only the corroborated missing-UUID validation diagnostic from header-stripped dyld stdout. Preserve readable load commands and nm exports with unknown dyld coverage, and keep unrelated process and tool failures typed.

Closes #5606
2026-10-21 01:12:51 +08:00
gensokyo-dev d98fc3859d test(evaluation): include native preparation in test deadlines (#5627)
Derive Darwin subprocess test budgets from the bounded ownership compiler budget while preserving short command deadlines. Always join the retained command scope after test failures.

Refs #5094.
2026-10-20 17:10:11 +00:00
morluto d0eca0517e Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 01:02:22 +08:00
Kaoru0822andClaude Opus 5.5 85b379c4ca test(evidence): assert the exact cancellation reason after staging cleanup fails (#5601)
52d1a72af made a cancelled write whose staging cleanup also fails carry the
caller's exact abort reason as its cause, with the cancellation retained as
cleanupPrimary and the staging directory as cleanup state. The boundary test
still expected the old wrapped cause, so it failed on main and in every PR
built on it; its finally block then masked the assertion with a cleanup
error. Assert the current contract.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 10:01:56 -07:00
morluto 22c84ce64a fix(hopper): recognize stripped Objective-C class labels
Classify legacy class-object names at the Hopper boundary and carry the typed fact into class discovery. Preserve exact labels, literal filtering, unrelated row metadata, and raw replies; derive classification from source text rather than incoming tags.

Closes #5617
2026-10-21 01:01:42 +08:00
morluto dd0015aaf1 fix(ida): own registration reads and bind selected configuration
Read bounded regular registrations asynchronously with retained descriptor cleanup. Carry the selected parsed configuration through provider factories and restoration, preserve exact cancellation reasons, and share workspace-parent resolution with doctor checks.

Closes #5561

Closes #5559

Closes #5604
2026-10-21 01:00:00 +08:00
morluto 7d6f90485e Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 00:53:09 +08:00
morluto 04ae07ab8c fix(kuna): bind version probes to stable executable identity
Compare executable fingerprints before and after the owned version probe, and capture the script prefix from the final hash stream. Preserve partial facts and failed-close ownership without claiming process interruption from a snapshot.

Closes #5611
2026-10-21 00:52:53 +08:00
gensokyo-dev 98f4072f1f feat(model): inspect GGUF and safetensors declarations (#5603) 2026-10-21 00:50:50 +08:00
morluto 5b676ba9f3 Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 00:32:49 +08:00
morluto 14cd78c322 fix(apple): retain unsupported NIB connectors in connection coverage
Recognize AppKit binding connectors as explicit unknown connection facts and
report partial semantic coverage rather than silently omitting them. Share
format-aware connector admission across keyed archives and NIBArchive.

Make the keyed archive table own parsed class and superclass facts for names,
array hierarchy traversal, inherited connectors, and class-table projection.
Preserve malformed class evidence and exclude unrelated custom class names.

Validation: 84 focused tests passed, including compiled CLI, filesystem,
MCP summary, and retained views; check:fast and test discovery passed.
Independent source review found no blocker. Production CLI and stdio MCP
replayed a read-only copy of Terminal 2.15's picker NIB: 13 connections with
partial unsupported-type coverage, versus baseline 9 with complete coverage.
Advertised schemas and retained coverage results validated with the SDK/Ajv.
No app, analysis target, or optional deep provider was executed.

Fixes #5590
2026-10-21 00:31:00 +08:00
gensokyo-dev 8716b52411 fix(evaluation): prepare and retain native ownership helpers (#5615)
Prepare native process ownership outside short command deadlines. Reuse the shared cleanup adapter and resource scope for direct/nested preparation failures and command cleanup.

Fixes #5094.
2026-10-20 16:29:46 +00:00
gensokyo-dev a35623707e fix(mcp): guide client and provider timeout recovery (#5608)
Teach client deadline recovery before REA results can be discarded, distinguish
producer-owned server budgets, and preserve Evidence/cleanup uncertainty.
Include actual Codex CLI recovery probes and CLI/MCP regression coverage.

Fixes #5598

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-21 00:16:44 +08:00
gensokyo-dev 2a6fc712eb fix(evaluation): join owned command cleanup before removing files (#5613)
Use shared owned command supervision for all evaluation helpers, join streamed output, and retain/retry incomplete cleanup before deleting run files.

Fixes #5094.
2026-10-20 16:16:29 +00:00
morluto 506400748e fix(electron): count bridge listener registrations by source callsite
Keep directly observed renderer listeners singular when bridge traversal
reaches them, while retaining separate paths for every exposed bridge member.
Preserve separate physical callsites and on/once operation identities.

Validation: 190 focused tests passed, including public CLI and stdio MCP
analysis and incoming feature tracing. Typecheck/lint and discovery passed.
The inert fixture was analyzed statically; no Electron target was executed.

Three alternating synthetic CLI tasks showed overlapping wall times (median
1.825s baseline, 1.808s current). Corrected bridge provenance increases serialized
task payload; no speed or context reduction is claimed. Actual model tokens
and full process-family CPU/peak memory were not measured.

Fixes #5586
2026-10-21 00:14:11 +08:00
morluto 57d64b6ba5 Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-21 00:09:56 +08:00
morluto ff78165978 fix(kuna): own version-probe processes through output and cleanup
Use the shared command supervisor for installation probes and retain exact
process cleanup owners through doctor, profile resolution, and session health.
Preserve exit status, bounded captured output, cancellation reasons, and live
cleanup facts. Block subsequent inspection until retained cleanup is retried.

Generalize the existing inspection resource scope and migrate its consumers,
including verifier scripts; remove the verifier's duplicate raw version probe.

Validation: 116 distinct focused tests passed, including built CLI doctor with
inherited output, cancellation/finalization, cleanup retry, and fake-provider
verifier workflows. Build, check:fast, and test discovery passed. No real Kuna
distribution or analysis target was executed.

Synthetic Darwin inspection timing: first-call median 707ms versus 5.79ms;
same-process repeat 37.9ms versus 3.08ms. First use includes ownership-helper
preparation. Family CPU and actual peak family memory remain unmeasured.

Fixes #5557
2026-10-21 00:09:34 +08:00
gensokyo-dev c3d7d0aafc fix(browser): honor long passive observation windows (#5605)
Reuse the cancellable segmented wait and settle observation termination through one cleanup owner. Preserve caller cancellation and release timers/listeners across early target end.

Fixes #3929.
2026-10-20 15:56:15 +00:00
morluto 90e433df06 fix(swift): retain uncertainty for unsupported nested identifiers
Stop inheriting an outer nominal category when a zero-prefixed identifier cannot be decoded. Preserve exact manglings in unresolved results under class and enum filters while retaining ASCII nominal controls.

Validated 39 source and in-memory MCP tests, typecheck/lint, and 22 compiler-produced code symbols from an inert Swift 6.3.2 object. No real Hopper inventory or target execution. Fixes #5553.
2026-10-20 23:41:16 +08:00
morluto 0ba4d6f43a fix(native): bind dispatch snapshots to the local reader profile
Retain native-only dispatch workflows without requiring a deep provider profile. Validate exact target, operation, and current reader bindings during open, import, recording, and export; preserve selected deep bindings and caller limits.

Validated public CLI and stdio MCP save/reopen, exact CLI replay, changed-limit cache partitioning, baseline failure and candidate success on an Apple-clang fixture, snapshot lifecycle regressions, typecheck and lint. No target or deep engine execution. Fixes #5529.
2026-10-20 23:31:45 +08:00
morluto 080c0e2b2b Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-20 23:15:43 +08:00
morluto 9eec57b469 fix(native): report record-local Objective-C budget omissions
Have method, property, ivar, and adopted-protocol list owners flag real budget omissions on returned class, protocol, and category records. Preserve known empty lists and existing decode reasons.

Validated 59 source tests, two built CLI controls, five static inspections of an Apple-clang fixture, and typecheck/lint. The target was never executed. Fixes #5543.
2026-10-20 23:15:05 +08:00
morluto 8d198d6ec7 fix(javascript): preserve unavailable scope uncertainty in comparisons
Classify wholly unknown or unavailable node observations at the version-item owner and retain their limitations across matched and unmatched comparisons. Preserve positive mixed observations and genuine additions/removals.

Validated source regressions and public CLI/stdout MCP workflows in the 103-test focused gate; typecheck and lint pass. Fixes #5534.
2026-10-20 23:14:47 +08:00
gensokyo-dev c2858d2aa0 perf(go): summarize build identity and query retained metadata (#5524)
Add opt-in Go build summaries and selected retained metadata pages while preserving complete Evidence and source identity.

Validated with 258 focused tests, full static/docs checks, real CLI/SDK workflows and native metadata oracles. CI baseline remediation assertions reproduce on unmodified main; fail-fast cancels two other shards. Owner authorized bypass with those coverage limits recorded in PR #5524.

Fixes #5499.
2026-10-20 23:09:10 +08:00
gensokyo-dev e52a71602d test: stabilize worker cancellation and trailer regressions (#5497) 2026-10-20 23:06:09 +08:00
HawkForge 8443692e2b fix(javascript): keep overflowing timer delays unknown (#3456)
Normalize non-finite timer literals to the existing unknown value at the semantic fact producer. Keep timers, source provenance, binding resolution and unrelated functions; preserve all finite delay values.

Qualify shared CLI/MCP behavior with precise regression oracles, 111 tests, actual source fixtures, real-package summary/fact/Evidence workflows and current-main integration.

Fixes #3400.
2026-10-20 15:02:38 +00:00
morluto 7b2087e449 test(kuna): separate composed doctor startup from cancellation timing
Allow the preceding Ghidra ownership preparation before waiting for the gated Kuna child. Keep the two-second cancellation join, exact reasons, reaping and cleanup assertions unchanged.

Refs #5568. A controlled startup delay reproduces the old failure; disabling cancellation forwarding still fails the retained join assertion. All 86 focused setup, doctor, helper and CLI checks passed on pinned Node 24.18.0/macOS arm64.
2026-10-20 22:57:21 +08:00
morluto f5d1012fab fix(setup): advertise only providers with passing readiness checks
Keep installation availability and full doctor inspection facts separate from the setup ready-provider list. A blocked Kuna cache no longer advertises deep analysis; passing unverified-version notes remain usable.

Refs #5105. All 16 focused setup and public CLI dry-run controls passed; typecheck and lint passed. Tests use a scripted Kuna version fixture and do not establish real-engine behavior. The pre-existing doctor cancellation startup-poll failure is tracked separately.
2026-10-20 22:49:13 +08:00
morluto d2a3269d0c Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-20 22:39:34 +08:00
morluto fd7da77fc0 fix(hopper): verify bookmark names and clear existing labels
Use the public rename API for an explicit empty existing name, retain omitted names and raw listing values, and verify fresh unnamed creation and explicit mutations by readback. Preserve independent verifier restorations and their primary failures.

Refs #5475. Focused bridge regressions and the complete real-Hopper suite passed on macOS arm64 with Hopper 6.6.0-demo 42.6316032. The verifier used a temporary unavailable Ghidra override to meet its sole-candidate prerequisite; reporter Hopper 6.1 remains unverified.
2026-10-20 22:39:23 +08:00
morluto 44521d3d75 refactor(macho): share thin header CPU interpretation
Give partial thin-header facts one domain owner and reuse them for standalone target admission and Mach-O load-command inspection. Preserve each consumer endianness policy and header/command checks; remove the FAT-only parser names.

Refs #5542. All 246 focused checks and six public CLI archive/image controls passed; typecheck and lint passed.
2026-10-20 22:37:25 +08:00
Sagar Kewat eac296a7da fix(browser): reject overflowing scenario timers (#3515)
Reject browser scenario waits and action deadlines beyond the underlying signed 32-bit timer interval in the shared input contract. Preserve maximum legal values and omitted deadlines; prevent unsupported input from opening a browser.

Strengthen the rejection oracle and verify public CLI/MCP canonical validation in both schema profiles, actual Chromium timing/cancellation/cleanup, Evidence export and compatibility with current main.

Fixes #3392.
2026-10-20 14:32:54 +00:00
gensokyo-dev 55cce6fc11 test(cli): retain recovery guidance in filtered failures (#5536)
Preserve typed input-contract recovery and source diagnostics through filtered CLI output in JSON, TOON, YAML and Markdown. Update legacy remediation-text assertions introduced by the concurrent main update.

Refs #5431 and #5470.
2026-10-20 22:26:57 +08:00
morluto 57e76599c0 Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-20 22:21:13 +08:00
morluto 498a667234 fix(javascript): retain source map section paths on declarations
Carry the parsed section path onto retained source nodes and contains edges. Refs #5466; validated with the same 50 focused source-map checks.
2026-10-20 22:19:35 +08:00
morluto 1195929fa5 test(browser): synchronize cancellation before the worker exits 2026-10-20 22:19:18 +08:00
morluto c4007f4542 Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-20 22:19:10 +08:00
morluto a74d859a19 fix(evm): probe the selected limiter before advertising availability
Share asynchronous executable selection between discovery and execution. Recheck it for default Linux x64 sessions, preserve caller-injected service policy and propagate cancellation through pending probes.

Refs #5086. Focused owner, inventory and MCP controls passed; Linux-specific discovery and execution cases were skipped on Darwin arm64 and remain unverified.
2026-10-20 22:18:52 +08:00
morluto 2b2e362a00 fix(javascript): retain partial indexed source map facts
Share section classification across declaration analysis and mapping parsing. Preserve external URLs, malformed section reasons, section paths and safe sibling declarations without fetching nested maps.

Refs #5466. All 50 focused tests passed, including real CLI and stdio MCP regressions; typecheck and lint passed.
2026-10-20 22:18:23 +08:00
morluto 497037e6e3 fix(macho): validate FAT slice format and CPU identity
Use observed thin-header facts before target architecture admission, reject archive payloads, and retain far-offset root inventory through bounded reads. Retry complete bounded FAT table reads.

Refs #5462, #5542. Focused native/filesystem checks passed (245 plus 70 after the table retry). Public MCP inventory parity and unchanged token estimates verified; no external analysis engine execution claimed.
2026-10-20 22:18:03 +08:00
morluto fa36657251 test(ci): deduplicate browser lifecycle fixtures and cover export ordering 2026-10-20 22:05:55 +08:00
morluto d43d3568f2 fix(evm): retain cancellation through final cleanup 2026-10-20 22:05:55 +08:00
morluto 25d3805e7f Merge remote-tracking branch 'origin/main' into codex/audit-continuation-20261020-refresh20 2026-10-20 22:04:00 +08:00
morluto 82902465c4 docs(errors): describe live JSON heap admission
Replace the superseded fixed 64 MiB process-input refusal with the shared reader diagnostic and recovery text. Restore CSV field boundaries in the adjacent import-limit catalogue entry.

Refs #5077. Verification is source consistency and CSV parsing, without a new large-file runtime claim.
2026-10-20 21:59:05 +08:00
Nitin Kushwaha cf5194f68e fix(firmware): separate analysis and publication deadlines (#4602)
Separate extraction/inventory and caller-selectable publication budgets in the shared firmware workflow. Preserve phase, selected timeout, verified progress, caller cancellation identity and committed observations through cleanup. Enforce monotonic expiry even before timer callbacks run.

Validated with 101 targeted tests, full static checks, documentation checks and real OpenWrt CLI/MCP workflows with digest and cleanup verification. Existing main CI failures are documented separately.

Fixes #4176.
2026-10-20 13:57:20 +00:00
JANG BYUNGKUN 52d1a72af0 feat(il2cpp): link native methods and export Ghidra seeds
Link IL2CPP metadata names to native addresses and types through shared CLI/MCP workflows, with bounded queries and atomic Ghidra seed export.

Preserve the original implementation by 8rulerstar and follow-up correctness, resource, provenance, and CI dependency repairs. Verified against real Windows/Android artifacts, independent references, actual Ghidra, and focused CLI/MCP tests.

Fixes #5112.
2026-10-20 21:56:54 +08:00
gensokyo-dev e50a271c72 fix(mcp): guide agents through tool error recovery (#5470)
Add shared, typed input-contract and timeout-state recovery guidance. Normalize SDK input failures within the actual MCP wire budget, preserve full diagnostics and protocol metadata, and retain original Evidence when normalized delivery would exceed the budget.

Fixes #5431.
2026-10-20 21:45:05 +08:00
Syed Rishad c374c2fe72 fix(ghidra): preserve partial dossiers on decompiler failure (#4650)
Preserve listing-backed facts and explicit unavailable decompiler facets when one function fails. Retain Evidence while excluding transient failures and derived workflows from snapshot reuse; keep healthy cache reuse and owned cleanup semantics.

Fixes #4644.
2026-10-20 12:08:08 +00:00
morluto 0c440bfc07 fix(cli): match listener recovery guidance to system failure
Classify listener errno and lifecycle phase at the transport owner. Preserve native cause and unknown codes while distinguishing host lookup, unavailable address, occupied port and permission recovery.

Refs #5455.
2026-10-20 19:54:56 +08:00
morluto a4dbb36d8e fix(javascript): retain uncertainty for missing source map mappings
Share the required mappings field contract and retain readable declarations across malformed indexed leaves while marking graph coverage partial.

Refs #5469.
2026-10-20 19:54:33 +08:00
morluto 0e83d92c58 fix(mcp): advertise existing absolute path constraints
Reuse the schema-visible host path owner across session, firmware, managed, browser, Electron and Evidence-file inputs. Keep existing runtime and CLI path semantics.

Refs #5493.
2026-10-20 19:54:14 +08:00
morluto ee12d517a2 fix(prompts): describe crash document without provider assumptions
Refs #5474. Use the existing provider-neutral document selector wording; public prompt list/render tests passed without starting providers.
2026-10-20 19:39:31 +08:00
morluto 9cf7a7cb0d fix(protobuf): preserve partial facts for malformed web trailers
Parse gRPC-Web trailer blocks with typed failures, enforce field values and lower-case names, and propagate unexpected decoder failures. Retain earlier fields and raw capture bytes across binary and text framing.

Refs #5386. Related control-value fix: #5422.
2026-10-20 19:39:18 +08:00
morluto 00a055be0f chore: merge latest main before publishing audit fixes 2026-10-20 19:29:26 +08:00
morluto 22278b20c0 chore: merge main into audited lifecycle fixes 2026-10-20 19:28:09 +08:00
morluto 3cf6206614 fix(mcp): require absolute evidence bundle paths 2026-10-20 19:26:17 +08:00
morluto 4714c7eaa3 fix(cli): preserve typed failures through output filters 2026-10-20 19:26:08 +08:00
morluto cec8f1e8f3 fix(providers): offer only admitted ambiguity choices 2026-10-20 19:25:59 +08:00
JANG BYUNGKUNandgensokyo-dev 21e0c580e7 feat(il2cpp): read member names, string literals and metadata versions 24 and 27 (#5326)
* feat(il2cpp): read member names, string literals and metadata versions 24 and 27

Adds field, property, event and parameter names with their owners, managed string literals, and the version 24 and 27 header layouts to inspect_il2cpp_metadata, with filtered pages for the new collections. Member decoding yields between row batches like the other row readers.

* fix(il2cpp): bound metadata expansion and query parameter owners

* test(il2cpp): cover nonempty property and event tables

---------

Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
2026-10-20 19:21:42 +08:00
morluto f01dccab77 fix(javascript): retain cancellation after observed worker failure 2026-10-20 19:13:06 +08:00
morluto 5f0bc86d1a docs(ko): describe update alias and bounded output 2026-10-20 19:05:50 +08:00
morluto f69332c94c test(process): bind capture watchdog cleanup to test lifetime 2026-10-20 19:05:44 +08:00
morluto 2e03251b61 fix(zip): retain raw filename provenance for legacy decoding 2026-10-20 19:05:38 +08:00
morluto 108c0e7e49 fix(macho): share width-specific load command alignment 2026-10-20 19:05:31 +08:00
morluto 266dd1d958 fix(go): reuse PE content spans for build metadata search 2026-10-20 19:05:24 +08:00
morluto cac12ae334 fix(workers): retain observed protocol failures across cancellation 2026-10-20 19:05:00 +08:00
morluto 861c11ec77 fix(evidence): preserve execution profiles in composed observations 2026-10-20 19:04:52 +08:00
morluto 9051809343 fix(adb): preserve empty string activity extras 2026-10-20 18:38:13 +08:00
morluto 9db5f1b276 fix(apple): keep empty asset catalog pages complete 2026-10-20 18:38:05 +08:00
morluto 3a9176098d fix(javascript): preserve observed worker failure ordering 2026-10-20 18:38:00 +08:00
morluto 483678bf9f fix(managed): retain operand-free instruction anchors 2026-10-20 18:37:56 +08:00
052956af34 fix(doctor): validate Hopper startup timeout in readiness checks (#3755)
Fixes #3306. Reuse the runtime timeout parser in doctor, preserve scope semantics and separate setting validation from provider configuration.

Co-authored-by: xiajiahang <xiajiahang82@gmail.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-20 10:32:12 +00:00
gensokyo-dev aa314ab682 ci(windows): run environment registration regressions (#5409)
Retain 13 Windows-only environment/setup regressions in the curated native lane. Select Windows qualification for both their three test files and their client configuration, registration and DSH production owner families. Guard membership and actual Git-diff classification; qualify all 60 target cases on hosted Windows.
2026-10-20 10:18:17 +00:00
gensokyo-devandKaoru0822 c23e161629 perf(mcp): record catalog identities for all schema profiles (#5415)
Share compiled schema conversion while recording all four built-in catalog profiles. Preserve canonical hashes, output validation and custom-budget fallback. Refs #723.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-20 10:09:28 +00:00
gensokyo-dev 1417bf943b feat(native): match retained function inventories across builds (#5390)
Match retained native inventories through shared CLI/MCP workflows with conservative symbol/byte correspondence, unresolved structural candidates, complete Evidence provenance and bounded paged reads.

Closes #5343.
2026-10-20 09:48:52 +00:00
ShuaixinHuang e84468c0bb fix(setup): preserve Windows environment override identity (#4946)
* fix(setup): preserve Windows environment override identity

* fix(setup): preserve selected platform and YAML alias metadata

* fix(setup): reconcile layered environment and projected YAML identities
2026-10-20 17:25:51 +08:00
ShuaixinHuang afde435c94 test(setup): use native Windows launcher in layered OpenCode fixture (#4947) 2026-10-20 17:25:38 +08:00
ShuaixinHuang e9fc8fb30c fix(javascript): preserve runtime path bytes and Electron ownership (#4941)
* fix(javascript): preserve literal percent runtime paths

* fix(javascript): ignore resolve prefixes before the final anchor

* fix(electron): retain application roots for loadFile declarations

* fix(electron): resolve loadFile from enclosing application package

* fix(electron): retain outer application root across package scopes

* fix(electron): derive application ownership from inventoried packages

* fix(electron): retain resolved package entrypoint ownership

* fix(electron): preserve competing application ownership

* fix(electron): retain invalid and omitted runtime ownership

* fix(electron): preserve omitted module ownership and runtime paths

* fix(electron): preserve proven roots before confining page paths

* fix(electron): retain possible owners behind missing imports

* fix(electron): distinguish absent imports and owned page candidates

* fix(electron): keep unavailable JSON out of owner gaps

* fix(electron): retain exact loader formats and default entry status

* fix(electron): retain unavailable entrypoint ownership candidates

* test(ghidra): preserve Windows Node probe prerequisites

* test(ghidra): assert cancellation during profile shutdown

* fix(electron): separate examined imports from frontend ownership

* fix(electron): retain unavailable directory entrypoint owners

* test(jeb): retain Linux ownership prerequisite in isolation

* fix(javascript): retain unchecked loader ownership and literal main paths

* fix(javascript): preserve runtime paths and call-site module aliases

* fix(javascript): bound module alias traversal and preserve projections

* fix(javascript): retain host module and nested artifact path boundaries

* fix(javascript): preserve ESM and archive module loader provenance

* test(javascript): distinguish unmapped containers from missing exports

* fix: retain default module aliases and Electron builtin imports

* fix: preserve host file URL and inward ASAR ownership

* fix: preserve CommonJS file URL classification in CI fixtures

* fix: retain bound module loaders and Windows entrypoint uncertainty

* fix: retain ASAR uncertainty and invalidate changed Electron app roots

* fix(javascript): retain ownership uncertainty across loader boundaries

* fix(javascript): preserve loader sources and bound alias queries

* fix(javascript): retain destructured loader sources

* fix(javascript): preserve loader uncertainty at resolution boundaries

* fix(javascript): preserve callable and package launch ownership

* fix(javascript): preserve captured values across member reads

* test(process): assert tagged filesystem cancellation failures

* fix(javascript): preserve inventory bases and invocation read timing

* fix(javascript): preserve ownership across indirect and unread loads

* test(javascript): order fixture directory creation on Windows

* test(javascript): share ordered filesystem fixture writer

* fix(javascript): unify loader provenance and package validation

* fix(javascript): preserve captured Node require loader values

* fix(javascript): preserve loader invocation authority

* fix(javascript): verify generic loader invocation authority

* fix(javascript): preserve conditional loader method alternatives

* fix(javascript): require proven factories for source association

* fix(javascript): honor replaced Electron app path setters

* fix(javascript): prove path and assignment source ownership

* fix(javascript): retain native delegate eligibility through shared writes

* fix(process): settle stale baseline errors after confirmed absence

* fix(javascript): preserve assignment and path boundary evidence

* fix(javascript): prove source-directory resolve anchors

* fix: preserve application path provenance and portable schemas

* fix(javascript): retain CommonJS exported setter effects

* fix: isolate Linux identity observations and retain native module exports

* fix(javascript): preserve published app and helper provenance

* fix(javascript): normalize typed stores and native path fixtures
2026-10-20 17:25:19 +08:00
morluto c284168c4b fix(objdump): scope debug-link limitations to DWARF requests 2026-10-20 17:18:21 +08:00
morluto be20ac3740 fix(source-maps): preserve failure priority and cancellation provenance 2026-10-20 17:18:20 +08:00
morluto cc73587ec4 fix(lldb): preserve observed failures through interrupted cleanup 2026-10-20 17:18:20 +08:00
morluto 98edca9f96 fix(pwndbg): clarify debugger context output limit message 2026-10-20 17:18:19 +08:00
morluto 98a5e56380 docs(ghidra): explain server-wide analyzer override scope 2026-10-20 17:18:19 +08:00
morluto 7c6142efdc fix(ghidra): retain stable Homebrew installation aliases 2026-10-20 17:18:18 +08:00
morluto 562dab00c5 fix(mcp): retain protocol envelopes when replacing oversized errors 2026-10-20 17:18:18 +08:00
morluto 3b02179560 fix(javascript): preserve uncertain call targets across activation boundaries 2026-10-20 17:18:18 +08:00
morluto 599fdac029 fix(browser): stop late navigation before releasing attached sessions 2026-10-20 17:18:17 +08:00
morluto 696832caa3 fix(gdb): gate readiness and retain caller cancellation through cleanup 2026-10-20 17:17:16 +08:00
morluto 459a356edb fix(evm): preserve cancellation and exact cleanup ownership 2026-10-20 17:17:16 +08:00
morluto 419502c8d0 fix(pcap): preserve cancellation and endpoint evidence through cleanup 2026-10-20 17:17:15 +08:00
morluto 1006714271 fix(sqlite): retain primary outcomes through cleanup retries 2026-10-20 17:17:15 +08:00
morluto e367750b1b fix(process): preserve observed command failures and native ownership 2026-10-20 17:17:14 +08:00
morluto cf3288d8cf fix(native): preserve Mach-O container framing across inspection 2026-10-20 17:16:44 +08:00
Liu Jieandgensokyo-dev d532b18123 fix(doctor): propagate Kuna cancellation and preserve partial observations (#5241)
Fixes #5106. Propagate the owned inspection signal, preserve typed cancellation and earlier failures, and retain completed installation observations through exact-owner cleanup retries.

Co-authored-by: Liu Jie <maxazure@gmail.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-20 09:15:09 +00:00
吴佳浩AlbenandXiaoBinGan 074768901f fix(pwndbg): separate the words in the debugger-context limit message (#5372)
The 64 MiB reply-budget refusal rendered as "exceeds64 MiB" because the
message word and the limit were joined. The pwntools sibling names the
same budget as "exceeds the 64 MiB reply budget"; use that wording.

The output-limit path had no producer regression, so the pwndbg suite
gains one that drives the real 64 MiB boundary, and the suite is now part
of test:python instead of running only when invoked by hand.

Co-authored-by: XiaoBinGan <XiaoBinGan@users.noreply.github.com>
2026-10-20 16:12:55 +08:00
gensokyo-devandKaoru0822 2538214e2c feat(analysis-view): add native inventory summaries and pages (#5378)
Add opt-in summaries and stable selected-field pages for native inventories through the shared CLI/MCP Evidence layer. Preserve complete source access, row identity, provenance, string qualifications and unknown discovery coverage.

Record real true/jq workflows and portable old-Evidence checks, including tokenizer proxy reductions, additional call/schema costs and observed latency/memory regressions.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-20 07:59:43 +00:00
gensokyo-dev b5d540f3a2 test(capture): split protobuf MCP acceptance scenarios (#5379)
Separate independent exclusion, partial-source, credential-preflight and descriptor-failure workflows so their costs do not accumulate under one test deadline. Reuse one worker-owned MCP connection with explicit awaited teardown, preserving sensitivity isolation and retained-Evidence checks.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
2026-10-20 07:54:47 +00:00
gensokyo-devandakushonkamen 4eaf3a117b fix(mcp): retain protocol framing for oversized tool errors (#5371)
Preserve the SDK resultType when bounded error recovery replaces an oversized response. Verify both revisions through the public serving entry, retained Evidence and same-connection recovery.

Refs #5273

Co-authored-by: akushonkamen <akushonkamen@163.com>
2026-10-20 07:31:02 +00:00
0134732fcd feat(capture): decode selected protobuf and gRPC bodies (#5031)
Retain exact bounded wire facts and optional supplied-schema interpretations for selected historical captures. Share CLI/MCP views and preserve Evidence, partial coverage, credential exclusions and source provenance.

Fixes #4986

Co-authored-by: AayushJB03 <aayushjb14@gmail.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 07:10:54 +00:00
gensokyo-dev 799e8265b2 fix(verification): retain Hopper ownership evidence across owner exit (#5357)
Keep one ProcessOwnershipEvidenceOwner for each graceful/SIGKILL session and share it across active and terminal scoped scans. Require live token-verified evidence before stopping the owner, and retain structured cleanup failure diagnostics.

The real Ubuntu 24.04 Hopper clean-setup/CLI/MCP job passes, including owner exit, target reacquisition, idempotence and zero remaining descendants. Local verification passes 87 CI guards, 51 ownership controls, discovery of all 1,714 test files and full static checks.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
2026-10-20 05:52:06 +00:00
gensokyo-dev 4668cea246 fix(ghidra): explain server restart for timeout recovery (#5356)
Explain process-scoped startup settings in shared CLI/MCP timeout guidance and the bundled skill. Preserve Evidence and cleanup before restarting REA, reconnect MCP, and allow enough client request time.

Validated with focused tests, static/docs/package checks, real Ghidra CLI/MCP recovery, and a completed 591-second EXE analysis under CPU and memory limits.
2026-10-20 05:49:00 +00:00
gensokyo-devandKaoru0822 58d6043303 perf(ghidra): omit redundant raw results (#5355)
Keep ordinary Ghidra facts in normalized Evidence without repeating complete raw replies. Preserve distinct overview, attestation, file-offset and pre-overlay observations through shared CLI/MCP execution.

Record real application measurements, equivalent selected facts, response admission and explicit latency/coverage limits.

Fixes #5337.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-20 05:14:33 +00:00
gensokyo-dev d148ce0905 perf(environment): index observed-state write cutoffs (#5350)
Index parsed recorded-write roots once per state projection and reuse positive and negative type cutoffs. Preserve wildcard, ancestor/descendant, canonical timeline and Evidence semantics under the existing representation budget.

Follow-up to the final performance thread on #5319, which was merged while this optimization was being validated.

Validated with 508 relevant source tests, compiled state CLI/MCP cases, real Gitea HAR CRUD/search captures and Chromium captures, static/build/docs/catalog gates, and equivalent completed before/after projections.
2026-10-20 12:16:02 +08:00
3fca2e0ca6 feat(environment): extract the initial state a capture's reads observed (#5319)
* feat(environment): extract the initial state a capture's reads observed

Add the environment-state analysis view. From the parents the environment
manifest accepts, it extracts the data the capture's reads observed before
the first related write: entity types with an identity field (proved by a
path parameter or inferred from an identity name), entities with their
recorded values and provenance, documents for written non-entity paths, and
a render plan per read tool that is kept only when it reproduces the tool's
latest initial recordings from the state; every other read tool is a
recorded view with the reason. The Evidence is always inferred.

Response-body decoding moves to a domain owner shared with replay, exact
JSON parsing moves to the owner of the exact-number policy, the manifest and
state views share parent admission and record grouping, and
projectAnalysisView takes its accumulators as one object.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): bound state at redacted writes; infer identity only from items

A scenario write whose URL was redacted has no request line, so it was
dropped and reads after it counted as initial state. Such a successful
write now joins the timeline with an empty path, whose root relates to
every type, so it ends every type's state; a limitation counts them.

A list whose recordings were all empty passed the "every listed item
carries it" check vacuously and published an identity field nothing
showed; it now needs at least one item, else the view stays recorded
as no-identity.

A value that differed between two request lines of one item tool, such
as a query variant, was called volatile, and the gate then substituted
each recording's own value; only repeats of one request line now show
volatility, so differing lines go through fields-differ.

List membership is compared only while a list can still be the whole
collection, and merged entities are indexed by type and collection once,
so paged captures no longer cost pages times entities (8,000 pages of
40,000 entities: 5.7 s to 0.23 s).

Docs and the tool contract say scenario state keeps the capture's
redaction markers and how redacted writes bound it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep first sightings, one list pointer and linear field unions

Entities took the order of the first plan observed, and item plans run
before list plans, so a complete list read before its detail reads came
out reordered and lost "all" membership; each entity now keeps its
earliest recorded sighting.

A list plan reused the first recording's pointer for later recordings,
so a later response that was itself an entity wrapping a list was read
as that list; every recording must now locate the same list.

The field union scanned its ordered list for every key, quadratic in an
object's width; a set now answers membership.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep post-write values and partial lists out of the initial state

A value that changed between repeats of one request line was named
volatile whenever no write under the type's own root lay between, so a
write under another root (for example POST /api/dashboards/db before a
second GET /api/search) left its effect in the initial state. Any
recorded write between the two observations now leaves every tool of the
type recorded with reason fields-differ instead.

A list was published with membership "all" even when a total or count
envelope member exceeded the number it listed. Such a counter now makes
the membership "recorded".

Also drop a stale doc comment on ObservedEntity.order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(environment): scope item-shaped and deleted written paths out of documents

State documents are held only for list-shaped paths a POST, PUT or PATCH
tool writes. Reads of item-shaped written paths and of paths that are only
deleted stay recorded views; the guide now says so and the spec defers them
to a later increment of #4933.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): count writes in flight when a value changes between reads

The volatility check compared write start positions with the two reads,
so a write already in flight when the earlier read started was missed and
its effect was named volatile. A write now counts when its interval
overlaps the span from the earlier read's start to the later read's end.

The check also ran once per changed field and scanned every write. It now
runs once per pair of observations, answered by a binary search over the
writes in timeline order and the latest end among each prefix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): catch cross-tool changes across writes; read only item totals

A value that changed across a write was caught only between repeats of
one tool's request line, so a list read before a write and an item read
after it put the post-write value into the initial state. Changes are
now classified per entity in timeline order after observation: across
any recorded write, a change between repeats of a line or between two
lines of the type rewrites the type (every tool recorded as
fields-differ); with no write between, a repeat's change is volatile.
The classification lives in environmentStateMerge.ts.

Any numeric member whose name contained "total" or "count" counted as
an item total, so total_pages, account_id or page_count made complete
lists partial. Item totals are now members whose name tokens include
total or count and none of page, pages or per; a string of digits counts
as a number; and a set has_more, next or next-page token member also
marks the list partial.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(environment): keep post-write observations out of initial state

* fix(environment): retain field provenance and bound state inference work

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
2026-10-19 20:33:46 -07:00
gensokyo-devandKaoru0822 4e716b0607 perf(analysis-view): reuse validated immutable captures (#5349)
Reuse the format owner's full validation for exact authenticated immutable captures across retained queries. Preserve ordinary mutable-input validation and per-request subject, coverage and budget checks.

Refs #3133.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-20 03:32:18 +00:00
gensokyo-dev d72021b0da fix(hopper): verify publisher before probing private display (#5346)
Return publisher refusal before unrelated private-display prerequisites can mask it. Retain display validation for admitted launchers, native launcher digest revalidation and owned cleanup.

Add a public CLI fault control using an unusable Python home, preserve the ordinary control and assert display selection for admitted versus refused launchers. Affected tests: 177 passes; 13 changed-file cases passed three additional repeats; full static checks pass.

Real-Hopper owner-exit identity revalidation fails identically on unchanged main and the PR; complete real-provider qualification is not passing. This pre-existing failure remains outside this focused correction.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-20 02:41:14 +00:00
f93a0335a8 feat(analysis-view): project rich captures from Evidence files and template path pairs (#5293)
Project large local Evidence captures through the authenticated file-source boundary and add guarded opt-in sibling-pair path inference. Preserve request cancellation, resource ownership and file-relative validation diagnostics.

Validated relevant source and compiled CLI/MCP/environment boundaries, static/build/docs/catalog gates, and a real isolated Gitea 28.2.0 capture through CLI, default stdio MCP and HTTP replay. Current-head automated review passed; unrelated long-running platform jobs may still be pending.

Co-authored-by: Edgar Arakelyan <edgar.arakelyan@scale.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
2026-10-20 10:33:52 +08:00
5fa4defcbc feat(artifacts): inspect and extract Godot PCK with retained facts (#3634)
* feat(artifacts): read Godot PCK packs

Add a Godot Engine PCK artifact reader for standalone packs and packs
embedded behind an executable trailer (formats 2 and 3). Members are
uncompressed byte ranges verified against their declared MD5 on read.

Encrypted directories, sparse bundles, patch removal entries, unknown
flags and format 1 fail closed as unavailable; encrypted members are
reported without being read. inspect-artifact and extract-artifact
recognize standalone packs by their GDPC magic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(artifacts): bound Godot PCK metadata and own member streams

Cap member paths at 4096 bytes and the retained directory at 64 MiB
before allocation. Read members with positional chunk reads through
pipeline so cancellation is typed, abandoned consumers release their
source, and the shared descriptor stays reader-owned. Retain the root
descriptor for godot-pck inventory, as for ZIP and universal Mach-O.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(artifacts): complete Godot PCK facts, integrity and selected views

* fix(artifacts): preserve atomic-root inventory Evidence

* fix(artifacts): bound aggregate PCK member expansion

---------

Co-authored-by: Samucahub <151155051+Samucahub@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-20 09:53:53 +08:00
JANG BYUNGKUNandgensokyo-dev 833136507d feat(il2cpp): inventory Unity IL2CPP global-metadata images, types and methods (#3807)
* feat(il2cpp): inventory IL2CPP global-metadata images, types and methods

Add inspect_il2cpp_metadata (CLI inspect-il2cpp-metadata), a read-only
in-process decoder for unencrypted Unity global-metadata.dat version 39.
It reports header sections, serialized index widths, images, type
definitions (nesting from the nestedTypes section) and method names.

Unrecognized magic and other versions are unsupported; damaged headers,
overlapping sections, inconsistent record sizes, out-of-range indices and
invalid strings fail with a reason code and no partial success. MCP
detail summary retains the complete Evidence and pages rows through
inspect_analysis_view kind il2cpp-metadata.

Adds an opt-in verify:il2cpp:metadata -- --metadata PATH check.

* feat(il2cpp): deliver metadata summaries by default over MCP

A 112,232-method file produced a 10.5 MB complete response, above the
10 MiB stdio budget. Default MCP delivery is now the retained summary;
detail complete stays available, and the one-shot CLI requests it.

* fix(il2cpp): reject shifted strings, nesting cycles and method owner drift

Review fuzzing showed that moving the strings section offset by one byte
silently renamed every image, type and method. Name indices must now start
a string, which also bounds total decoding by the section size.

Nesting cycles and methods whose declaring type disagrees with the owning
type range are rejected instead of returned. Adds service, shutdown and
index-width coverage, and moves environment-specific measurements out of
the public guide and tool description.

* feat(il2cpp): decode global-metadata versions 29 and 31

Unity 2022.3 writes version 29 or 31 metadata: a 256-byte header of
(offset, size) pairs, fixed 4-byte indices, type records with
elementTypeIndex, and method records that gained returnParameterToken in
version 31. Record counts come from section sizes and must be whole.

Sections report a null count for these versions and index widths report
fixed-width-version. Image, type and method rows keep the same shape, and
the string, nesting and method-ownership checks apply to every version.

* fix(il2cpp): bound report size before serializing and tighten coverage

Rows share decoded names, so a 130 KB file could expand into gigabytes of
JSON before the 64 MiB budget check, ending in an internal RangeError. The
provider now refuses from a lower bound on the serialized rows first.

The decoder also rejects non-empty sections inside the header, methods
outside their declaring type's range and overlapping image type ranges, and
keeps a leading byte order mark in names. Layouts now carry one indexing
mode instead of two coupled flags, and the tool description explains
nested_type_start.

* fix(il2cpp): refuse oversized metadata before decoding rows

Address review findings on the IL2CPP metadata inventory:

- check a lower bound from header row counts before any row object is
  allocated, so a large rejected file no longer builds every row first;
- validate sealed parent Evidence and count its rows once per report
  instead of on every inspect_analysis_view page;
- decode version 39 fixtures with 2- and 4-byte type-definition,
  generic-container and parameter indices.

* docs(il2cpp): attach the decoder comment to readIl2cppMetadata

* fix(il2cpp): deliver complete rows by default like the other inspection tools

inspect_il2cpp_metadata defaulted to detail summary, the only inspection
tool to do so. Omitted detail now returns every row inline, as
inspect_artifact, decode_interface_builder and the capture tools do;
summary stays one argument away and the guide, CLI reference and skill
reference say to select it first for large games, whose complete MCP
delivery is refused at the stdio budget with retained Evidence.

* test(il2cpp): cover narrow-width -1 sentinels and fix the skill's default

An empty image stores its type start as the all-ones value of a one- or
two-byte index; the decoder reads it as -1, but no fixture exercised it,
so removing either conversion passed the suite. The fixture can now append
an empty image, and both widths decode it. The skill still described a
summary default; it now says to select summary first, as the guide does.

* docs(il2cpp): request summary explicitly in the summary example

* chore(il2cpp): hash the verifier metadata through owned file resources

* fix(il2cpp): count escaped name length without building the escaped string

* fix(il2cpp): keep the verifier's check failure and small-table last page

* feat(domain): count JSON string length without building the escaped string

* fix(il2cpp): keep descriptor cleanup owners and share the JSON length count

* test(domain): give the backslash case real backslashes

* fix(il2cpp): select the CLI path and finish the command like the other tools

Follow main's absoluteCallerPath (#4067) and pass the command signal to finishAnalysisCommand.

* fix(il2cpp): select the verifier input path like the CLI

Use absoluteCallerPath (#4067) so a path with a symlink followed by .. names the same file the CLI and MCP inspect.

* feat(il2cpp): add compact composable metadata queries

Retain source-indexed Evidence for filtered batch and field queries. Bound representation growth before serialization, yield decoding for cancellation, and share CLI Evidence publication with desktop inspection. Verify public Unity metadata against independent byte and managed-DLL oracles and exercise actual stdio SDK workflows.

* fix(il2cpp): retain the validated metadata header magic

* test(il2cpp): remove obsolete execution wording exception

* fix(artifacts): preserve export selection and completed source facts

---------

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-20 07:20:47 +08:00
gensokyo-dev 82c76e2cba fix(ci): validate unindexed readiness heads with live PR metadata (#5316) 2026-10-20 07:19:58 +08:00
bf1eeee94f feat(environment): build environments from browser scenario captures (#5182)
Build an agent environment directly from retained capture_browser_scenario Evidence through the existing manifest, serve and export commands. Preserve request ordinals, source pointers, redaction markers, unavailable bodies, provenance and the default stdio MCP transport.

Followups admit copied/transformed text before body validation or decoding, avoid request-text allocation in replay, normalize portable file inventories, select dependent CI lanes, retain the author's redaction/body-budget corrections, and count body coverage over represented requests.

Validation: full pinned-toolchain static gate, source and public CLI/MCP regressions, canonical catalog checks, actual Chromium interactive and live GitHub API captures with exact HTTP replay and stdio parity, the generated non-root Docker image, and its smoke task through real agent-env 0.9.1334. Verification scopes, resource measurements and platform limits are recorded in the PR and feature verification document.

Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 06:07:15 +08:00
7a0c47bfa4 feat(environment): export an environment manifest as an agent environment bundle (#4999)
Export an authenticated capture and environment manifest as a pinned agentenv bundle with provenance, a replay verifier and smoke task.

Followups preserve immutable input ownership, bounded discovery, caller paths and numeric values; bind bundle writes and package copying to retained filesystem owners; verify POSIX modes; retain cleanup authority; and verify framework/npm executable selection. Default MCP remains stdio.

Validation: pinned Linux toolchain, typecheck/build/lint/format/docs/knip, 452 focused tests, ten product-catalog cases, real GitHub response replay in the generated non-root Docker image, and the real pinned agentenv framework smoke workflow. Platform and resource-measurement limits are recorded in the feature verification document.

Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-20 05:29:43 +08:00
gensokyo-dev b4938aed58 feat(artifacts): triage desktop installation directories (#5207)
* feat(artifacts): triage desktop installation directories

* fix(artifacts): retain completed probes through failed file cleanup

* perf(artifacts): decode only assembly reference names for desktop triage

* fix(artifacts): enforce exact signatures and responsive directory probes

* fix(artifacts): recognize Unity bundles and bound FORM chunks

* fix(artifacts): retain bounded desktop omission evidence

* fix(artifacts): select ASAR targets before inventory probes

* chore: preserve tested upstream HTTP owner during integration

* fix(artifacts): reuse Mach-O signatures for FAT64 desktop probes

* fix(artifacts): expose bounded desktop probe diagnostics

* fix(artifacts): derive desktop snapshots from observed source identities

* fix(artifacts): admit desktop facts before JSON expansion
2026-10-20 04:01:36 +08:00
gensokyo-dev 71ae02c6ef fix(process): retain child scope and bound native exit waits (#5280)
Retain original parent/child scope and prior native-generation proof across exit settlement and token retries. Keep historical scope separate from signal authority, count each supplied snapshot once, and share one existing native-exit deadline throughout cleanup.

Validated 387 affected tests (one Darwin-only skip), five controls repeated three times, and 30 synced-main integration tests (one platform skip). Synced-head static, architecture, docs and discovery checks pass; real GDB qualification passes 44 CLI/MCP cases. Native-observer edge controls are simulated.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-19 19:27:43 +00:00
10f1994fe1 feat(environment): serve an environment manifest as a replay environment (#4975)
Serve retained capture Evidence as a bounded MCP replay environment with discovery.
Preserve default stdio, caller-selected facts and complete source Evidence.

Fix numeric fidelity, argument identity, startup cancellation and bounded discovery,
query/path matching and output metadata. Verify real recorded API data and public
CLI/MCP workflows; preserve explicit gaps for Windows and third-party hosts.

Co-authored-by: Edgar Arakelyan <edgar.arakelyan@scale.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 03:06:29 +08:00
gensokyo-devandKaoru0822 909b9f7b6b fix(rizin): keep protocol failures outside exit recovery (#5290)
Separate debugger exit-policy readback from process descriptor checks. Require the final native readback before considering inferior-end proof, and regress an ambiguous reply delivered as the real owned inferior exits. Preserve debugger ownership on failure.

Fixes #5282

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-20 02:56:41 +08:00
gensokyo-devandKaoru0822 e84e17e30f fix(rizin): accept proven inferior exit after detach (#5281)
Reuse the common Linux identity reader and retain the original PID/start-time pair throughout detach. After Rizin confirms no active descriptor, accept a proven end of that original process while preserving refusals for unresolved or live mismatched targets. Remove the duplicate proc parser and cover deterministic exit/live-redirect transitions with owned fixtures.

Fixes #5277

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-20 02:29:04 +08:00
gensokyo-dev 1c2c2f1e78 fix(process): settle native exit and repair ownership verification (#5249)
* fix(process): classify baseline cleanup with current ownership facts

Use the pre-launch baseline only to select candidates for current native
identity/token validation. Preserve confirmed absence and verified foreign
generations instead of carrying a premature baseline identity failure.

Exercise the real Linux enumeration/exit race and retain countercontrols for
unknown identities and live token-owned processes.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)

* fix(ci): distinguish process inventory from historical PID lookups

* test(ci): verify decoded historical PID controls before tracing

* fix(ci): trace historical PID handles and signal probes

* fix(ci): resolve traced directory paths across pathname syscalls

Classify producer-decoded FD/path pairs once instead of limiting failed relative
lookup detection to openat on /proc. This preserves attempted readlinkat, statx
and newfstatat accesses with no returned descriptor.

Three regression cases fail against the previous policy and all 33 controls
pass with the shared pathname interpretation.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)

* test(ci): declare unresolved legacy pathname coverage

Report the historical-PID access surfaces actually checked and explicitly mark
legacy cwd-relative pathname calls unverified. The existing tracer does not
provide their cwd identity, and a blanket rejection also rejects legitimate
GDB build-ID metadata queries.

Retain every committed access guard and document the preexisting limit without
claiming absence from missing path evidence. The complete real 44-case CLI/MCP
recorded-crash qualification passes with the coverage declaration.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)

* fix(ci): reject priority access to historical PIDs

* fix(ci): preserve C-quoted components in traced path checks

strace renders non-ASCII pathname bytes as C octal escapes, not JSON strings.
Keep those components opaque when resolving literal ASCII path separators and
proc PID selectors, matching the existing absolute-path interpretation.

Two controls fail before the correction and all 35 pass afterward. An actual
strace observation independently reproduces the rejection of an unrelated
Chinese filename and verifies the corrected classification.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)

* fix(ci): reject historical PID resource and scheduler calls

* fix(schema): preserve portable large base64 validation

* fix(ci): share explicit PID syscall contracts with tracing

Derive tracer selection and reported coverage from the same named target
contracts used by the access checker. Cover resource limits, scheduler calls,
process metadata, PID groups, capabilities and pidfd operations without mixing
UIDs, policy enums, self selectors or output values with target PIDs.

Interpret each target once and retain unresolved target facts as a distinct
failure. Emit the coverage catalog once per verifier result.

The previous oracle misses 28 new controls. All 83 controls pass after the
change; real native resource/scheduler probes capture 14 previously missed
calls with resource limits and affinity unchanged. All 35 selected syscall
names are accepted by the pinned local strace.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)

* fix(ci): classify I/O priority and qualify PID trace coverage

* fix(process): keep ownership retries on the native clock

* fix(ci): retain process edges in ownership trace inventory

Keep fork/vfork and resumed edges along with clone events so the shared attribution owner receives the complete process relation facts it consumes.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)

* fix(process): type native exit predicates and ownership fixtures precisely

* fix(ci): retain trace coverage limits after integration

Restore explicit unverified symlink aliases and same-Node stat/status purpose in the shared coverage contract and guide. The native-exit and trace-attribution integration does not establish those properties. Preserve both limitations rather than silently broadening the reported qualification.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
2026-10-20 02:01:00 +08:00
NoThingandKaoru0822 1b3ac94242 fix(rizin): bound recent history frames by UTF-8 byte budget (#5246)
Bound recent decoded history to complete UTF-8 prefixes and reuse the bounded capture implementation without changing command Evidence or wire queue accounting. Add deterministic Unicode and invalid-byte coverage, and document history retention.

Fixes #5091
Fixes #5242

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-20 01:41:46 +08:00
morluto b44cb5bd30 test(javascript): distinguish selected paths from artifact identity
Check CLI parity against the admitted absolute selection and verify that MCP retains relative selections separately. Equal canonical artifact results do not imply equal Evidence IDs when caller-selected paths differ.
2026-10-20 01:17:45 +08:00
gensokyo-devandKaoru0822 2dd5effe2a fix(rizin): default one-shot output to plain presentation (#5269)
Default native one-shot Rizin presentation to plain text before collection while preserving caller colour overrides, literal output, recorded argv and shared CLI/MCP Evidence.

Fixes #4488

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-20 01:12:35 +08:00
morluto 0e62094b69 test(setup): isolate registration checks from installed providers
Select absent Hopper, Ghidra and Java locations consistently across registration environment acceptance fixtures. Host PATH Java was executing during IDA budget checks and exposing those checks to unrelated provider cleanup failures. Keep the process ownership failure policy and all registration assertions intact.
2026-10-20 00:53:52 +08:00
morlutoandgensokyo-dev 5199c672ff fix(process): keep lifecycle waits independent of application timers
Use Node promise timers consistently for ownership retries, final verification and capture-journal quiet settlement. Preserve the existing elapsed-time budgets, ownership checks, cancellation and trailing-callback drain.

Adapt the ownership timer correction from gensokyo-dev's PR #5249 and complete the same fix in the adjacent capture-journal owner. Three new controlled regressions fail before the fix; 93 source tests and 94 CLI/MCP/process boundary tests pass afterward, with static checks passing. Global performance replacement and ordinary native Jadx incidence remain unverified.

Fixes #5267

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-20 00:45:49 +08:00
c4aaf813e0 fix(javascript): retain selected application paths in Evidence
Record the admitted selected path separately from canonical artifact identity in successful and partial Evidence. Anchor relative inputs consistently across both CLI routes using the existing caller-path owner.

Adapt shared client verifier assertions and boundary coverage from PR #5261, and the dedicated-route anchoring correction proposed in PR #5265. Historical parsing remains independent of live paths, including legacy records without the parameter.

Validation: 118 focused tests in eight files, static and docs checks, discovery, and installed Gemini CLI 0.29.5 loopback verification of 207 schemas/241 examples passed. Synthetic static-analysis fixtures; no live Google API or native target execution.

Fixes #5258

Co-authored-by: kwakhyun <khyun2348@naver.com>
Co-authored-by: vishal-tambi <tambivishal3@gmail.com>
2026-10-20 00:37:45 +08:00
morluto aacf740a04 fix(ci): correlate ownership trace threads and preserve setup failures
Follow CLONE_THREAD edges across strace -ff files when excluding the ownership process's stat/status reads. Keep provider child processes outside the allowance and document the same-process attribution limit.

Validate setup result array shapes and preserve the original failed-plan JSON instead of masking it with a diagnostic TypeError.
2026-10-20 00:05:22 +08:00
morluto 0949313d8f fix(schema): compose portable stack-safe base64 constraints
Replace the lookahead-based pattern with separate allOf/not JSON Schema rules for quartet length, alphabet, padding and canonical pad bits. Share the runtime predicates with HAR and padded base64 parsing.

Validate converted advertised leaves with the MCP SDK validator, preserve permissive versus canonical semantics, and exercise every pattern near the 32 MiB encoded-input budget in all JavaScript modes.
2026-10-20 00:05:22 +08:00
morluto 4af71a45f9 fix(process): reconcile native lifetime and selective Linux UID facts
Settle absent and zombie candidates before retaining baseline or token-read failures. Preserve fail-closed behavior for live and unknown generations, and stop retrying exited candidates.

Bind Linux effective UID to stat-bracketed status reads only for unreadable-token candidates, preserving partial identity facts and avoiding full-table UID enrichment.
2026-10-20 00:05:22 +08:00
Edgar Arakelyanandgensokyo-dev 60bd646478 feat(mcp): add opt-in streamable HTTP transport (#4955)
Add an explicit Streamable HTTP entry for environment/gateway hosts while keeping stdio registrations and default behavior. Preserve the shared provider/session owner across DELETE and replacement; fence and drain tool/completion work before handover or teardown.

Bound HTTP input and plain-response admission, cancel refused bodies, join whole exchanges and asynchronous response cleanup before provider hooks, gate startup readiness, and reject queued HTTP/1.1 pipelining while retaining sequential keep-alive.

Validation: 8 static/build tasks, 83 adapter tests and registry metadata pass. A real installed gh binary produces seven equivalent CLI/stdio/HTTP reports with DELETE/replacement and clean signal shutdown. Broader local native-provider/ownership failures reproduce on clean main and are documented with limitations in the PR.

Co-authored-by: Edgar Arakelyan <edgar.arakelyan@scale.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-19 23:58:51 +08:00
morluto 255d906e15 fix(native): scan byte-pattern inputs without regexp stack growth
Keep exact wildcard, whitespace and aligned-mask validation in the shared
domain refinement. Advertise descriptive string inputs instead of repeating
regexes, and remove discarded byte/mask array materialization.

Preserve caller spelling and error precedence; cover large public stdio
queries, provider-boundary parsing and connection recovery.

Fixes #5257
2026-10-19 22:09:42 +08:00
morluto 49b4edfe77 fix(browser): validate large base64 without regexp stack overflow
Share padded decoding across CDP response shapes and cache fingerprints,
and count binary WebSocket bytes without allocating a decoded buffer.
Preserve HAR canonical pad bits and validate before allocation.

Replace repeated alphabet quartets in canonical schemas with separate
alphabet, padding and fixed-width length assertions. Cover near-32MiB
encodings under ordinary, Unicode and Unicode-set modes, plus complete
4MiB CLI and MCP retained-evidence export workflows.

Fixes #5253
2026-10-19 21:46:23 +08:00
gensokyo-devandKaoru0822 3ea0d9489e feat(objdump): select native disassembly by symbol (#5171)
Push optional native symbol selection into GNU objdump before collecting Evidence. Preserve native matching, raw output, artifact identity, scoped limitations and the existing full-disassembly default through the shared CLI/MCP workflow.

Fixes #5159

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-19 20:15:20 +08:00
morluto dc936f433c test(process): distinguish native preparation from capture allocation
A missing temporary path stops Darwin native-inspector preparation before
capture allocation can account for resources. Keep its progress coverage
unknown; Linux reaches the capture root allocation and reports not-required
resources. Assert the public typed failure preserves the selected temp path.

The combined Electron/progress focused rerun passed 33 tests on macOS arm64
with Node 24.18.0. The seven progress cases passed; native Linux was not run.
Static checks, docs checks and test discovery also passed on the final tree.
2026-10-19 20:04:00 +08:00
morluto 49e67aa1d9 fix(process): retain native ownership evidence through cleanup
Keep a run-scoped evidence owner from acquisition through settlement and
cleanup retry. Bind token observations to native generations and retain
related generations and unresolved identity lookups across table omissions,
reparenting and process-group changes without treating PID hints as authority.

Use native effective UID facts for withholding decisions, corroborate Linux
procfs absence, and share the Linux stat parser with sampling and debugger
identity checks. Signal only after current token and group revalidation.
Complete swept cleanup across all groups with one bounded final family check;
retain unresolved owners and successful-peer completion across retries.

Validation: npm run check, docs:check and test discovery passed. Focused
ownership/consumer coverage totals 513 passed and 1 skipped across 35 files,
including the corrected Electron cancellation test rerun independently. Darwin helper compilation, real
owned Node child cleanup, CLI/MCP capture and retained cleanup retries ran.
Real Electron applications, native Linux races/PID reuse and Windows cleanup
were not qualified. The original Linux reports remain open for that work.

Fixes #5238
Refs #4322, #5206
2026-10-19 20:04:00 +08:00
gensokyo-dev 0fc8462be1 fix(tests): complete independent agent evaluation cleanup
Attempt independent auth and run-tree cleanup even after permission denial,
retaining the primary verification failure alongside cleanup errors. Exercise
both retention modes through the verifier entrypoint, preserve startup
diagnostics, and retain cooperative coverage for root.

Fixes #5095

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
2026-10-19 11:54:04 +00:00
gensokyo-dev b999e72476 fix(ci): repair capture ownership and portable ABI validation (#5224)
* fix(tests): restore reliable snapshot and container CI checks

Keep exact cancellation causes and partial snapshot facts in regression oracles. Match fault injection to real directory handles and isolated MCP module ownership; await terminal cleanup progress within the existing test deadline. Reuse the valid ASAR Pickle fixture and preserve truncated-container rejection.

* fix(tests): isolate runtime faults and own CLI subprocesses

Keep the runtime provider mock in the isolated project after reused CLI graphs exposed lost fault injection. Use the existing owned CLI fixture for Inspector parity and update command checks, retain caller environment choices, and require the removed alias to fail with COMMAND_NOT_FOUND. Keep current test deadlines and production behavior.

* fix(process): retain executable handles through read cancellation

Use the existing borrowed descriptor reader so stream cancellation cannot invalidate a handle owned by capture. Preserve the exact cancellation and permit immediate scope reuse after cleanup. Reproduce the native-stream failure with actual file IO and retain completed/failed-close controls.

Synchronize runtime cancellation and backwards-clock injection with observed running progress. The corrected clock oracle now rejects a Date.now-based deadline under controlled rollback; keep test deadlines and narrow host cleanup checks unchanged.

* test(process): observe prelaunch cancellation at descriptor reads

* fix(process): retain read failures alongside observed cancellation

* fix(flutter): advertise portable Unicode ABI selectors
2026-10-19 19:32:22 +08:00
morluto a0edd145d3 fix(analysis): preserve input diagnostics and reuse JEB contracts 2026-10-19 18:45:48 +08:00
morlutoandYi-111-a 64abd4aefb fix(flutter): select reported ABI labels through shared contracts
Reuse canonical CLI fields and preserve literal archive labels through exact selection. Keep UTF-8 path budgets at inventory while advertising the same bounded Unicode selector that runtime admission enforces.

Co-authored-by: Yi-111-a <153097222+Yi-111-a@users.noreply.github.com>
2026-10-19 18:38:57 +08:00
morluto 69aa5465cd fix(frida): preserve resume failures across caller cancellation 2026-10-19 18:21:16 +08:00
morluto 2ec602b191 fix(frida): clarify device selection and cleanup contracts 2026-10-19 18:17:54 +08:00
morluto 44b6ec97ee fix(frida): retain cancellation through final session cleanup 2026-10-19 18:17:45 +08:00
morluto 69fe86c5c7 fix(frida): separate attachment from target resume observations 2026-10-19 18:11:27 +08:00
morluto 00dd959b82 fix(mcp): derive shared provider cleanup from loaded ports
Separate load-failure metadata from the typed optional observation ports
and derive the process cleanup inventory from those ports. This includes
the JavaScript runtime owner and removes the separate four-provider list.

Preserve all load failures in server injection and keep shared providers
caller-owned across individual server closure. Retain failed close hooks
for retry while removing peers whose cleanup completed.

Validated with 19 focused lifecycle/isolation checks and a final rerun of
the new boundary regression, check, docs and exact test discovery. The
runner test uses real idle providers with controlled SDK/shutdown handles
and a close rejection; active Inspector resource consequences, native
Linux/Windows and end-to-end stdio shutdown remain unverified.

Fixes #5222
2026-10-19 18:03:22 +08:00
morlutoandPrabhuram Karki 435efe7afc fix(frida): share exact JSON string byte accounting
Count the serialized JSON representation at its owner, including escaped
lone UTF-16 surrogates. Frida now retains the correct bounded prefix and
reports truncation in script results and subsequent session Evidence.

Move the existing exact managed string counter into the domain layer and
use it for Frida, managed projections and Ghidra inline PDB caveats. Remove
the superseded counters while keeping Ghidra's bounded length guards and
NativeAOT's distinct raw-byte admission before string allocation.

Validated with 296 focused tests, check, docs and exact test discovery.
The Unicode oracle checks every UTF-16 code unit and adjacent fragments
against native JSON encoding. Frida execution uses simulated native handles
through the real MCP handlers/client; real target instrumentation is unverified.

Fixes #5097

Co-authored-by: Prabhuram Karki <prabhuramkarki07@gmail.com>
2026-10-19 17:50:50 +08:00
4cbcead46c fix(frida): share canonical discovery results across adapters
Own device and process discovery projection in the application workflow,
bound to each named output contract. CLI and MCP now consume that result
directly, including retained observations when final CLI cleanup fails.

Remove the duplicate adapter projections and preserve provider failures,
caller-selected identifiers, process records and cleanup diagnostics.

Validated with 103 focused tests, npm run check and docs:check. Real local
Frida 17.23.2 discovery on macOS arm64 returned the same three devices
through the compiled CLI and production stdio MCP; both now pass the
advertised schema. Remote endpoints and native Linux/Windows unverified.

Fixes #4637

Co-authored-by: shreyansh1729 <shreyanshiitian1729@gmail.com>
Co-authored-by: Kaushalendra-Marcus <yadavkausha4a5@gmail.com>
2026-10-19 17:35:10 +08:00
91884c3743 fix(ghidra): own operation-scoped JVM failure evidence
Scan provider output before retention and keep bounded confirmed token facts
through output completion. Exclude identifier prefixes, pre-checkpoint context,
and unconfirmed tails; preserve invalid UTF-8 and directional truncation facts.

Make confirmed OOME observations authoritative for projection. Retained raw
prefixes cannot establish an OOME, and unrelated output cannot supply its
resource kind or recovery advice. Incomplete no-OOME output preserves the
primary error and explains uncertainty. Current checkpoint coverage remains
separate from historical budget loss.

Adapt the retention approach from #4774 with independently reproduced scanner
and projection counterexamples corrected before integration.

Validation: 268 focused tests, npm run check, npm run docs:check, and test
discovery (1639 files exactly once) pass. Controlled Node pipes/socket and fake
Ghidra JVM only; real Ghidra and native Linux/Windows behavior are unverified.

Fixes #4682
Fixes #5220

Co-authored-by: reason-machines[bot] <293529679+reason-machines[bot]@users.noreply.github.com>
Co-authored-by: Saim Shafique <msaimshafique4664@gmail.com>
2026-10-19 17:15:32 +08:00
morluto 048d70755e fix(frida): preserve script evidence through cancellation and decoding
Keep per-script messages and truncation in one owned capture through native
load completion and awaited cleanup. Return cancelled partial observations
when cancellation is observed at native completion, including native rejection;
retain failed cleanup for retry and preserve earlier failures during cleanup.
Report missing creation handles without claiming the engine did no work.

Hash original script-file bytes and retain replacement-decoding provenance
without changing normalized CLI/MCP result schemas or accepted file behavior.
Share this projection across persistent and one-shot Evidence.

Validation: 103 focused tests, final 38 manager source tests, npm run check,
and npm run docs:check pass. Controlled public CLI/MCP workflows and fake
Frida bindings only; no real target injection or device verification.

Fixes #3979
Fixes #3396
2026-10-19 16:41:15 +08:00
morluto 39275420ea fix(process): preserve cancellation through liveness rechecks
Forward the accepted observation signal into per-member process-table
rechecks and preserve its exact cancellation reason. Keep uncancelled
inspection failures unverifiable and guard successful late completions.

Fixes #5205
2026-10-19 15:52:36 +08:00
morluto ca71e91d23 fix(process): await owned observation commands through finalization
Supervise sampler and ownership-query commands through physical exit on
cancellation. Share Darwin helper command ownership, reject new commands
after close starts, and drain admitted commands before removing the root.
Keep failed root cleanup retryable without rerunning completed queries.

Fixes #5199
Fixes #5202
2026-10-19 15:37:15 +08:00
morluto ba866a26ec fix(process): preserve partial sampling observations and shutdown gaps
Keep procfs absence separate from denied and failed reads. Carry successful
rows, thread children and bounded diagnostics together so one failed sibling
cannot erase readable peers. Retain root initialization failures and validate
ps-discovered Linux candidates through stable procfs identity brackets.

Await issued reads during shutdown, retain completed rows and report an
unfinished pass through the existing sampling failure/diagnostic contract.
Derive partial coverage at its owner and preserve actual read errors when
shutdown also interrupts observation. Keep the public capture schema unchanged
and verify it with the previous strict capture reader.

Update directly affected coverage consumers and regression fixtures, including
identity contradictions, mixed outcomes, late failures, cleanup, cancellation,
process-only comparison unknowns and converted MCP schemas.

Validation: 12 focused files / 123 tests; full check; docs check (5 tests);
test discovery (1,635 files). Real macOS CLI/MCP controls exercised source-owned
PTY targets. Linux permission behavior uses deterministic boundary fixtures;
real Linux and Windows qualification remain unavailable. Completed CLI cost
comparisons do not establish a speedup.

Fixes #5081
Fixes #5194
2026-10-19 15:14:42 +08:00
morluto e8da7e1edd fix(artifacts): share bounded ASAR signature observations
Parse Pickle extents once at the ASAR boundary and carry finalized signature
facts through root and nested classification. Scan JSON whitespace within its
declared extent and decode budget without retaining the whitespace prefix.
Keep prefix storage bounded independently of stream chunk ownership.

Fill fixed ASAR prefixes and DMG trailers across short reads, preserve
cancellation through admission and stream EOF, and retain existing cleanup
ownership. Cover public CLI/MCP selection, root/nested inventory, malformed
JSON whitespace and padding, limits, native/XML consumers and descriptor faults.

Validation: 24 focused files / 170 tests; full check; docs check; test discovery.
Official inert ASAR fixtures and controlled descriptor faults were exercised;
real Electron execution, Windows and natural OS short-read frequency remain
unverified. Equivalent compact CLI tasks returned identical results and reply
token estimates; repeated timings do not establish a speedup.

Fixes #3574
Fixes #5188
2026-10-19 14:32:48 +08:00
morluto 2e5171e391 fix(browser): retain historical capture outcomes through cleanup 2026-10-19 14:03:57 +08:00
morluto 87ab054ea3 fix(runtime): retain Inspector and Electron cleanup ownership 2026-10-19 14:03:28 +08:00
morluto 7f4e7d5577 fix(browser): preserve caller cancellation through CDP observations 2026-10-19 14:00:01 +08:00
morluto 9aca543f46 fix(browser): isolate web bundle analysis with bounded partial results
Run inert captured-script analysis in owned children with per-script and aggregate deadlines, bounded source/result transfer and explicit per-script coverage. Preserve completed facts and exact cleanup authority across cancellation, mixed descriptor/process failures and cross-consumer retry.

Share aggregate source admission across page and Electron capture, expose CLI/MCP resource controls and retain selected parameters in Evidence. Verified with controlled CDP public workflows, real owned Node failure controls and the reporter-matching ReactDOM UMD artifact; real Chrome/Electron and Windows/Bun remain unqualified.
2026-10-19 13:22:54 +08:00
morluto 715d93e954 refactor(process): share ownership for isolated analysis workers
Separate child and private-root ownership from JavaScript analysis protocols. Retain exact cleanup lifetimes across retries, late handshakes and runtime reuse; observe request-stream errors and preserve per-job file cleanup during worker reuse.
2026-10-19 13:12:25 +08:00
e4c3d72396 fix(javascript): converge cyclic aliases with explicit projection widening
Replace initializer-history and full-path enumeration with a finite projection
join at each source read. Retain conservative local returned-reference effects
and disclose precision loss through static, semantic and captured-web results.
Close full-binding callback cycles while preserving narrowed read semantics.

Fixes #4348
Fixes #5138
Refs #4349
Refs #4364

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Fuxuan-CN <3072252442@qq.com>
2026-10-19 12:26:54 +08:00
morluto 9af0b6113c fix(process): retain snapshot handles and partial read outcomes 2026-10-19 11:37:41 +08:00
morluto 974487f00f fix(process): preserve cleanup ownership through retries and close
Carry historical cleanup reports with the exact lease that can confirm
release. Bind originating capture errors and typed retry aggregates to
those owners while preserving primary failures and completed observations.

Keep those bindings through MCP close and compose mixed session/process
cleanup failures. Start both close operations even when a child throws a
typed failure synchronously.

Fixes #5144
Fixes #5163
Fixes #5166
2026-10-19 10:52:55 +08:00
morluto dfe8378cf5 fix(electron): preserve callback ownership through listener removal
Keep canonical callback ownership independent of writable raw-listener
metadata. Resolve the native removal argument in current registration order,
then let EventEmitter own mutation, getter timing and removal meta-events.

Leave registrations unwrapped with explicit observation gaps when methods
or receivers do not support that ownership model. Preserve per-callback
Evidence for supported registrations and document the remaining limits.

Fixes #4513
2026-10-19 09:51:04 +08:00
morlutoandDeryFerd d6ca7b3f20 fix(process): gate launch and retain cancellation provenance
Check cancellation at the PTY execution boundary after executable sampling
and descriptor cleanup settle. Completed file observations cannot authorize
launch for a cancelled request. Preserve exact caller reasons in the shared
capture cancellation constructor and its admission, exit and finalization
consumers instead of reconstructing them downstream.

Exercise real executable reads and closes through the capture API with a
throwing PTY sentinel at five schedules. Retain a real completed Node capture
and its cleanup facts when the final progress callback cancels the request.
Strengthen existing metadata and baseline cancellation controls.

Adapted after review of #4836 at 014afa3892.
Raw snapshot/sampler descriptor cleanup ownership remains tracked in #5140;
this execution-admission change does not claim to solve failed close recovery.

Closes #4512
Closes #5142

Co-authored-by: DeryFerd <deryferdikao125@gmail.com>
2026-10-19 09:14:00 +08:00
morlutoandshreyansh1729 d3627b1038 fix(mcp): preserve procedure aliases and complete name ambiguity
Derive address suggestions separately from name uniqueness across every
validated inventory row. Keep the sole exact address or an explicit ambiguous
state per name, without retaining a set of all name/address pairs. Reuse the
canonical address/value leaf contract for completion's parsed facts.

Cover order independence, same-address duplicates, later ambiguity and alias
rows beyond the MCP reply limit through the public SDK. Preserve provider
spelling, document context, cold-session admission and cancellation behavior.

Adapted from #4648 at 5b019e1179.

Closes #4623

Co-authored-by: shreyansh1729 <shreyanshiitian1729@gmail.com>
2026-10-19 08:54:23 +08:00
Vaidehi Kakad 273bb66276 fix(setup): treat empty APPDATA as unset for VS Code, Trae and Devin (#5126) 2026-10-19 08:45:04 +08:00
morluto 6296fdf560 fix(reference)!: preserve symlink races and root failure facts
Classify replacement EINVAL at the readlink syscall so the reader and importer
retain sibling observations. Give an admitted root's enumeration failure its
own typed field, use it for unresolved symlink coverage, and project it as a
graph limitation instead of an invalid dot-path child entry. Keep admission,
cancellation and cleanup failures distinct.

Closes #5135
Closes #5136

BREAKING CHANGE: Partial reference-source reader results report failed root
enumeration in rootFailure instead of a failed directory child at path ".".
Historical source graphs preserve the root failure as a top-level limitation.
2026-10-19 08:36:53 +08:00
morlutoandrudrakshagarwal4200-ai c85b44e1b1 fix(process)!: retain partial filesystem snapshot observations
Keep expected readlink and follow-up lstat failures as typed entry omissions,
including the observed path and errno. Retain directory metadata and sibling
observations, distinguish known identity replacements, and keep cancellation
and unexpected I/O failures terminal. Reuse admitted root metadata and test
cancellation by descriptor state rather than a count of named lookups.

Adapt the symlink race handling proposed in #4587 at fae4e25539.

Closes #4575

BREAKING CHANGE: Filesystem enumeration omission reasons now also include
entry_unavailable and identity_changed. Clients validating the old literal
reason must accept the expanded capture schema.

Co-authored-by: rudrakshagarwal4200-ai <rudrakshagarwal4200@gmail.com>
2026-10-19 08:34:39 +08:00
morlutoandDragolone 95c8f57aa2 fix(investigation): scope automatic unknowns to result Evidence
Construct automatic unknown identity once at the application boundary.
Validate the original question before adding immutable Evidence scope, and
preserve each result's supporting link through CLI and MCP producers.

Apply the shared policy to derived investigations, managed comparisons and
verification, composed workflow residuals, and process-capture residuals.
This prevents registry conflicts and silent loss of later result links.
Keep explicit creation/update semantics and exact Evidence replays intact.

Cover all affected producer families with public MCP regressions, preserve
snapshot provenance distinctions, and retain blank-question/error handling.
Remove the superseded single-result call-path test.

Fixes #3333

Co-authored-by: Dragolone <160818051+Dragolone@users.noreply.github.com>
2026-10-19 08:02:03 +08:00
morlutoandHenglie 92dadf9334 fix(domain): preserve partial reference comparison facts
Own endpoint identity and per-edge kind knowledge in one parsed reference
representation. Preserve exact same-artifact coordinates and cross-artifact
name uncertainty, including generated and nonunique procedure labels.

Use exact multiplicity-preserving sparse compatibility flow instead of
positional/greedy pairing or a quadratic adjacency matrix. Share the native
coordinate parser with call paths and remove the superseded projections.

Validate public MCP comparison/reconstruction outcomes, independent tiny
permutation oracles, dense matching and advertised JSON Schemas.

Fixes #4210
Fixes #5131

Co-authored-by: Henglie <ebhenglie@gmail.com>
2026-10-19 07:45:34 +08:00
morluto 559af3d3ff fix(uninstall): retain per-file partial outcomes
Preserve configuration paths and constituent actions independently of aggregate status. Derive summaries from all leaf outcomes, including after final cleanup reporting, so a later failure cannot hide an earlier removal.

Closes #5079
2026-10-19 07:22:01 +08:00
morluto a80575c736 fix(native): preserve partial call reference evidence
Retain provider-reported call sites and raw classification independently of generic reference flags. Keep all endpoint evidence when containing-procedure routes merge, and include relation in edge identity to avoid order-dependent labels.

Closes #5130
2026-10-19 07:12:44 +08:00
morluto fdaffe21cc docs(manifest): align plan with top-level body parsing 2026-10-19 07:08:20 +08:00
291059adb4 feat(analysis-view): project an environment manifest from web network captures (#4954)
* feat(analysis-view): project an environment manifest from web network captures

Add the environment-manifest view kind to inspect_analysis_view for retained
HAR Evidence: the primary origin's recorded request lines become a
deterministic tool surface (names, path templates, parameters with their
rule and basis, observed query names, value-free body shapes, record
pointers), with excluded groups, three fixed unknowns and the shared
projection budget. The four format rules always apply; after-uid-literal,
opaque-token and sibling-variance are opt-in and labelled, and literal
fold-in never touches a format-rule parameter. The api-surface accumulator
moves onto shared route, media-type and budget helpers without behaviour
change.

Refs morluto/rea#4933

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(web-network): check the manifest refusal text like the api-surface refusal

The real-capture verifier stringified the whole MCP result for the
environment-manifest refusal, so a declared "[" literal matched the result
envelope itself; compare the parsed refusal as the api-surface branch does.

Refs morluto/rea#4933

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): record the hosted web-network lane run for the manifest view

Refs morluto/rea#4933

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* docs(specs): reconcile the manifest view verification scope note with the hosted run

Refs morluto/rea#4933

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(analysis-view): bound body, route and name work in the environment manifest

Addresses the automated review findings on the PR: read request bodies at the
top level only instead of walking nested values; admit every literal route
part before materializing it; compare at most 32 segments in sibling-variance
and say so; keep stop words literal after a uid literal; keep the next
collision suffix per tool-name base; preserve a templated exclusion when two
groups print the same row.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(analysis-view): keep manifest folding, naming and media-type reads linear

Addresses the second automated review round: fold literal siblings through
set membership, key collision suffixes by the truncated name they share, and
charge a request media type before it is scanned.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(analysis-view): charge the manifest group key before building it

Addresses the third automated review round: the composite key copies the
method, origin, template and rules, so that copy is reserved before the key
is stringified.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(analysis-view): accept a +json suffix only on application media types

Addresses the fourth automated review round: `image/example+json` or
`text/example+json` no longer counts as JSON for origin selection, exclusion
or body shapes, matching the documented `application/json` and
`application/*+json` contract.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(analysis-view): require the capture parent's exact subject for a manifest

Addresses the fifth automated review round: the manifest cites the report
path and digest, so a parent whose subject is absent or names another path or
SHA-256 is refused at admission, as the capture view already does; the
api-surface view keeps its existing admission.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(analysis-view): share truncated suffix allocation work

Track suffix progress by the actual truncated prefix and suffix width. Distinct full names can collide only after suffix truncation; sharing that progress prevents quadratic rescanning while preserving shorter free names and existing allocation order.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* fix(analysis-view): merge only identifier-like siblings under sibling-variance

Addresses the sixth automated review finding: a bucket merged whenever one
literal carried a digit, folding plain words such as `mine` into the
parameter. The rule now partitions the bucket, merges the identifier-like
siblings and leaves the other literals as their own tools.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(analysis-view): combine qualifying sibling cohorts

Keep coded identifiers and a qualifying plural hyphenated cohort in one eligibility Set before checking the minimum merge size. Read each literal once and reuse the same membership at the consumer, preserving non-identifier routes and the three-hyphen minimum.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

* docs(analysis-view): clarify opt-in sibling folding

State the additional sibling-variance selection in the guide, acceptance specification and MCP parameter description. Preserve the existing single-rule behavior and caller-selected inference rules.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-19 07:07:37 +08:00
morluto 65884350ff fix(native): retain partial call routes and omitted sites
Separate enumeration outcome from retained facts in the native call-route
owner. Keep every available typed call with its source provider and site,
supplement incomplete kinds with inferred fallback targets, and retain
known routes when fallback fails. Per-reference unknowns take precedence
over aggregate availability; cancellation remains terminal.

Project partial routes before enumeration failures, preserve each omitted
route's relation, and include its call site in the omitted-edge identity
so distinct observations to one target cannot overwrite each other.
Remove the superseded success-only provider/result representation.

Validation: 69 focused cases plus final 30-case rerun, including nine
public SDK MCP regressions; full static/architecture, docs and discovery
checks pass. Controlled-provider source REDs reproduce both route loss
and omitted-site collisions. Real native providers remain unverified.

Closes #5073
Closes #3922
Closes #5128
2026-10-19 06:48:14 +08:00
22ddd82014 fix(uninstall): preflight repeated registration ownership
Read shadowed registrations from the effective JSONC syntax tree before
any client is changed. Share the same typed ownership decision with the
reread before removal, including foreign OpenCode V1 fallbacks. Remove
all admitted duplicates using one member/separator planner and grant
serializer authority only for exact admitted paths.

Setup may remove its explicitly superseded OpenCode V1 path. Preserve
inactive repeated parents, unrelated entries, comments and source backups.
Use the pinned JSONC scanner instead of handwritten string decoding.

Validation: final 86 focused cases and 9 setup acceptance cases passed;
104 additional filesystem consumer cases passed. Static/architecture,
docs and discovery checks passed. A broader 186-case run had one OMP
timeout; its isolated 9-case rerun passed, with timeout cause unverified.
Controlled compiled CLI comparisons verify removal/refusal and backups;
real developer-client execution remains unverified.

Adapted from #4977 at 4cd22d4ec2.
Closes #4976

Co-authored-by: Nikhil Bhagat <knewboy.nykhil@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 06:32:14 +08:00
morluto d1adc60795 test(contracts): align plist and UI finalization regressions
Update public-boundary expectations after the explicit XML unknown-scalar
and native UI deadline provenance changes. Retain raw malformed literals,
independent exact integers, expanded-year ISO dates, and partial UI reports.
Assert successful cleanup releases its lease and failed cleanup retains it
until close retries. Keep malformed-input and true date-range coverage.

The shared number fixture owns CLI/filesystem/MCP expectations. Native
plutil controls confirm integer entities are invalid plist literals, even
though they are valid XML. No runtime behavior or CI gates change.

Validation: 187 source cases, 138 focused public cases, final 97-case
rerun after fixture typing/group changes, full static/architecture checks,
and test discovery (1591 files).
2026-10-19 06:22:32 +08:00
morluto 32f0e51209 fix(session): describe native UI trace source routes
Share source operations with execution owners and derive availability and missing prerequisites from one evaluation. Distinguish authored UI dispatch from native-seed call tracing without inventing a default request mode. Preserve target gates, typed failures and partial results.

Fixes #5071
2026-10-19 03:39:02 +08:00
morlutoandMert Kaya 29910d16b9 fix(apktool)!: select numeric regions using Android b+ qualifiers
Normalize three-digit region aliases at the shared locale owner, preserving
caller labels and physical-table reuse. Reject malformed legacy qualifiers
through the same CLI/MCP contract and table classifier.

Adapt the owner correction and regressions from PR #4918 after checking Android
and supported Apktool qualifier sources. Add public MCP validation and preserve
existing two-letter regional selectors.

Fixes #4916

BREAKING CHANGE: Numeric legacy locale selectors such as es-r419 are rejected.
Use es-419 or b+es+419. Two-letter region selectors remain supported.

Co-authored-by: Mert Kaya <47145541+mertkayacs@users.noreply.github.com>
2026-10-19 03:25:25 +08:00
morluto 50b6975d86 fix(session): admit direct native dispatch metadata providers
Share named metadata source operations between execution and capability discovery. Preserve symbol fallback and typed runtime failure behavior, and cover availability through public MCP workflows.

Fixes #5070
2026-10-19 03:19:33 +08:00
morluto 1d5bf5ff08 fix(session): align call relationship discovery with traversal modes
Declare the missing trace composition and correct call graph prerequisites to require address resolution plus the selected relationship direction. Report forward/backward modes and the actual default independently, preserving missing operations, owner failure reasons and direct partial outcomes.

Share the direction-to-provider mapping across runtime and discovery, reuse the mode evaluator, select defaults by name, and check composition coverage against every canonical enhanced contract. Keep same-endpoint traces callable without relationship reads.

Adapt the missing trace-composition correction proposed in PR #4729 and complete the directly related ownership/refactoring and sibling graph correction.

Validation: 75 source tests and 76 public MCP/schema tests passed; full static/architecture checks, docs and test discovery passed. Controlled SDK/provider workflows verified unchanged catalogs and normalized traces. Small whole-session costs were recorded, with no speedup claim. No native-engine, CLI, Linux/Windows or model tool-selection qualification.

Fixes #4687
Fixes #5068
Co-authored-by: AHMED <aptech356@gmail.com>
2026-10-19 03:08:39 +08:00
morluto 3537e58c1a fix(plist)!: preserve unknown XML scalar identities
Interpret complete scalar source at the XML owner instead of accepting numeric prefixes, permissive date strings or nonempty booleans. Retain malformed content as explicit unknown scalars with original literals and reasons, while preserving the surrounding archive and independent numeric facts.

Share the representation across plist, keyed archive, Interface Builder and entitlement projection; remove the superseded numeric fallback and helpers. Parse date fields as UTC, retain real entity/CDATA semantics, and distinguish native integer/real whitespace without ambiguous whitespace backtracking.

Validation: 276 source tests and 60 compiled/public tests passed, with updated scalar regressions rerun; static, architecture and docs checks passed. Native macOS plutil controls and CLI/MCP source-hash/time-zone controls executed. No Linux/Windows or deep-provider qualification. Tiny completed CLI task costs recorded; no performance improvement claimed.

BREAKING CHANGE: Unresolved XML scalar values now use $plist_type unknown wrappers with element, literal and reason. This replaces the former real/null unknown marker and malformed scalar prefix fallback. Supported extended UTC years now preserve their timestamp.

Fixes #4852
2026-10-19 02:48:09 +08:00
morlutoandAvichal Pandey cee95b2ae6 fix(plist): preserve source semantics in XML data decoding
Adapt the completed-quartet decoder from PR #4981 at 4cf6cac14. Bind raw source spans to validated DOM nodes before entity and line-ending interpretation can change data bytes. Preserve depth preflight, reject invalid data forms and allocate exact decoded output through one shared quartet grammar.

Fixes #4978

Co-authored-by: Avichal Pandey <avichal2018lko@gmail.com>
2026-10-19 02:28:27 +08:00
morluto eb2c3b589e fix(native): retain LLDB evidence prefixes after read failures
Return byte prefixes with tagged read outcomes and exact causes. Share those facts across partial journals and captures, preserve typed primary failures and successful siblings, and keep zero-byte failures unavailable. Retain failed descriptor and root owners through retry.

Fixes #5058
2026-10-19 02:06:07 +08:00
morluto d4e233946a fix(errors): retain secondary failures without replacing primary causes
Give the typed error owner a separate retained secondary-failure collection. Preserve exact direct causes, including caller cancellation reasons and absent causes, while keeping existing diagnostic and live cleanup ownership projections.

Fixes #5059
2026-10-19 01:56:58 +08:00
morluto 292e7bef27 fix(native): bound LLDB PID reads before validation
Derive the read limit from the accepted safe decimal PID plus a tolerated CRLF and overflow sentinel. Retain short-read handling, cached valid facts and existing descriptor ownership and handshake semantics.

Fixes #5057
2026-10-19 01:48:37 +08:00
morluto 36d156ff05 fix(native): retain UI interruption source through final cleanup
Record caller cancellation versus the owned deadline once and share that provenance through helper execution, scenario waits and finalization. Preserve independent failures and partial reports, consolidate scenario failure handling and dispose listeners on every exit.

Fixes #5056
2026-10-19 01:41:52 +08:00
morluto 7201e8a443 fix(native): validate LLDB readback encoding before reporting facts
Decode completed journal rows strictly while retaining valid neighbors and torn-tail semantics. Preserve structured result read, decoding, JSON and schema failures through the typed fallback.

Fixes #5055
2026-10-19 01:41:48 +08:00
morluto 9e259f87c8 fix(native): retain signature roots until descriptor cleanup completes
Give each signature snapshot a private child-resource scope. Its composite
root lease closes those children before removing the directory and retains
both stages across failed retries. Bind local cleanup failures to their
exact owner so child release cannot clear a failed root removal.

Replace the mixed-outcome regression that expected premature root removal.
Cover real descriptor denial, primary/cancellation preservation, MCP close
and same-connection recovery. Expose underlying real codesign test errors
before asserting result fields.

Fixes #5052
2026-10-19 01:24:40 +08:00
morlutoand星闌 8307ea3717 fix(adb): preserve command failure target identities
Keep the selected device, addressed file and actual host operand distinct
at the command owner. Parse known device and file diagnostics before
projection, including AOSP host write/read failures and exact snapshots.
Classify complete captured stderr before shortening display text, and
scan leading notices without expanding the capture into a line array.

Adapt Xinglan233's PR #4655 and extend its source-shaped host controls.
Add built CLI/MCP identity, long-path, recovery and input-preservation
coverage. Real platform-tools and Android devices remain unverified.

Fixes #4641
Fixes #4643
Fixes #5051

Co-authored-by: 星闌 <xinglan233@163.com>
2026-10-19 01:13:57 +08:00
morlutoandMangolycheematcha fd728f271e fix(plist): ignore processing instructions between container members
Exclude processing-instruction nodes at the shared container-member owner
before dispatching plist tags. Keep strict syntax validation and scalar
content rules, with app-resolution and CLI/MCP evidence regressions.

Adapted from Mangolycheematcha's PR #4965, including its boundary controls.
Added built CLI/MCP coverage and verified container fixtures with plutil.

Fixes #4964

Co-authored-by: Mangolycheematcha <288892596+Mangolycheematcha@users.noreply.github.com>
2026-10-19 01:03:32 +08:00
gensokyo-devandKaoru0822 b0b485abff fix(hopper): verify and repair the Linux embedding runtime (#5041)
Verify the distribution Python embedding library during approved Linux Hopper
setup, conditionally repair the matching Ubuntu dependency, and confirm that
the library loads. Share fresh bounded observations with doctor, preserve
unknown configuration and caller cancellation, and join probe exit through
the existing process supervisor.

Validate clean Ubuntu installation, normal-user real Hopper CLI/MCP workflows,
independent ELF/SQLite oracles, cancellation and cleanup regressions, 154
focused checks and all 40 current-head CI checks. Preserve measured artifact
identity, failed attempts and local host-memory guard limitations.

Closes #5015.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-19 00:11:10 +08:00
gensokyo-dev 23f984b1a8 fix(tests): restore Android prerequisite verification
Supply a real retained resource owner to every Android verifier prerequisite
check, sharing the existing Ghidra verifier cleanup scope. Match recovery
checks to typed Java or archive failures and applicable remediation, preserving
exact close retry authority and primary failures.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
2026-10-18 12:46:25 +00:00
gensokyo-dev 093ce695f0 fix(tests): preserve temporary fixture ownership
Normalize shared test fixture prefixes using the hygiene verifier ownership rule. Preserve caller labels, existing owned names, and third-party caches; cover retained fixtures and exact cleanup through subprocess regressions.
2026-10-18 11:34:44 +00:00
gensokyo-devandKaoru0822 63c970812b perf(hopper): reuse decoded records for literal string matches (#5017)
Keep complete decoded string records in Hopper's existing search inventory
and directly project literal matches, removing the redundant full record
projection and superseded value-only representation.

Record real Linux CLI/MCP correctness and Evidence checks, shorter warm
queries, negative whole-task costs, native coverage gaps and resource stops.

Fixes #5010.

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-18 19:19:20 +08:00
gensokyo-devandKaoru0822 c12d9eda87 docs(jeb): qualify Linux CE native workflows (#5002)
Qualify the official Linux CE headless launcher and engine-native item references.
Record real native CLI/MCP qualification, costs, failures and integration controls.

Closes #4996

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-18 17:13:04 +08:00
morluto a25eb5fbb4 chore(release): sync 6.7.0 checkpoint
Preserve the immutable 6.7.0 tag ancestry and synchronize version metadata after verified npm publication. Keep newer main performance changes and the full 6.6.0 changelog.
2026-10-18 16:18:49 +08:00
7c458f04b9 perf(apktool): avoid duplicated primary strings on request
Add opt-in string_tables_only and CLI --string-tables-only to keep selected
strings once in typed table facts. Preserve existing defaults and legacy replies;
charge aggregate output capacity for the copies actually requested.

Validate shared CLI/MCP behavior with independent XML oracles, three real APKs,
94 source tests, nine compiled boundary tests, 36 completed MCP tasks and three
CLI parity tasks. Preserve full task estimates, negative timings, resource
admission refusal and verification limitations in the measured report.

Fixes #4982

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-18 15:38:16 +08:00
8f7d12e30d perf(analysis-view): reuse validated immutable parents
Reuse successful format validation for exact authenticated immutable native and imported JavaScript results. Preserve schema normalization and alias topology before borrowing source data; owned JavaScript graph wrappers retain their existing metadata-normalization path.

Validated with 130 source tests, 36 compiled CLI/MCP boundary tests, 27 default-deadline integration tests, full checks/docs/build, and paired real retained-Evidence tasks. The report preserves cold costs, previous negative results, incomplete resource-stopped runs, and the limits of offline token estimates.

Fixes #4810

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-18 14:38:00 +08:00
2389 changed files with 287431 additions and 22537 deletions

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. 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: "42"
version: "44"
---
# REA
@@ -30,6 +30,8 @@ unavailable, read [connection and recovery](references/connection-and-recovery.m
Diagnose the observed blocker, continue useful supported work, and resume the
original task after repair. Client approval, shell PATH, registration and engine
availability have different remedies; avoid repeating setup for all of them.
If the host times out without a REA result, do not repeat the unchanged call or
assume work stopped. Read the recovery guide's deadline distinction before retrying.
1. Diagnose without changing REA or client configuration. `npx` may download
the package and write to npm's cache. For Codex, run
@@ -89,9 +91,19 @@ explicit path or endpoint and do not need it.
- ASAR or extracted JavaScript/Electron tree:
`analyze_javascript_application`.
- Archive/package member inventory (ZIP/APK/IPA/MSIX/AppX or DMG):
`open_binary` with the supplied local path; use `inspect_artifact` when its
graph and findings help answer the question.
- Archive/package member inventory (ZIP/APK/IPA/MSIX/AppX, DMG, or a PyInstaller
executable): `open_binary` with the supplied local path; use `inspect_artifact`
when its graph and findings help answer the question. A PyInstaller CArchive
is the application layer; the bootloader is only the native prefix. Start with
`detail: "summary"` for large inventories, then use retained inventory views
for selected member fields/pages. A complete small inventory can cost less
than extra calls and schemas. Runtime options are metadata, not files.
Compact delivery still inventories and hashes members. See the
[Python packaged applications guide](https://github.com/morluto/rea/blob/main/docs/python-packaged-applications.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
executable digest or binary snapshot; use `open_binary` for native code.
- Android APK code, classes, methods, or incoming references:
`inspect_android_package`, then focused Android tools when advertised.
Archive member inventory still uses the archive route above.
@@ -155,7 +167,9 @@ explicit path or endpoint and do not need it.
ambiguity. No implicit fetch or target execution; WAT is not original source.
See the [WASM guide](https://github.com/morluto/rea/blob/main/docs/wasm-artifacts.md).
- Explicit local EVM bytecode carrier: `inspect_evm_interface` with caller-selected
`raw` or `hex` encoding. Preserve carrier/decoded digests and treat selectors,
`raw` or `hex` encoding. The owned worker deadline is `timeout_ms` (default
30000 ms, range 1..2147483647, next call). It does not raise the fixed byte,
address-space, or CPU allowances. Preserve carrier/decoded digests and treat selectors,
argument strings and mutability as inferred candidates; this performs no chain
lookup or target execution. For the complete inferred interface without hex or
duplicate stdout, discover support and select `detail: "summary"`; complete
@@ -169,12 +183,40 @@ explicit path or endpoint and do not need it.
absent metadata does not prove a binary is not Go, and unparsed text records
remain explicit. See the
[Go binary guide](https://github.com/morluto/rea/blob/main/docs/go-binaries.md).
- Embedded CUDA/HIP code objects: `inspect_gpu_code_objects`; inventory targets
first, then decode selected payloads and query retained GPU Evidence.
- Bundled GGUF or safetensors model declarations: `inspect_model_artifact`
with the explicit local file. Default header hashing leaves full-file identity
unknown; `hash: "full"` additionally reads all weights for SHA-256. MCP returns
retained summaries; optional `view` selects one page in the initial call. Use
`inspect_analysis_view` kind `model-artifact` for
batched metadata keys, tensor names or type totals, selected fields and pages.
Preserve header-scoped indices and array preview omissions; do not infer model
behavior from declared architecture or tensor types. See the
[model file guide](https://github.com/morluto/rea/blob/main/docs/model-artifacts.md).
- Unity IL2CPP names, member owners and string literals from `global-metadata.dat`:
`inspect_il2cpp_metadata` with the explicit local file; MCP defaults to compact
counts. Query sections, images, types, methods, fields, properties, events,
parameters or string_literals through `inspect_analysis_view`
with the returned `parent_evidence_id`, using exact filters, batch indices and
selected fields. Parameters accept `method_indices`, avoiding a scan of all
parameter pages. Missing collections in historical Evidence remain unknown.
Versions 24, 27, 29, 31 and 39; no Unity, IL2CPP
binary or disassembler is run. Unrecognized magic (possibly encrypted) and
other versions are unsupported. Optional matching `binary_path` enables static native addresses and type references; query `method_addresses` with indices or addresses/states, preserving every shared-body method and both artifact identities. Without a linked binary native counts remain unknown. Byte-pattern fallback is inferred; no runtime behavior or same-build pairing is proved. See the
[IL2CPP metadata guide](https://github.com/morluto/rea/blob/main/docs/il2cpp-metadata.md).
- Embedded cargo-auditable Rust dependency metadata: `inspect_rust_binary`
with the explicit local ELF, PE, or thin Mach-O file. This built-in
target-free inspection requires no Rust installation or disassembler. Preserve
package order, dependency indices, and the section file range. A missing
`.dep-v0` section is null metadata, not proof the binary has no dependencies.
A rustc commit hash is an inference from a read-only `/rustc/<40-hex>/` path.
For selected crates, use `view: {collection: "packages", names: [...],
fields: ["name", "version", "source"]}` on the first call; explicitly include
`dependencies` for direct index references. Use `detail: "summary"` for counts
and ranges, or retained `inspect_analysis_view` Rust package/edge pages for
subsequent filters. Keep the complete parent Evidence accessible; CLI compact
delivery requires `--evidence_output`.
See the
[Rust binary guide](https://github.com/morluto/rea/blob/main/docs/rust-binaries.md).
@@ -247,6 +289,12 @@ Provider candidate facts describe possible providers, while top-level session
capabilities describe the current route and `analysis_provider_binding` names the
selected provider. Do not treat those scopes as interchangeable.
For a Ghidra startup timeout on a large native target, follow
[deadline recovery](references/native-and-artifacts.md#ghidra-startup-deadline-recovery)
before abandoning deep analysis or repeating the same cold import. The default
330 seconds is configurable; changing the server's environment requires a new
REA process.
## Work summary-first
Start with the default result and use its inline Evidence and graph context.
@@ -25,8 +25,9 @@ stdio. A full JDK, including `jdk.compiler`, is required on every host; Windows
`JAVA_HOME` selects `bin\java.exe`. Consult the Android guide for actual host
verification coverage. Calls use one worker and provider deadlines; optional
`REA_JADX_HEAP_MIB` selects the JVM heap and `REA_JADX_OPERATION_TIMEOUT_MS`
the per-operation deadline (default 120000 ms; the MCP client's tool timeout
must also allow it). The APK is never launched,
the per-operation deadline (integer milliseconds from 1 to 2147483647, default
120000; a change applies on the next process start; the MCP client's tool
timeout must also allow it). The APK is never launched,
and no emulator is required.
Manifest entries and decompiled text are static observations, not execution or
@@ -34,6 +34,47 @@ answers part of the question, and name the unavailable evidence separately.
Do not substitute another target. Label observations from ordinary shell tools
as such; only actual REA output supplies REA Evidence.
## Distinguish client and server deadlines
A host message such as `timed out awaiting tools/call` with no REA result means
the client's deadline expired before a result arrived. It does not establish
that REA finished, canceled successfully, or released all resources. Do not
repeat the unchanged analysis. Inspect available session/provider state and
retained Evidence only when useful; an idle `binary_session` is not proof that
every target-free operation stopped. Never invent a missing Evidence reference.
Allow the host tool deadline to cover execution, cancellation/cleanup, and
response delivery. In Codex, the setting is
`mcp_servers.<server-id>.tool_timeout_sec` in **seconds**, not
`startup_timeout_sec`. Select a value for the actual operation budget and
headroom, not a universal timeout. See the
[official MCP configuration reference](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
Apply configuration changes only within the authorized scope, preserving
unrelated entries and backups; reconnect/restart as required by the host.
When configuration is not editable, report the setting needed or use an
authorized CLI fallback. Do not silently broaden permissions or switch targets.
A returned REA `provider_timeout` instead means the **server/provider** reached
its deadline. Follow its `remediation.action`, reuse accessible partial Evidence,
and resolve reported incomplete cleanup before retrying. Raising only the
client deadline does not change this server budget. For static JavaScript,
`analysis_timeout_ms` (CLI `rea analyze-javascript-application <path>
--analysis-timeout-ms <milliseconds>`) controls each source's
startup, analysis and transfer deadline in **milliseconds**. Increase that
budget or reduce semantic work / select exact inventoried `source_paths` when
the task permits. Omit `source_paths` for all sources; `[]` is invalid.
`detail: "summary"` reduces delivery, not analysis work. A per-source budget
does not bound the elapsed time for an entire multi-source application.
Partial-Evidence inspection can avoid recomputation; an unavailable reader is
not itself a reason to block a corrected static-analysis retry.
The shorthand `rea analyze <path>` does not expose this timeout flag; use the
explicit JavaScript command when changing that budget.
For invalid arguments, use the connected tool's current input schema, or the
installed CLI's command help. Refresh the catalog if stale; do not guess fields
from an older skill or return the entire catalog to repair one field. Correct
all reported fields before retrying.
## Repair registration when needed
For Codex:
@@ -24,6 +24,17 @@ retain its complete source and receive that view immediately. Without that
advertised choice, keep the existing complete call. CLI inspection returns
portable complete Evidence; save it before projecting a selected inline view.
For native procedure/name/string inventories, select `detail: "summary"` when
the connected tool advertises it and the task needs counts or selected rows.
Use its parent Evidence ID with
`view: {kind: "native-inventory", offset: 0, limit: 32, fields: ["value"]}`.
Search tools retain the existing pattern/mode/case/document selection. Omit
`fields` for complete records; `record.address` and `source_index` remain on
selected rows. Selecting `value` keeps its string/decoding qualifications.
Parent Evidence ID plus source index preserves same-address
alternatives. Follow `coverage.next_offset` only as far as the question needs;
exhausting retained rows does not establish complete program discovery.
Use `record_unknown` to track unresolved questions in the user's investigation
and name the authority or environment still required. Supply supporting and
contradicting evidence IDs. It updates the session registry directly.
@@ -69,3 +80,23 @@ When the connected schema advertises `include_query_parameter_names`, select
it in the view for distinct observed names with original record ordinals. Query
values are omitted; the names establish neither required parameters nor a
complete server schema. Keep the original parent Evidence for exact URLs.
Use `inspect_analysis_view` with `view: {kind: "environment-manifest"}` on the
same retained HAR Evidence to project the primary origin's request lines into
named tools with path templates, parameters, observed query names, value-free
body shapes and record pointers for an agent environment. Opt into
`template_rules` only when recorded identifiers need them; every template,
parameter and merged sibling is an inference, no header, cookie or body value is
copied, and the three stated unknowns stay unresolved.
Use `view: {kind: "environment-state"}` with the manifest's `template_rules` to
extract the data those reads observed instead: entity types and identity
fields, entities with recorded values, documents, and per-tool render plans
checked against the recordings. The state comes only from reads before the
first related write; types, identity and list membership are inferences.
`rea environment-serve manifest.json --evidence capture.json` derives that
state at startup, answers read tools from it and serves `data/reset`,
`data/add` and `data/get` on `/agentenv`; write tools are not served. It
replays the capture instead with `--replay-only` or when the state is
unavailable (not derivable, or a catalog over the discovery budget), and its
stopped document's `state` says which applied.
@@ -18,9 +18,15 @@ only selected files. The result and summary record `source_selection`; files
outside scope and their relationships remain unknown, so partial application
coverage does not mean the selected source failed. Use repeated `--source-path`
on either static application CLI route. Omit the selection when the question
requires complete application analysis. `detail: "summary"` reduces delivery
requires complete application analysis; `source_paths: []` is invalid, not an
unfiltered request. `detail: "summary"` reduces delivery
and does not by itself reduce analysis work.
ASAR header/index admission is fixed at 16 MiB / 16777216 bytes for this
release and has no runtime override. `source_paths`, `detail`, and
`max_heap_mb` do not bypass or raise it. Analyze an extracted directory, or
supply an archive whose header fits.
Exact `#alias` specifiers resolve through the importer's
enclosing package `imports` map to package-local files; nested `node_modules`
packages use their own map. Wildcard, recursive, and external-package import
@@ -35,7 +41,9 @@ the complete application Evidence inline when it fits.
When the connected schema advertises `max_heap_mb` and `analysis_timeout_ms`,
these select the isolated source analyzer's old-space heap and per-source
deadline. Defaults are 1024 MiB and 300000 ms. They do not change the MCP
process heap. A Bun-hosted REA does not enforce the heap choice; on Windows it
process heap or the client's tool deadline. For a host timeout without REA
output, use the [deadline recovery guide](connection-and-recovery.md#distinguish-client-and-server-deadlines)
instead of raising the server budget. A Bun-hosted REA does not enforce the heap choice; on Windows it
instead limits the analyzer's committed memory to that choice plus a 512 MiB
runtime reserve.
Resource-limited analyses preserve completed static facts and
@@ -1,5 +1,48 @@
# Native, managed, and packaged artifacts
For release comparisons, export `list_procedures` Evidence from each target before
closing it. Close clears session records: import both bundles after collecting the
two targets, or supply portable inline Evidence. `match_native_functions` pairs unique exact names and, when supplied,
complete observed body bytes. Reuse optional same-context `list_names`,
`procedure_info`, `read_bytes` and existing `analyze_function` Evidence; avoid
decompiling every function merely to match it. Its summary retains a parent for
`inspect_analysis_view` `function-matches` collections `matches` and `functions`.
Select columns, batch IDs and page individual facts; aliases remain unresolved.
Unpaired observations do not prove additions/removals. Existing matched dossier
pairs include inputs for `compare_functions`; otherwise analyze just chosen pairs.
## Apple app resources
Use `open_bundle_resources` with the selected app path, then `inspect_plist`,
`decode_interface_builder`, `inspect_asset_catalog`, or `inspect_keyed_archive`.
The resource session reads the app without resolving `CFBundleExecutable` or
starting a deep provider. Preserve `resource_root` provenance, per-resource
hashes where reported, and null executable identity; a directory path is not
an executable digest. Export retained Evidence before closing or switching
roots. Binary analysis snapshots do not apply. Use `open_binary` to switch to
executable analysis, and `close_binary` to release either session kind.
The four matching CLI commands accept the app path directly. For an archive
inside the app, use `inspect-keyed-archive APP_PATH RELATIVE_ARCHIVE_PATH`.
Host requirements for plist and compiled asset/Interface Builder tooling still
apply; a resource-only session does not establish provider availability.
## Desktop installation directories
When an installation directory is supplied and its runtime is unknown, use
`inspect_desktop_application` with its absolute path. Default MCP summary
delivery retains complete Evidence. Read `files`, `omissions`, `candidates`, `components` or
`next_probes` with `inspect_analysis_view` kind `desktop-application`, selecting
exact paths, batched file/omission IDs or families and only needed fields and pages.
Summary `probe_issues` retains counts and bounded previews. Select files with
`has_issues: true` and fields `path`, `read_status`, `issues` to retrieve exact
failures directly; preview text is display data, while `file_id` selects full facts. Preserve source
coverage, read-range identity and unknowns; directory snapshot identity is not
a digest of every file's contents. Component path markers do not establish
runtime presence. For compact CLI output, use
`inspect-desktop-application PATH --detail summary --evidence_output BUNDLE`.
See [desktop installations](https://github.com/morluto/rea/blob/main/docs/desktop-applications.md).
## Go build metadata
Use `inspect_go_binary` for an explicit local ELF, PE or thin Mach-O when the
@@ -11,6 +54,34 @@ unparsed module-text line. A missing record is an unknown, not proof of a
non-Go binary; observed metadata does not authenticate its claims. Function,
source and type recovery remain a separate native-analysis question.
## Model files
Use `inspect_model_artifact` (`inspect-model-artifact PATH`) for local GGUF v2/v3
and safetensors declarations without a model runtime. Header-only mode does not
read weights or establish full-file identity. `hash: "full"` explicitly streams
all bytes. Retained `model-artifact` views page `metadata`, `tensors` and derived
`types`, with exact batch filters and selected fields. Arrays retain typed counts
and eight-element previews; omitted values, unknown types and runtime behavior
stay explicit. See [model files](https://github.com/morluto/rea/blob/main/docs/model-artifacts.md).
## IL2CPP metadata
Use `inspect_il2cpp_metadata` for an explicit local Unity `global-metadata.dat`
(versions 24, 27, 29, 31 and 39) when the question concerns assembly images,
names, member owners, string literals, namespaces or index ranges. No `open_binary`, Unity installation or target
execution is required. The CLI equivalent is `inspect-il2cpp-metadata PATH`.
MCP defaults to counts with complete retained Evidence. Query `sections`,
`images`, `types`, `methods`, `fields`, `properties`, `events`, `parameters` or
`string_literals` through `inspect_analysis_view`; use exact names,
batch indices and selected fields. Row indices are scoped by artifact SHA-256
and collection; page offsets count filtered matches. Parameters support batch
`method_indices` to read one method's parameters directly. Historical reports
without member collections retain unknown counts rather than empty inventories. Preserve
artifact SHA-256 and index widths. Unrecognized magic may mean encryption and
is unsupported, not decrypted. Linking names to `GameAssembly` or
`UnityFramework` code addresses remains a separate native-analysis question.
See [IL2CPP metadata](https://github.com/morluto/rea/blob/main/docs/il2cpp-metadata.md).
## Rust dependency metadata
Use `inspect_rust_binary` for an explicit local ELF, PE, or thin Mach-O when
@@ -124,6 +195,36 @@ operation's full ordered list. Candidate capabilities describe possible
providers. Top-level session capabilities describe the current route, and
`analysis_provider_binding` identifies the selected provider.
## Ghidra startup deadline recovery
`provider_timeout` during the first Ghidra query can cover import, auto-analysis,
bridge startup, and readiness. The default 330,000 ms is configurable through
`REA_GHIDRA_STARTUP_TIMEOUT_MS`; a smaller query still needs the same cold import.
Preserve useful Evidence before closing the session or restarting REA. Check
`close_binary` and resolve reported cleanup failures. Set a larger startup budget
in the environment that launches REA, then restart REA and reconnect the MCP
client before reopening the same target. Closing and reopening a binary in the
existing server keeps its original configuration and starts import again.
Environment changes in an agent's shell do not update an already running MCP
server. If its launch configuration cannot be changed, report that constraint
and the exact retry setting instead of claiming a fixed technical limit.
The client's tool-call deadline must allow startup plus the requested query;
server settings and progress notifications cannot override it. CLI analysis
avoids the MCP client deadline, but retains the provider deadline. For example:
```sh
REA_GHIDRA_STARTUP_TIMEOUT_MS=1800000 rea analyze /absolute/path/to/app.exe --provider ghidra --json
```
Thirty minutes is an example budget, not a completion guarantee. Keep host CPU
and memory controls in place. Disable specific expensive analyzers only when
their missing coverage is acceptable and retain the resulting limitations.
Exported C and embedded resources remain useful independent evidence, but a
timeout does not establish complete analysis or absence of code. See the
[deadline and client guide](https://github.com/morluto/rea/blob/main/docs/mcp-contracts.md#ghidra-first-query-deadlines-and-recovery).
## Static memory and original file bytes
For Ghidra, `read_bytes` reads initialized analysis memory, including loader
@@ -244,8 +345,8 @@ every executable in the bundle. It also lists missing or weak loads and earlier
`architecture`. System paths stay undetermined because the dyld shared cache
provides them.
Use `extract_artifact` when materialized files are needed. It extracts the active
target and accepts optional `integrity_policy`; see the [MCP contracts](https://github.com/morluto/rea/blob/main/docs/mcp-contracts.md).
Use `extract_artifact` when materialized files from a supported format are needed.
It extracts the active target and accepts optional `integrity_policy`; see the [MCP contracts](https://github.com/morluto/rea/blob/main/docs/mcp-contracts.md).
It materializes all regular files into a fresh temporary directory chosen by
REA. Symlinks and encrypted entries are inventory facts, not extractable files.
The result reports the materialized directory; callers do not choose the
@@ -254,8 +355,11 @@ destination. No separate permission grant is needed.
Native DMG traversal automatically uses a read-only mount on supported macOS
hosts, with an owned temporary mount directory and cleanup. It needs no approval
flag. Unsupported hosts or mount failures remain explicit limitations; do not
claim child inventory when only root identity is available. Extraction is a
separate filesystem-writing operation.
claim child inventory when only root identity is available. DMG extraction is
unavailable through `extract_artifact`. To access DMG files on macOS, create a
read-only mount with your own tools, select files from that mount for analysis,
and detach the mount you created when finished. REA's inspection mount is
temporary, not a retained export of the image's contents.
For headerless DOS COM, explicitly open with `format: "dos-com"` (CLI
`--target-format dos-com`). Inspect the load image before trusting function
@@ -295,3 +399,22 @@ with two complete inspection Evidence records (or current-session retained
references) and explicit scope. Preserve unknown types/duplicate names; static
interface equality is not runtime compatibility. CLI accepts complete inline
Evidence in `rea compare-wasm-interfaces input.json --json`.
## Godot PCK
For a standalone PCK, `open_binary` then `inspect_artifact` with
`detail: "summary"` retains the complete static inventory. Use the returned
`parent_evidence_id` with `inspect_analysis_view` inventory occurrences filtered
by exact `logical_paths` or `occurrence_ids`, and join `artifact_id` to nodes
filtered by `artifact_ids`. Select only needed fields; identity links remain.
Prefer `inspect-artifact --detail summary --evidence_output PATH` for CLI tasks;
the same CLI discovers embedded packs via their EOF trailer without opening a
native analysis provider. Normal native opening remains unchanged.
Distinguish declared MD5 from observed SHA-256 and graph/page completeness from
`source_coverage`. Encrypted directories and sparse bundles have unknown entry
coverage; encrypted members have unknown content identity. An empty filtered
page cannot prove absence in unknown coverage. Retained views are historical,
not fresh filesystem checks. No decryption, Godot resource decoding, GDScript
decompilation or target execution is provided. See
[Godot PCK](https://github.com/morluto/rea/blob/main/docs/godot-pck.md).
@@ -69,6 +69,12 @@ with `inspect_analysis_view` and `view: {kind: "capture", detail: "preview", off
Select complete record pages only for needed headers, metadata or payloads; views
read the historical parent without repeating capture decoding.
For selected protobuf/gRPC bodies, keep raw bytes as the source and use
`inspect_analysis_view` kind `protobuf`, collection `bodies`, `frames` or
`fields`. Batch exact record ordinals and field numbers/IDs, and select
`schema_value` or `text` only when needed. Supply a local descriptor set and
message type for schema interpretation; compressed payloads remain unknown.
Inspect native `.saz` snapshots with `inspect_web_network_capture` and
`format: "saz"`; encrypted archives are unsupported. For live
traffic analysis, connect Everywhere's separate MCP server and use its
+13 -3
View File
@@ -1,5 +1,10 @@
name: Cache npm package downloads
description: Restore npm's download cache and save it only from trusted default-branch events.
description: Restore npm's download cache. Trusted default-branch jobs that opt in may save it.
inputs:
save:
description: Save the shared download cache when this event is allowed to write it.
required: false
default: "false"
outputs:
can-save:
description: Whether this run may update the shared npm download cache.
@@ -23,20 +28,25 @@ runs:
can_save=true
fi
cache_key="npm-download-${RUNNER_OS}-${runtime_arch}-${LOCKFILES_HASH}"
# Same platform only. A lockfile change can reuse tarballs from the previous key.
restore_key="npm-download-${RUNNER_OS}-${runtime_arch}-"
{
printf 'can-save=%s\n' "${can_save}"
printf 'path=%s\n' "${cache_path}"
printf 'key=%s\n' "${cache_key}"
printf 'restore-key=%s\n' "${restore_key}"
} >> "${GITHUB_OUTPUT}"
- name: Restore and save npm package downloads
if: steps.context.outputs.can-save == 'true'
if: steps.context.outputs.can-save == 'true' && inputs.save == 'true'
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ steps.context.outputs.path }}
key: ${{ steps.context.outputs.key }}
restore-keys: ${{ steps.context.outputs.restore-key }}
- name: Restore npm package downloads without saving
if: steps.context.outputs.can-save != 'true'
if: steps.context.outputs.can-save != 'true' || inputs.save != 'true'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ${{ steps.context.outputs.path }}
key: ${{ steps.context.outputs.key }}
restore-keys: ${{ steps.context.outputs.restore-key }}
+64
View File
@@ -0,0 +1,64 @@
name: Cache retention
on:
workflow_run:
workflows: ["CI"]
types: [completed]
# Qualification calls ci.yml with actions: read. A nested workflow cannot raise
# that token, so cache deletion stays in this workflow.
permissions:
contents: read
actions: write
concurrency:
group: cache-retention-${{ github.event.workflow_run.head_sha }}
cancel-in-progress: false
jobs:
retain:
name: Retain Turbo snapshots and npm download caches
# Restrict the triggering-source checkout to same-repository default-branch
# CI events. The helper runs from this trusted workflow revision; triggering
# source is used only for cache identity and is never executed. Static and
# build save snapshots before later lanes finish, so failed, timed-out, or
# cancelled runs still retain those snapshots.
if: >-
(github.event.workflow_run.conclusion == 'success' ||
github.event.workflow_run.conclusion == 'failure' ||
github.event.workflow_run.conclusion == 'timed_out' ||
github.event.workflow_run.conclusion == 'cancelled') &&
github.event.workflow_run.head_repository.full_name == github.repository &&
github.event.workflow_run.head_branch == github.event.repository.default_branch &&
(github.event.workflow_run.event == 'push' ||
github.event.workflow_run.event == 'schedule' ||
github.event.workflow_run.event == 'workflow_dispatch')
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
ref: ${{ github.workflow_sha }}
path: trusted-retention
persist-credentials: false
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
ref: ${{ github.event.workflow_run.head_sha }}
path: triggering-source
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: trusted-retention/.nvmrc
- name: Retain current Turbo snapshots and npm download caches
env:
GH_TOKEN: ${{ github.token }}
CI_REPOSITORY: ${{ github.repository }}
CACHE_PREFIX: rea-static-v1-${{ runner.os }}-${{ runner.arch }}-
CACHE_KEEP_KEY: rea-static-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('triggering-source/.nvmrc', 'triggering-source/.npmrc', 'triggering-source/package-lock.json') }}-${{ github.event.workflow_run.head_sha }}
CACHE_DEEP_PREFIX: rea-static-deep-v1-${{ runner.os }}-${{ runner.arch }}-
CACHE_DEEP_KEEP_KEY: rea-static-deep-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('triggering-source/.nvmrc', 'triggering-source/.npmrc', 'triggering-source/package-lock.json') }}-${{ github.event.workflow_run.head_sha }}
CACHE_KNIP_PREFIX: knip-meta-v1-${{ runner.os }}-
CACHE_KNIP_KEEP_KEY: knip-meta-v1-${{ runner.os }}-${{ hashFiles('triggering-source/knip.json', 'triggering-source/tsconfig.json', 'triggering-source/package.json', 'triggering-source/package-lock.json') }}-${{ github.event.workflow_run.head_sha }}
CACHE_PORTABLE_PREFIX: rea-portable-build-v2-${{ runner.os }}-${{ runner.arch }}-
DEDUPE_NPM_DOWNLOADS: "true"
run: node trusted-retention/scripts/ci/cache-retention.mjs
+172 -16
View File
@@ -15,6 +15,15 @@ on:
description: Exact qualification source; must match the caller revision.
required: true
type: string
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted release qualification passes it.
required: false
permissions:
contents: read
@@ -29,6 +38,15 @@ concurrency:
env:
HUSKY: "0"
# Set Actions secret TURBO_TOKEN and variable TURBO_TEAM. OIDC can mint
# TURBO_TOKEN via vercel/setup-turborepo-remote-cache-action; do not commit a token.
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Release qualification sets remote_cache_write and passes the
# token. Open pull requests get an empty token and the local cache only.
# Remote reads need a credential, and pull requests do not receive one.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
jobs:
changes:
@@ -59,6 +77,7 @@ jobs:
web_network: ${{ steps.plan.outputs.web_network }}
web_runtime: ${{ steps.plan.outputs.web_runtime }}
web_source_map: ${{ steps.plan.outputs.web_source_map }}
agentenv: ${{ steps.plan.outputs.agentenv }}
nativeaot: ${{ steps.plan.outputs.nativeaot }}
ghidra_bridge: ${{ steps.plan.outputs.ghidra_bridge }}
website: ${{ steps.plan.outputs.website }}
@@ -127,6 +146,9 @@ jobs:
- name: Cache npm package downloads
id: npm-cache
uses: ./.github/actions/npm-cache
with:
# Linux x64 writer. Parallel Linux jobs restore this key.
save: "true"
- run: npm ci
- name: Restore static task cache
if: needs.changes.outputs.code == 'true'
@@ -150,14 +172,10 @@ jobs:
if: needs.changes.outputs.code == 'true'
env:
CI_PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
CI_STATIC_CONTEXT_SCRIPT: check:ci:fast:tasks
run: npm run ci:static-context
- if: needs.changes.outputs.code == 'true'
run: npm run check:ci
- if: needs.changes.outputs.code == 'true'
run: npm run verify:test-discovery
- name: Check LLDB producer retention and launch contracts
if: needs.changes.outputs.code == 'true'
run: npm run test:python
run: npm run check:ci:fast
- if: needs.changes.outputs.code != 'true'
run: npm run format:check
- name: Save validated static task cache
@@ -179,6 +197,72 @@ jobs:
if-no-files-found: ignore
retention-days: 7
static-deep:
name: Deep static checks
needs: changes
# Full qualification only. Provider lanes wait on fast static, not this job.
if: needs.changes.outputs.tier == 'full' && needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: .nvmrc
- name: Cache npm package downloads
id: npm-cache
uses: ./.github/actions/npm-cache
- run: npm ci
- name: Restore deep static task cache
id: static-cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .turbo/cache/
key: rea-static-deep-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.nvmrc', '.npmrc', 'package-lock.json') }}-${{ github.sha }}
restore-keys: rea-static-deep-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.nvmrc', '.npmrc', 'package-lock.json') }}-
- name: Restore Knip analysis cache
id: knip-cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: node_modules/.cache/knip
# Each trusted commit publishes a new entry. Restore still matches the
# configuration prefix from the previous successful full run.
key: knip-meta-v1-${{ runner.os }}-${{ hashFiles('knip.json', 'tsconfig.json', 'package.json', 'package-lock.json') }}-${{ github.sha }}
restore-keys: knip-meta-v1-${{ runner.os }}-${{ hashFiles('knip.json', 'tsconfig.json', 'package.json', 'package-lock.json') }}-
- name: Record deep static task source and execution identity
continue-on-error: true
env:
CI_PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
CI_STATIC_CONTEXT_SCRIPT: check:ci:deep:tasks
run: npm run ci:static-context
- name: Run deep static checks
run: npm run check:ci:deep
- name: Save validated deep static task cache
if: >-
success() && steps.npm-cache.outputs.can-save == 'true' &&
steps.static-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .turbo/cache/
key: ${{ steps.static-cache.outputs.cache-primary-key }}
- name: Save Knip analysis cache
if: >-
success() && steps.npm-cache.outputs.can-save == 'true' &&
steps.knip-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: node_modules/.cache/knip
key: ${{ steps.knip-cache.outputs.cache-primary-key }}
- name: Upload complete deep static diagnostics
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: static-deep-check-reports
path: .cache/static-checks/
include-hidden-files: true
if-no-files-found: ignore
retention-days: 7
test-source:
name: Source tests
needs: changes
@@ -218,9 +302,11 @@ jobs:
# every shard's diagnostics and coverage. Passing PRs run the full suite.
fail-fast: ${{ github.event_name == 'pull_request' && needs.changes.outputs.tier == 'fast' }}
matrix:
# Fast feedback spends the same six test jobs on one source group and
# five built groups; full qualification retains six complete shards.
shard: ${{ fromJSON(needs.changes.outputs.tier == 'fast' && '["1/5","2/5","3/5","4/5","5/5"]' || '["1/6","2/6","3/6","4/6","5/6","6/6"]') }}
# Fast feedback uses one source group and eight built groups so the
# slowest built shard job stays inside a ten-minute execution budget.
# Classification, build, and report merge sit outside that job.
# Full qualification retains six complete shards with coverage.
shard: ${{ fromJSON(needs.changes.outputs.tier == 'fast' && '["1/8","2/8","3/8","4/8","5/8","6/8","7/8","8/8"]' || '["1/6","2/6","3/6","4/6","5/6","6/6"]') }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
@@ -302,7 +388,8 @@ jobs:
needs.changes.outputs.recorded_crash == 'true' ||
needs.changes.outputs.web_network == 'true' ||
needs.changes.outputs.web_runtime == 'true' ||
needs.changes.outputs.web_source_map == 'true'
needs.changes.outputs.web_source_map == 'true' ||
needs.changes.outputs.agentenv == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
@@ -322,7 +409,9 @@ jobs:
with:
save: ${{ github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
- run: npm run test:prepare
- name: Find available trusted full-suite timing history
# Fast and full shards measure different file costs. Download only the
# matching history so one tier cannot pack the other with its weights.
- name: Find available trusted timing history
id: history
continue-on-error: true
env:
@@ -330,13 +419,14 @@ jobs:
CI_REPOSITORY: ${{ github.repository }}
CI_REPOSITORY_ID: ${{ github.repository_id }}
CI_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
CI_TIMING_TIER: ${{ needs.changes.outputs.tier }}
run: node scripts/ci/test-history.mjs
- name: Download previous timing report
if: steps.history.outputs.run-id != ''
continue-on-error: true
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: test-timings
name: ${{ steps.history.outputs.artifact-name }}
run-id: ${{ steps.history.outputs.run-id }}
github-token: ${{ github.token }}
path: .cache/ci-test-history
@@ -371,8 +461,9 @@ jobs:
retention-days: 7
sqlite-runtime:
# Preserve all selected coverage, but admit expensive host/provider work
# only after static validation. Portable tests still provide early feedback.
# Admit expensive host/provider work after fast static validation
# (typecheck, lint, format). Deep static does not gate these lanes.
# Portable tests still provide early feedback.
needs: [changes, static, build]
if: needs.changes.outputs.sqlite == 'true'
uses: ./.github/workflows/sqlite-runtime.yml
@@ -467,11 +558,22 @@ jobs:
include-hidden-files: true
if-no-files-found: error
retention-days: 30
# Default-branch runs only. Pull-request artifacts share this name and
# the lookup reads one page, so publishing them would hide main.
- name: Publish successful timing history
if: needs.changes.outputs.code == 'true' && needs.changes.outputs.tier == 'full' && success() && needs.test-shard.result == 'success'
if: >-
success() &&
needs.changes.outputs.code == 'true' &&
needs.test-shard.result == 'success' &&
(
needs.changes.outputs.tier == 'full' ||
(needs.changes.outputs.tier == 'fast' && needs.test-source.result == 'success')
) &&
github.ref == format('refs/heads/{0}', github.event.repository.default_branch) &&
(github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: test-timings
name: test-timings-${{ needs.changes.outputs.tier }}
path: .cache/ci-test-history/test-results.json
include-hidden-files: true
if-no-files-found: error
@@ -575,6 +677,9 @@ jobs:
- name: Cache npm package downloads
id: npm-cache
uses: ./.github/actions/npm-cache
with:
# ubuntu-latest is the Linux x64 writer above. Other hosts save their own key.
save: ${{ matrix.os != 'ubuntu-latest' }}
- name: Verify native runtime identity
env:
EXPECTED_CI_PLATFORM: ${{ matrix.platform }}
@@ -711,7 +816,14 @@ jobs:
- name: Cache npm package downloads
id: npm-cache
uses: ./.github/actions/npm-cache
with:
save: "true"
- run: npm ci
- name: Typecheck with the official Windows compiler
env:
GOMAXPROCS: "2"
GOMEMLIMIT: "3GiB"
run: npm run typecheck -- --checkers 2
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: rea-build-cache
@@ -742,12 +854,19 @@ jobs:
npx vitest run --coverage.enabled=false
src/process/capture/FilesystemSnapshot.test.ts
tests/process-global/filesystemSnapshotFallbackCancellation.test.ts
tests/boundary/filesystem/typescriptCompiler.test.ts
tests/boundary/filesystem/binaryTarget.test.ts
src/contracts/sessionPathInputs.test.ts
tests/boundary/filesystem/directAnalysisSnapshotReplay.test.ts
tests/boundary/mcp/rawBinaryMcp.test.ts
tests/boundary/filesystem/safeOutputTree.test.ts
tests/boundary/providers/native/artifactProvider.archiveSafety.test.ts
tests/boundary/providers/native/artifactProvider.extractionCompleteness.test.ts
tests/boundary/filesystem/setupUnavailableProvider.test.ts
tests/boundary/filesystem/windowsNpxRegistration.test.ts
tests/boundary/filesystem/clientConfigurationEnvironment.test.ts
tests/boundary/filesystem/clientConfigurationLayeredEnvironment.test.ts
tests/acceptance/setup/registrationRuntimeEnvironmentCli.test.ts
tests/boundary/android/workspaceGuardianRetry.test.ts
tests/acceptance/setup/homeDirectoryFallback.test.ts
tests/boundary/filesystem/javascriptApplicationWorkflows.test.ts
@@ -853,61 +972,96 @@ jobs:
skills/reverse-engineer-anything
if-no-files-found: error
# Provider lanes wait for fast static and the portable build, not deep static.
browser:
needs: [changes, static, build]
if: needs.changes.outputs.browser == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-browser.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
binary_layout:
needs: [changes, static, build]
if: needs.changes.outputs.binary_layout == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-binary-layout.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
evm:
needs: [changes, static, build]
if: needs.changes.outputs.evm == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-evm-interface.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
javascript_recovery:
needs: [changes, static, build]
if: needs.changes.outputs.javascript_recovery == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-javascript-recovery.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
recorded_crash:
needs: [changes, static, build]
if: needs.changes.outputs.recorded_crash == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-recorded-crash.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
web_network:
needs: [changes, static, build]
if: needs.changes.outputs.web_network == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-web-network-captures.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
web_runtime:
needs: [changes, static, build]
if: needs.changes.outputs.web_runtime == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-web-runtime.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
web_source_map:
needs: [changes, static, build]
if: needs.changes.outputs.web_source_map == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-web-source-map.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
agentenv:
needs: [changes, static, build]
if: needs.changes.outputs.agentenv == 'true'
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
uses: ./.github/workflows/real-agentenv.yml
with:
build_cache_artifact: rea-build-cache
remote_cache_write: ${{ inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')) }}
nativeaot:
needs: [changes, static]
@@ -932,6 +1086,7 @@ jobs:
[
changes,
static,
static-deep,
build,
reverse-tools-quality,
test-shard,
@@ -953,6 +1108,7 @@ jobs:
web_network,
web_runtime,
web_source_map,
agentenv,
nativeaot,
ghidra_bridge,
website,
+5
View File
@@ -14,6 +14,11 @@ concurrency:
env:
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
jobs:
mutation:
+98
View File
@@ -0,0 +1,98 @@
name: Real agentenv environment bundle
on:
workflow_dispatch:
workflow_call:
inputs:
build_cache_artifact:
description: Portable build cache artifact from the calling CI run.
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
permissions:
contents: read
env:
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
NODE_OPTIONS: --max-old-space-size=768
PIP_DISABLE_PIP_VERSION_CHECK: "1"
jobs:
real-agentenv:
name: Export and run an environment bundle with the agentenv runner
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: .nvmrc
- name: Cache npm package downloads
id: npm-cache
uses: ./.github/actions/npm-cache
- run: npm ci
- uses: ./.github/actions/portable-build-cache
with:
build_cache_artifact: ${{ inputs.build_cache_artifact }}
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
# Public ECR caps anonymous pulls by data per source IP and hosted runners share IPs, so the
# framework's image builds can fail here for hours. mirror.gcr.io serves the same Docker
# official images under the same digests, so each base image the pinned framework builds from
# is pulled there and named as its Dockerfile names it, as the framework's own CI does.
# Digest-pinned names are set in containerd, whose images Docker reads only on the containerd
# image store; switching stores restarts dockerd, so it happens before anything uses Docker.
- name: Use the containerd image store
run: |
[ -s /etc/docker/daemon.json ] || echo '{}' | sudo tee /etc/docker/daemon.json >/dev/null
jq '.features["containerd-snapshotter"] = true' /etc/docker/daemon.json > "$RUNNER_TEMP/daemon.json"
sudo mv "$RUNNER_TEMP/daemon.json" /etc/docker/daemon.json
sudo systemctl restart docker
docker info --format '{{json .DriverStatus}}' | grep -q io.containerd.snapshotter
- name: Acquire the pinned agentenv runner in isolated runner storage and check host Docker
shell: bash
run: |
runner_root="${RUNNER_TEMP}/rea-agentenv-runner"
python -m venv "${runner_root}"
"${runner_root}/bin/python" -m pip install --require-virtualenv --no-cache-dir 'agentenv-framework==0.9.1334'
"${runner_root}/bin/agent-env" --version
docker version --format '{{.Server.Version}}'
echo "REA_AGENT_ENV_COMMAND=${runner_root}/bin/agent-env" >> "${GITHUB_ENV}"
echo "REA_DOCKER_COMMAND=$(command -v docker)" >> "${GITHUB_ENV}"
- name: Pull the pinned framework's public ECR base images from mirror.gcr.io
shell: bash
run: |
package="$("${REA_AGENT_ENV_COMMAND%/agent-env}/python" -c 'import agent_env, pathlib; print(pathlib.Path(agent_env.__file__).parent)')"
grep -rhoE '^FROM +public\.ecr\.aws/docker/library/[^ ]+' --include='Dockerfile*' "${package}" | awk '{print $2}' | sort -u |
while read -r image; do
name=${image#public.ecr.aws/docker/library/}
source=mirror.gcr.io/library/$name
case $name in *@*) source=mirror.gcr.io/library/${name%%[:@]*}@${name#*@} ;; esac
for attempt in 1 2 3; do
docker pull --quiet "$source" && break
if [ "$attempt" = 3 ]; then echo "::warning::couldn't pull $source; $image's build will pull it"; continue 2; fi
sleep $((attempt * 10))
done
case ${name%@*} in *:*) docker tag "$source" "${image%@*}" ;; esac
case $image in *@*) sudo ctr --namespace moby images tag "$source" "$image" >/dev/null ;; esac
done
- name: Export a bundle from the source-owned capture and run it with the agentenv runner
run: npm run verify:agentenv:environment
+16
View File
@@ -14,6 +14,15 @@ on:
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
permissions:
contents: read
@@ -21,6 +30,13 @@ permissions:
env:
NODE_OPTIONS: --max-old-space-size=768
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
REA_VERIFY_LARGE_ELF_MCP: ${{ inputs.large_mcp && '1' || '0' }}
jobs:
+16
View File
@@ -8,10 +8,26 @@ on:
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
workflow_dispatch:
env:
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
permissions:
contents: read
+8
View File
@@ -8,6 +8,14 @@ on:
permissions:
contents: read
env:
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
jobs:
windows-native-artifact:
name: Build Windows bridge security boundary
+16
View File
@@ -9,6 +9,15 @@ on:
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
permissions:
contents: read
@@ -16,6 +25,13 @@ permissions:
env:
NODE_OPTIONS: --max-old-space-size=768
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
jobs:
real-evm-interface:
@@ -6,6 +6,11 @@ on:
env:
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
permissions:
contents: read
+5 -12
View File
@@ -13,20 +13,8 @@ on:
- "src/composition/go.ts"
- "src/cli/goCommands.ts"
- "src/server/registerGoTools.ts"
- "src/server/createServer.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/artifacts/readStableArtifact*.ts"
- "src/artifacts/ArtifactReader.ts"
- "src/process/PrivateRuntimeRoot.ts"
- "scripts/verify-go-binary.mjs"
- "scripts/lib/mcp-verifier-results.mjs"
- "scripts/rea.mjs"
- "package.json"
- "package-lock.json"
- ".nvmrc"
permissions:
contents: read
@@ -38,6 +26,11 @@ concurrency:
env:
NODE_OPTIONS: --max-old-space-size=768
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
jobs:
real-go-binary:
+5
View File
@@ -5,6 +5,11 @@ on:
env:
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
permissions:
contents: read
+5
View File
@@ -5,6 +5,11 @@ on:
env:
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
permissions:
contents: read
@@ -8,6 +8,15 @@ on:
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
workflow_dispatch:
permissions:
@@ -15,6 +24,13 @@ permissions:
env:
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
NODE_OPTIONS: "--max-old-space-size=768"
RAYON_NUM_THREADS: "1"
+7 -11
View File
@@ -20,21 +20,17 @@ on:
- "src/composition/captures.ts"
- "src/cli/captureCommands.ts"
- "src/server/registerCaptureTools.ts"
- "src/server/createServer.ts"
- "src/server/sessionAvailabilityPolicy.ts"
- "src/application/CapabilityInventory.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/process/**"
- "src/artifacts/readStableArtifact.ts"
- "scripts/verify-packet-capture.mjs"
- ".github/workflows/real-packet-capture.yml"
- "package*.json"
- ".nvmrc"
permissions:
contents: read
env:
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
concurrency:
group: real-packet-capture-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
+16
View File
@@ -9,6 +9,15 @@ on:
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
permissions:
contents: read
@@ -16,6 +25,13 @@ permissions:
env:
NODE_OPTIONS: --max-old-space-size=768
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
UV_CONCURRENT_BUILDS: "1"
UV_CONCURRENT_INSTALLS: "1"
UV_PYTHON_DOWNLOADS: never
+7 -11
View File
@@ -13,21 +13,17 @@ on:
- "src/composition/signals.ts"
- "src/cli/signalCommands.ts"
- "src/server/registerSignalTools.ts"
- "src/server/createServer.ts"
- "src/server/sessionAvailabilityPolicy.ts"
- "src/application/CapabilityInventory.ts"
- "src/contracts/toolContracts.ts"
- "src/contracts/toolEffects.ts"
- "src/cli.ts"
- "src/cliCommandNames.ts"
- "src/process/**"
- "src/artifacts/readStableArtifact.ts"
- "scripts/verify-signal-recording.mjs"
- ".github/workflows/real-signal-recording.yml"
- "package*.json"
- ".nvmrc"
permissions:
contents: read
env:
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
concurrency:
group: real-signal-recording-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
+5
View File
@@ -12,6 +12,11 @@ permissions:
env:
HUSKY: "0"
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
jobs:
real-termux:
@@ -9,12 +9,28 @@ on:
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
permissions:
contents: read
env:
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
NODE_OPTIONS: --max-old-space-size=768
jobs:
+16
View File
@@ -7,11 +7,27 @@ on:
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
workflow_dispatch:
permissions:
contents: read
env:
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
jobs:
real-web-runtime:
runs-on: ubuntu-latest
+16
View File
@@ -7,11 +7,27 @@ on:
required: false
type: string
default: ""
remote_cache_write:
description: Trusted release qualification may publish the remote cache.
required: false
type: boolean
default: false
secrets:
TURBO_TOKEN:
description: Remote cache token. Only trusted callers pass it.
required: false
workflow_dispatch:
permissions:
contents: read
env:
HUSKY: "0"
# A called workflow sees the caller event, so workflow_call is not an event
# name here. Writes when remote_cache_write is set, or on the default branch
# for push, schedule, and manual dispatch. Open pull requests stay empty-token
# and use the local cache only.
TURBO_TOKEN: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (inputs.remote_cache_write == true || (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'))) && 'local:rw,remote:rw' || 'local:rw' }}"
jobs:
real-web-source-map:
runs-on: ubuntu-latest
+9
View File
@@ -21,6 +21,12 @@ on:
env:
HUSKY: "0"
# Remote cache stays local when either value is empty.
# Writes only on the default branch for push, schedule, manual dispatch,
# and workflow_call. Pull requests get an empty token and remote read-only mode.
TURBO_TOKEN: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && secrets.TURBO_TOKEN || '' }}"
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
TURBO_CACHE: "${{ (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call')) && 'local:rw,remote:rw' || 'local:rw,remote:r' }}"
concurrency:
group: release-${{ inputs.release_branch || github.event.pull_request.merge_commit_sha || github.ref_name }}
@@ -301,8 +307,11 @@ jobs:
contents: read
actions: read
uses: ./.github/workflows/ci.yml
secrets:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
with:
source_sha: ${{ needs.merged-release.outputs.sha || needs.release-please.outputs.sha }}
remote_cache_write: true
rehearsal:
name: Rehearse qualified release on a clean runner
+37 -25
View File
@@ -90,6 +90,12 @@ Setup supports Claude Code, Codex, Cursor, Gemini CLI, Grok Build and
[installation and setup](docs/installation.md) for provider configuration and
manual MCP registration.
MCP uses compact input schemas by default to reduce context overhead. Set
`REA_MCP_INPUT_SCHEMA_PROFILE=full` in your MCP registration when you need the
complete advertised field guidance and nested validation details. Both profiles
keep the full tool set and canonical server validation. See
"Compact input schema profile" in the MCP contracts guide.
### Ask your agent
```text
@@ -174,31 +180,37 @@ CLI commands use the same workflows.
REA requires Node.js 22.x (>=22.19), 24.x (>=24.11), or 26+, plus npm.
Additional tools and host support depend on the target:
| Target | What REA returns | Requirements and guide |
| ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](docs/native-investigation.md) |
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
| Go binaries | Embedded compiler version, modules, replacements and build settings | Built-in static ELF/PE/thin Mach-O inspection; no Go installation required |
| 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) |
| WASM artifact | Validation, sections, exact import/export WAT forms and decoded WAT | Caller-supplied WABT 1.0.42; `inspect_wasm_artifact` |
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
| SQLite databases | Tables, columns, indexes, views, triggers and selected ordinary-table rows | Local database/WAL snapshot; Node.js 24.x >=24.15 or 26+ with native SQLite limits |
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; Linux: procps-compatible `ps`; [application analysis](docs/javascript-application-workflows.md) |
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](docs/browser-observation.md) |
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR or Fiddler Everywhere SAZ; mitmdump on Linux for native mitmproxy; [capture guide](docs/web-network-captures.md) |
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | None (static only); [managed-code guide](docs/managed-code-analysis.md) |
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
| Android devices | Devices, packages, processes, logs, dumps, screen captures, and APK/file transfers | Caller-supplied adb (emulator or hardware); [ADB guide](docs/adb-device-analysis.md) |
| JEB projects | Engine-backed project units, artifact digests and type/method pseudo-code | A caller-started JEB client serving MCP, selected with REA_JEB_MCP_URL; [JEB guide](docs/jeb-analysis.md) |
| Android resources | Decoded manifest, string tables, locales and version facts | Caller-supplied Apktool launcher; [resource guide](docs/apktool-resource-analysis.md) |
| Flutter apps | Dart snapshot hash, per-ABI library digests and engine build provenance | None (static APK parsing); [Flutter guide](docs/flutter-analysis.md) |
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
| Recorded packets | Selected fields, repeated values, filters and decode-as rules | Linux: TShark 4.x + prlimit; [capture guide](docs/packet-captures.md) |
| Packet summaries | Endpoints, DNS, TLS SNI, protocol distribution and HTTP requests | Caller-supplied tshark and capinfos (Linux-verified); [pcap guide](docs/pcap-analysis.md) |
| Recorded logic signals | Decoder annotations, sample ranges and diagnostics | Linux: sigrok-cli 0.7.2 + prlimit; [signal recordings](docs/signal-recordings.md) |
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
| Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
| Target | What REA returns | Requirements and guide |
| ----------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Desktop installations | Runtime candidates, supporting files, component markers and next probes | Built-in bounded directory/header inspection; [desktop applications](docs/desktop-applications.md) |
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](docs/native-investigation.md) |
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
| Go binaries | Embedded compiler version, modules, replacements and build settings | Built-in static ELF/PE/thin Mach-O inspection; no Go installation required |
| GPU code objects | CUDA/HIP targets, selected kernel parameters and resources, retained PTX text | Built-in static ELF/PE/fatbin/CUBIN/PTX inspection; [GPU code objects](docs/gpu-code-objects.md) |
| Model artifacts | GGUF / safetensors metadata, tensor declarations and derived totals | Built-in header inspection; optional full-file hash; [model files](docs/model-artifacts.md) |
| IL2CPP metadata | Unity global-metadata.dat assembly images, type and method names and index ranges | Built-in static decoding of versions 24, 27, 29, 31 and 39; no Unity required |
| Godot PCK | Archive inventory and extraction, original header/directory facts and selected content identities | Built-in static formats 2, 3 and 4; no Godot required |
| Rust binaries | Embedded cargo-auditable crate names, versions, sources and dependency edges | Built-in static ELF/PE/thin Mach-O inspection; [Rust binaries](docs/rust-binaries.md) |
| WASM artifact | Validation, sections, exact import/export WAT forms and decoded WAT | Caller-supplied WABT 1.0.42; `inspect_wasm_artifact` |
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier on Linux x64; [offline EVM guide](docs/evm-bytecode.md) |
| SQLite databases | Tables, columns, indexes, views, triggers and selected ordinary-table rows | Local database/WAL snapshot; Node.js 24.x >=24.15 or 26+ with native SQLite limits |
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools on Linux x64; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; Linux: procps-compatible `ps`; [application analysis](docs/javascript-application-workflows.md) |
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](docs/browser-observation.md) |
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR or Fiddler Everywhere SAZ; mitmdump on Linux for native mitmproxy; [capture guide](docs/web-network-captures.md) |
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | None (static only); [managed-code guide](docs/managed-code-analysis.md) |
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
| Android devices | Devices, packages, processes, logs, dumps, screen captures, and APK/file transfers | Caller-supplied adb (emulator or hardware); [ADB guide](docs/adb-device-analysis.md) |
| JEB projects | Engine-backed project units, artifact digests and type/method pseudo-code | A caller-started JEB client serving MCP, selected with REA_JEB_MCP_URL; [JEB guide](docs/jeb-analysis.md) |
| Android resources | Decoded manifest, string tables, locales and version facts | Caller-supplied Apktool launcher; [resource guide](docs/apktool-resource-analysis.md) |
| Flutter apps | Dart snapshot hash, per-ABI library digests and engine build provenance | None (static APK parsing); [Flutter guide](docs/flutter-analysis.md) |
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
| Recorded packets | Selected fields, repeated values, filters and decode-as rules | Linux: TShark 4.x + prlimit; [capture guide](docs/packet-captures.md) |
| Packet summaries | Endpoints, DNS, TLS SNI, protocol distribution and HTTP requests | Caller-supplied tshark and capinfos (Linux-verified); [pcap guide](docs/pcap-analysis.md) |
| Recorded logic signals | Decoder annotations, sample ranges and diagnostics | Linux: sigrok-cli 0.7.2 + prlimit; [signal recordings](docs/signal-recordings.md) |
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
| Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
| PyInstaller executables | CArchive members, Python version, entry scripts and extracted bytecode | None (static only); [Python packaged applications](docs/python-packaged-applications.md) |
Static JavaScript and .NET inspection read the supplied files without running
the application. Runtime capture runs or interacts with the selected target
+44 -16
View File
@@ -458,6 +458,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
FunctionAnalysisObservation observation = analyzeFunctionObservation(request.params);
JsonObject result = functionObservation(observation.dossier(), observation.limitations());
result.add("relationship_coverage", observation.relationshipCoverage());
if (observation.decompilerFailed()) result.addProperty("cache_policy", "live");
yield result;
}
case "set_address_name", "set_addresses_names" -> {
@@ -1540,12 +1541,23 @@ public final class ReaGhidraBridge extends HeadlessScript {
requireKeys(params, Set.of("procedure"));
Function function = resolveProcedure(requireString(params, "procedure"));
InstructionScan scan = scanInstructions(function, Integer.MAX_VALUE);
DecompileResults decompilation = decompile(function);
DecompileResults decompilation;
String decompilerFailure = null;
try {
decompilation = decompile(function);
} catch (RequestFailure failure) {
// The listing, reference and CFG facts below do not depend on the
// native decompiler. Cancellation still ends the request.
if (!failure.code.equals("decompile_failed")) throw failure;
decompilation = null;
decompilerFailure = failure.getMessage().strip();
}
String pseudocode = decompiledText(decompilation);
JsonObject availability = new JsonObject();
availability.add("pseudocode", facetAvailability(
pseudocode != null,
function.isExternal() ? "Ghidra does not decompile external functions."
decompilerFailure != null ? decompilerFailure
: function.isExternal() ? "Ghidra does not decompile external functions."
: function.getBody().isEmpty() ? "Ghidra has no function body to decompile."
: "Ghidra completed decompilation without returning pseudocode."
));
@@ -1594,9 +1606,16 @@ public final class ReaGhidraBridge extends HeadlessScript {
result.add("basic_blocks", blocks);
result.add(
"native_api",
nativeApiBoundary(function, decompilation)
decompilerFailure == null
? nativeApiBoundary(function, decompilation)
: unavailableNativeApiBoundary(decompilerFailure)
);
result.add(
"native_value_flow",
decompilerFailure == null
? nativeValueFlow(decompilation)
: unavailableNativeValueFlow(decompilerFailure)
);
result.add("native_value_flow", nativeValueFlow(decompilation));
// Successful full queries distinguish collected empty sets from missing facts.
// Availability does not claim that Ghidra resolved every runtime relationship.
for (String facet : List.of("comments", "callers", "callees", "references", "strings_names", "cfg")) {
@@ -1643,6 +1662,12 @@ public final class ReaGhidraBridge extends HeadlessScript {
!decompilation.getErrorMessage().isBlank()) {
limitations.add("Ghidra decompiler diagnostic: " + decompilation.getErrorMessage());
}
if (decompilerFailure != null) {
limitations.add(
decompilerFailure + (decompilerFailure.endsWith(".") ? " " : ". ") +
"Pseudocode, the native API boundary and p-code value flow are unavailable for this procedure; assembly, comments, callers, callees, references, strings, names and basic blocks come from the Ghidra program listing and were still collected."
);
}
result.add("limitations", limitations);
monitor.checkCancelled();
int missingCallers = 0;
@@ -1651,25 +1676,16 @@ public final class ReaGhidraBridge extends HeadlessScript {
if (unrepresentedCaller(reference, callerFunctions)) missingCallers++;
}
return new FunctionAnalysisObservation(result, calls.limitations(),
callRelationshipCoverage(calls, missingCallers));
callRelationshipCoverage(calls, missingCallers), decompilerFailure != null);
}
private JsonObject nativeValueFlow(DecompileResults decompilation) throws Exception {
HighFunction highFunction =
decompilation == null ? null : decompilation.getHighFunction();
if (highFunction == null) {
JsonObject unavailable = new JsonObject();
unavailable.addProperty("available", false);
unavailable.addProperty(
"reason",
return unavailableNativeValueFlow(
"Ghidra has no HighFunction p-code model for this procedure"
);
JsonArray limitations = new JsonArray();
limitations.add(
"No p-code operations or def-use relationships were recovered for this procedure."
);
unavailable.add("limitations", limitations);
return unavailable;
}
List<PcodeOpAST> selected = new ArrayList<>();
@@ -2357,6 +2373,18 @@ public final class ReaGhidraBridge extends HeadlessScript {
return result;
}
private static JsonObject unavailableNativeValueFlow(String reason) {
JsonObject unavailable = new JsonObject();
unavailable.addProperty("available", false);
unavailable.addProperty("reason", reason);
JsonArray limitations = new JsonArray();
limitations.add(
"No p-code operations or def-use relationships were recovered for this procedure."
);
unavailable.add("limitations", limitations);
return unavailable;
}
private static JsonObject unavailableNativeApiBoundary(String reason) {
JsonObject unavailable = new JsonObject();
unavailable.addProperty("available", false);
@@ -4875,7 +4903,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
private record InventoryItem(Address address, String value, JsonObject facts) {}
private record AddressNameRequest(String inputAddress, Address address, String name) {}
private record FunctionEntry(Function function, InventoryItem item) {}
private record FunctionAnalysisObservation(JsonObject dossier, List<String> limitations, JsonObject relationshipCoverage) {}
private record FunctionAnalysisObservation(JsonObject dossier, List<String> limitations, JsonObject relationshipCoverage, boolean decompilerFailed) {}
private record CallBoundaryObservation(List<String> limitations, Integer unrepresentedCalleeCalls, JsonArray unresolvedCalls) {}
private record SwiftStringLiteralDecode(JsonArray literals, JsonArray omissions) {}
private record SwiftLiteralLayout(
+53 -23
View File
@@ -236,6 +236,15 @@ def _name_matches(document, address, name):
return observed == name or (not name and observed is None)
def _bookmark_name(document, address):
getter = getattr(document, "getBookmarkName", None)
if not callable(getter):
raise CapabilityUnavailableError(
"Hopper's public Python API does not expose getBookmarkName"
)
return getter(address)
def _address(document, value=None):
"""Keep explicit hexadecimal coordinates distinct from symbol names."""
if value is None:
@@ -431,10 +440,6 @@ def _procedure_map(document):
return result
def _strings(document):
return {address: record["value"] for address, record in _string_inventory(document).items()}
def _string_record(segment, address, display):
"""Read one native typed object, retaining its shortened display separately."""
length = segment.getObjectLength(address)
@@ -521,7 +526,7 @@ def _search_inventory(document, kind):
if kind == "procedure":
values = _procedure_map(document)
elif kind == "string":
values = _strings(document)
values = _string_inventory(document)
elif kind == "name":
values = {_hex(address): value for address, value in _name_map(document).items()}
else:
@@ -548,23 +553,17 @@ def _search_results(document, kind, params):
else:
raise CapabilityUnavailableError("Regex matching requires REA's supervised worker; the native bridge only executes literal searches")
selected = []
for item in _search_inventory(document, kind):
if not matches(item[1]):
continue
selected.append(item)
if not selected:
return []
if kind == "string":
records = _string_inventory(document)
return [{"address": address, **records[address]} for address, _ in selected]
return [
{
"address": address,
"value": value,
}
for address, value in selected
return [
{"address": address, **record}
for address, record in _search_inventory(document, kind)
if matches(record["value"])
]
return [
{"address": address, "value": value}
for address, value in _search_inventory(document, kind)
if matches(value)
]
def _unavailable(reason):
@@ -1004,15 +1003,46 @@ def _dispatch(method, params):
observed = getter(address)
return observed == comment or (comment == "" and observed is None)
if method == "list_bookmarks":
return [{"address": _hex(item), "name": document.getBookmarkName(item)} for item in document.getBookmarks()]
return [{"address": _hex(item), "name": _bookmark_name(document, item)} for item in document.getBookmarks()]
if method == "set_bookmark":
address = _address(document, params.get("address"))
_segment(document, address)
name = params.get("name")
if name is not None:
_api_text(name, "Bookmark name")
document.setBookmarkAtAddress(address, name)
return document.hasBookmarkAtAddress(address)
has_bookmark = getattr(document, "hasBookmarkAtAddress", None)
if not callable(has_bookmark):
raise CapabilityUnavailableError(
"Hopper's public Python API does not expose hasBookmarkAtAddress"
)
exists = has_bookmark(address)
if name is None and exists:
# Omission means preserve the existing bookmark and its name.
return True
if not callable(getattr(document, "getBookmarkName", None)):
raise CapabilityUnavailableError(
"Hopper's public Python API does not expose getBookmarkName"
)
if name == "" and exists:
rename = getattr(document, "renameBookmarkAtAddress", None)
if not callable(rename):
raise CapabilityUnavailableError(
"Hopper's public Python API does not expose renameBookmarkAtAddress"
)
rename(address, name)
else:
setter = getattr(document, "setBookmarkAtAddress", None)
if not callable(setter):
raise CapabilityUnavailableError(
"Hopper's public Python API does not expose setBookmarkAtAddress"
)
setter(address, name)
if not has_bookmark(address):
return False
observed = _bookmark_name(document, address)
if name is None:
return observed is None or observed == ""
return observed == name or (name == "" and observed is None)
if method == "unset_bookmark":
address = _address(document, params.get("address"))
# Permit removing a legacy orphan bookmark, but do not report success
+65 -7
View File
@@ -12,16 +12,29 @@ struct ProcessIdentityObservation: Encodable {
let pid: Int32
let state: String
let identity: String?
let effective_uid: UInt32?
let lifecycle: String?
let relation: ProcessRelationObservation?
let reason: String?
}
private struct ProcessMetadata {
struct ProcessRelationObservation: Encodable {
let state: String
let parent_pid: Int32
let process_group_id: Int32
}
struct ProcessMetadata {
let identity: String
let effectiveUid: UInt32
let lifecycle: String
let parentPid: Int32
let processGroupId: Int32
let pointerSize: Int
}
struct ProcessSnapshot {
fileprivate let metadata: [Int32: ProcessMetadata]
let metadata: [Int32: ProcessMetadata]
let failure: String?
}
@@ -75,6 +88,10 @@ func readProcessSnapshot(
process.kp_proc.p_pid,
ProcessMetadata(
identity: "\(start.tv_sec):\(start.tv_usec)",
effectiveUid: process.kp_eproc.e_ucred.cr_uid,
lifecycle: process.kp_proc.p_stat == SZOMB ? "zombie" : "non-zombie",
parentPid: process.kp_eproc.e_ppid,
processGroupId: process.kp_eproc.e_pgid,
pointerSize: process.kp_proc.p_flag & P_LP64 != 0 ? 8 : 4
)
)
@@ -87,20 +104,61 @@ func readProcessSnapshot(
}
func readProcessIdentities(pids: [Int32]) -> [ProcessIdentityObservation] {
let snapshot = readProcessSnapshot()
readProcessIdentities(pids: pids, snapshot: readProcessSnapshot())
}
func readProcessIdentities(
pids: [Int32],
snapshot: ProcessSnapshot
) -> [ProcessIdentityObservation] {
return pids.map { pid in
guard pid > 0 else {
return unavailableIdentity(pid: pid, reason: "invalid_process_id")
}
guard let metadata = snapshot.metadata[pid] else {
return unavailableIdentity(
if let failure = snapshot.failure {
return unavailableIdentity(pid: pid, reason: failure)
}
// This records absence from this successful KERN_PROC_ALL snapshot only.
// Unlike the Linux procfs path, it has no PID-specific kill(0)
// corroboration; callers must not treat it as universal or future exit
// proof.
return ProcessIdentityObservation(
pid: pid,
reason: snapshot.failure ?? "process_not_in_snapshot"
state: "absent",
identity: nil,
effective_uid: nil,
lifecycle: nil,
relation: nil,
reason: "not-in-snapshot"
)
}
return ProcessIdentityObservation(pid: pid, state: "readable", identity: metadata.identity, reason: nil)
return ProcessIdentityObservation(
pid: pid,
state: "readable",
identity: metadata.identity,
effective_uid: metadata.effectiveUid,
lifecycle: metadata.lifecycle,
relation: ProcessRelationObservation(
state: "observed",
parent_pid: metadata.parentPid,
process_group_id: metadata.processGroupId
),
reason: nil
)
}
}
private func unavailableIdentity(pid: Int32, reason: String) -> ProcessIdentityObservation {
ProcessIdentityObservation(pid: pid, state: "unavailable", identity: nil, reason: reason)
ProcessIdentityObservation(
pid: pid,
state: "unavailable",
identity: nil,
effective_uid: nil,
lifecycle: nil,
relation: nil,
reason: reason
)
}
enum RunTokenReadError: Error {
+1 -1
View File
@@ -95,7 +95,7 @@ def main():
try:
encoded = json.dumps(reply, ensure_ascii=True, allow_nan=False).encode("utf-8")
if len(encoded) > OUTPUT_BYTES:
encoded = json.dumps({"ok": False, "reason": "output-limit", "message": "Complete debugger context exceeds64 MiB reply budget."}).encode("utf-8")
encoded = json.dumps({"ok": False, "reason": "output-limit", "message": "Complete debugger context exceeds the 64 MiB reply budget."}).encode("utf-8")
descriptor = os.open(request["reply_path"], os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
with os.fdopen(descriptor, "wb") as handle:
handle.write(encoded)
+11 -2
View File
@@ -14,7 +14,7 @@ BRIDGE = Path(__file__).with_name("core_context.py")
class CoreContextTests(unittest.TestCase):
def inspect(self, failure=None, connection="core", symbols=None, architecture="x86_64-little-endian"):
def inspect(self, failure=None, connection="core", symbols=None, architecture="x86_64-little-endian", objfile="recorded-executable"):
commands, reads, queries = [], [], []
state = {"executable": None, "symbols": None, "connection": None}
gdb = types.ModuleType("gdb")
@@ -50,7 +50,7 @@ class CoreContextTests(unittest.TestCase):
def maps():
self.assertIsNone(state["executable"], "Helper executable must be discarded before mapping queries")
queries.append("maps")
return [types.SimpleNamespace(start=4096, end=8192, offset=0, flags=5, objfile="recorded-executable")]
return [types.SimpleNamespace(start=4096, end=8192, offset=0, flags=5, objfile=objfile)]
pwndbg.aglib.vmmap.get = maps
modules = {module.__name__: module for module in [
@@ -104,6 +104,15 @@ class CoreContextTests(unittest.TestCase):
self.assertEqual(reads, [])
self.assertEqual(queries, [])
def test_output_limit_message_separates_the_words_and_names_the_limit(self):
result, _, reads, queries = self.inspect(objfile="m" * (64 * 1024 * 1024))
self.assertFalse(result["ok"])
self.assertEqual(result["reason"], "output-limit")
self.assertNotIn("exceeds64", result["message"])
self.assertEqual(result["message"], "Complete debugger context exceeds the 64 MiB reply budget.")
self.assertEqual(reads, [])
self.assertEqual(queries, ["maps"])
def test_wrong_connection_or_remaining_symbols_never_queries_mappings(self):
for options in [{"connection": "native"}, {"symbols": "unexpected-symbols"}]:
with self.subTest(options=options):
+8
View File
@@ -29,6 +29,8 @@ export default defineConfig({
items: [
{ text: "Native binaries", link: "/native-investigation" },
{ text: "Go build metadata", link: "/go-binaries" },
{ text: "IL2CPP metadata", link: "/il2cpp-metadata" },
{ text: "Model artifacts", link: "/model-artifacts" },
{ text: "Rust dependencies", link: "/rust-binaries" },
{
text: "JavaScript and Electron",
@@ -43,12 +45,18 @@ export default defineConfig({
text: "Web network captures",
link: "/web-network-captures",
},
{ text: "Agent environments", link: "/agent-environments" },
{ text: "Electron observation", link: "/electron-observation" },
{ text: "Electron fuses", link: "/electron-fuses" },
{ text: "Process capture", link: "/process-capture" },
{ text: ".NET assemblies", link: "/managed-code-analysis" },
{
text: "Python packaged applications",
link: "/python-packaged-applications",
},
{ text: "Android applications", link: "/android-analysis" },
{ text: "Apple applications", link: "/apple-application-analysis" },
{ text: "Desktop installations", link: "/desktop-applications" },
{ text: "Firmware", link: "/firmware-analysis" },
{ text: "SQLite databases", link: "/sqlite-databases" },
{ text: "Packet captures", link: "/packet-captures" },
+11 -6
View File
@@ -162,8 +162,9 @@ and during shutdown.
APKs keep other names report the `unknown` role rather than guessing.
- **Partial results keep facts.** Failed individual pulls return successful
artifacts with `coverage: "partial"` and per-file `failures`. Listings
that contain unrecognized lines report them as `unparsed_lines` and mark
partial coverage instead of dropping rows.
and package searches that contain unrecognized lines report the first ten
as `unparsed_lines`, state the exact total in a limitation when more were
seen, and mark partial coverage instead of dropping rows.
- **Mutations are explicit.** `push_adb_file`, `install_adb_package`, and
`uninstall_adb_package` declare `mutatesTarget` and never run implicitly:
pushes check for existing device files before transfer and refuse them
@@ -171,7 +172,9 @@ and during shutdown.
transfer even with `overwrite`; only a clean `test -e` exit of 1 with no
output is interpreted as absence. The check is not atomic, so a different
process can create the path before `adb push` writes it. When available, the device's
`sha256sum` verifies the transfer; installs preserve the
`sha256sum` verifies the transfer. A missing command or output without a
recognizable digest reports `device_digest_source: "unavailable"` with an
unverified-transfer limitation; installs preserve the
device's `Failure [...]` reason verbatim.
- **Producer identity stays attached.** Every result embeds the producing
adb client (`binary_path`, `path_source`, `version`, `installed_path`).
@@ -183,9 +186,11 @@ and during shutdown.
The app/activity lifecycle tools use `am start -W` and `am force-stop`.
- Per-invocation budgets: client/devices 10-20 s, shell reads 20-60 s with
64 KiB-8 MiB capture caps (logcat 4 MiB, screen 32 MiB), transfers and
bugreports 600 s. Output capture overflow reports `resource_constraint`;
deadline expiration, including the client-version probe, reports
`provider_timeout`. Command cancellation preserves the caller's exact reason;
bugreports 600 s. Output capture overflow reports `resource_constraint`
and names the byte allowance. Deadline expiration, including the
client-version probe, reports `provider_timeout` and names the effective
milliseconds. This release has no runtime override for those deadlines or
capture caps. Command cancellation preserves the caller's exact reason;
a later abort does not replace an already completed command failure.
- Pull and capture outputs are additive: the destination must not already
exist. Re-running a completed pull refuses the existing directory instead
+700
View File
@@ -0,0 +1,700 @@
# Agent environments from recorded captures
Use `rea environment-serve` to serve an environment manifest as an agent
environment: an MCP server whose tools answer from what one retained web
network capture observed, plus the environment card the agentenv framework
reads to discover it. By default the server derives the
[state the capture observed](#the-state-a-capture-observed) at startup and
answers read tools from it; `--replay-only` replays the capture's records
instead. Nothing is fetched from the recorded application; every answer comes
from retained Evidence. `rea environment-export` writes the same pair as a
bundle folder `agent-env run` builds and runs; see
[Export a bundle](#export-a-bundle).
```sh
rea inspect-web-network-capture /absolute/session.har har --format json > capture.json
rea inspect-analysis-view view.json --format json > manifest.json
rea environment-serve manifest.json --evidence capture.json --port 8765
```
The first command inspects the capture; the second projects the
[environment manifest](web-network-captures.md#environment-manifest) view from
it, where `view.json` wraps the capture Evidence as the inline source:
```json
{
"source": { "kind": "inline", "evidence": { "evidence_id": "ev_…" } },
"view": {
"kind": "environment-manifest",
"template_rules": ["after-uid-literal", "opaque-token", "sibling-variance"]
}
}
```
The third command serves that manifest from the state it derives from the
capture; see [Serve from the state](#serve-from-the-state). Both served files
are complete REA Evidence JSON as the commands write it with `--format json`;
the `evidence` member of `view.json` is the whole of `capture.json`.
## From a browser scenario
The capture can also come from REA itself: a
[browser scenario](browser-scenario-contract.md) records a scripted session
in a browser REA launches, and its Evidence is a manifest parent like a HAR
inspection. Select the `network` event family and response bodies. A replayed
reply carries up to 256 KiB of a recorded body, but the scenario keeps at most
`max_network_body_bytes` of each body (64 KiB by default), and only within its
allocation budgets: base64 is charged about 11 bytes per body byte, and
redaction more the shorter a declared secret is (about 35 bytes per body byte
for a 12-character `admin_password`). A body over
`max_network_body_allocation_bytes` (1 MiB by default) is kept as `unavailable`
with that reason; one over `max_event_allocation_bytes` (4 MiB) or
`max_total_event_allocation_bytes` (16 MiB) loses its whole content event,
headers included, which the capture lists among its omissions. Either way its
tool replays no body. The example raises all four so that 256 KiB bodies are
kept when the declared secret has at least 12 characters:
```json
{
"browser": { "mode": "launch", "executable_path": "/usr/bin/chromium" },
"start_url": { "url": "http://127.0.0.1:5230/auth", "query": [] },
"secrets": [
{ "secret_id": "admin_password", "environment_variable": "APP_PASSWORD" }
],
"actions": [
{
"step_id": "user",
"action": "fill",
"locator": { "kind": "css", "selector": "input[name=username]" },
"value": { "source": "literal", "value": "admin" }
},
{
"step_id": "password",
"action": "fill",
"locator": { "kind": "css", "selector": "input[type=password]" },
"value": { "source": "secret", "secret_id": "admin_password" }
},
{
"step_id": "sign-in",
"action": "press",
"locator": { "kind": "css", "selector": "input[type=password]" },
"key": "Enter"
},
{
"step_id": "first-memo",
"action": "goto",
"destination": { "url": "http://127.0.0.1:5230/m/1", "query": [] },
"wait_until": "load"
}
],
"capture": {
"events": ["network"],
"network": {
"request_body": true,
"response_body": true,
"header_values": false
},
"limits": {
"max_network_body_bytes": 262144,
"max_network_body_allocation_bytes": 12582912,
"max_event_allocation_bytes": 12582912,
"max_total_event_allocation_bytes": 67108864
}
}
}
```
```sh
APP_PASSWORD=… rea capture-browser-scenario scenario.json --format json > capture.json
rea inspect-analysis-view view.json --format json > manifest.json # view.json wraps capture.json as before
rea environment-serve manifest.json --evidence capture.json --port 8765
```
Each network transaction becomes one record, in request order, and the
record's ordinal is its zero-based position; a transaction whose URL carried a
redacted secret is left unrepresented rather than templated, and one the
capture cannot attribute to a single request and response is left
unrepresented too. Tools are chosen by response media type, so a scenario that
selected neither response bodies nor header values is refused; one that
selected header values but no response bodies yields a manifest but no state,
so it is served by replay. The browser
scenario redacts credential headers and the secrets it declares; values the
application returns in response bodies, such as session tokens, are kept, and
the replayed body is the bytes the browser exposes for each response, with any
declared secret replaced by its redaction marker (a body that redaction had to
empty replays no body).
## What a manifest is
An environment manifest is a projection of one application's recorded request
lines into a tool surface: one tool per method and path template on the
primary origin, with inferred path parameters, observed query parameter
names, value-free body shapes and pointers to the parent records each tool
cites. It carries no bodies and no headers. The manifest's
`parent_evidence_id` names the capture Evidence it was projected from; the
serve command refuses a manifest whose parent is not the supplied `--evidence`
file with an `invalid_request` error naming both identifiers, so a manifest can
never be served from records it did not cite.
The MCP catalog and environment card use a 1 KiB UTF-8 budget for each
captured display sample. Observation, body-key and cited-record lists show
whole values with omission counts; long method, path and query-name displays
show a marked prefix. Complete values remain in manifest Evidence. Argument
names longer than 64 characters use collision-safe `path_<n>` or `query_<n>` aliases; replay maps
those aliases to the complete captured names.
Discovery is admitted as a complete catalog under a 1 MiB serialization
reservation before the listener binds. Reservation charges up to six bytes per
UTF-16 code unit for JSON escaping/UTF-8 expansion, plus schema overhead;
a catalog may therefore be refused even when its compact JSON is smaller.
This was calibrated with 1500 query fields and eight concurrent SDK discovery
requests (183,798-byte card, 507.27 MiB sampled process-family RSS). Over-capacity
catalogs return `resource_constraint`, retain complete input Evidence, and require
a smaller capture or manifest. Fields and tools are never silently omitted.
Served from the state, each description is longer and the card declares the
data plane, so a catalog replay admits can exceed the reservation; the state
is then unavailable and the server serves replay instead (see
[Serve from the state](#serve-from-the-state)).
## What replay means and does not mean
Replay answers every tool with `--replay-only` or when the state is unavailable,
and, served from the state, each read tool whose view the state does not back.
Each such MCP tool call selects one of the records its manifest tool cites and
returns that record's recorded response. Selection compares the supplied path
parameters against the record's path segments at the parameter indexes, then
the supplied query values against the record's query string, and keeps the
record with the most matches; ties keep manifest order. The result reports
where the answer came from:
```json
{
"status": 200,
"content_type": "application/json",
"body": { "id": 2, "login": "probe" },
"replay": {
"record_ordinal": 5,
"evidence_id": "ev_…",
"exact_match": true,
"recorded_path": "/api/users/2",
"recorded_query": null,
"recorded_line_truncated": false,
"body_recorded": true,
"body_encoding": "utf-8",
"truncated": false
}
}
```
`exact_match` is true when every supplied path parameter and query value
equals the recorded one; it says nothing about parameters the caller omitted.
Recorded query parsing runs only when supplied query arguments affect selection.
A path value matches a recorded segment as written or after percent-decoding;
when both kinds of match are available, the record whose segment equals the
value as written is chosen. `recorded_query` keeps the `?` of an explicit empty
query, and a recorded path or query longer than 1 KiB is cut in the reply with
`recorded_line_truncated: true`; selection always uses the full recorded line.
`content_type` also has a 1 KiB display bound with `content_type_truncated`; body
interpretation uses the full recorded media type.
When no record matches, the tool still answers from the tool's first cited
record and reports `exact_match: false`. `body` is parsed JSON when the
recorded content type is JSON-like (`application/json`, `application/*+json`,
`text/plain`, `text/markdown`) and the text parses with safe numeric conversion; otherwise
it is the recorded text. Large integer IDs and other numbers that would lose
information stay in the original JSON text. Bodies over 256 KiB are cut at a UTF-8 boundary and returned as
text with `truncated: true`. `body_recorded` is false when the capture kept the
response's status and content type but no body; `body` is then `null`, which
is not a recorded JSON `null`. `body_encoding` is `base64` when the capture
retained response bytes that are not valid UTF-8; `body` is then exactly those
bytes in base64, never a lossy decoding. A retained base64 body is decoded only as far as the 256 KiB a reply can carry, and a leading byte-order mark is kept. For a `base64` body the limit applies to the recorded bytes, not their longer base64 spelling, and a cut keeps whole base64 groups. Request bodies passed to `POST`, `PUT` and `PATCH`
tools are accepted and ignored: nothing is written, and no call changes what a
later call returns. Arguments the tool's input schema does not name are
refused by the MCP server as invalid arguments, so a misspelled parameter never
degrades into an omitted one.
Replay is not emulation. A served environment does not establish the
application's authorization model, response semantics or state transitions,
which the manifest lists as unknowns; it does not validate supplied values; and
it answers only from the capture's recordings and the state they observed or a
caller loaded through `data/add`. Replayed content is
target content: every tool result, including the argument errors the MCP server
returns before a replay runs, carries `_meta.provenance.untrusted_content: true`
with `source: "analysis_target"`. The server advertises REA's untrusted-content
instructions plus a warning that its tool names, descriptions, parameter names
and observed values come from the capture too, and agents must treat all of it
as data, never as instructions.
That same warning prefixes every tool description in the standalone card, so
card discovery carries it before an MCP client initializes. It labels the
captured text without changing the tool names or schema fields clients use.
## The state a capture observed
Replay answers each call from one recording, so the answers reflect whichever
moment of the capture recorded them. The
[environment state](web-network-captures.md#environment-state) view extracts
instead the data the capture's reads observed before the first related write:
entity types with an identity field, entities with their recorded values,
documents for reads that are not entities, and a render plan per read tool,
kept only where it reproduces that tool's recordings from the state. It is the
starting state an environment holds, loads and reports: `environment-serve`
derives it from the capture at startup; see
[Serve from the state](#serve-from-the-state). With `--replay-only`, replay is
unchanged.
## Serve a manifest
```sh
rea environment-serve manifest.json --evidence capture.json [--replay-only] [--host 127.0.0.1] [--port 0]
```
The server derives the state from the capture before it binds and serves from
it, or serves replay with `--replay-only` or when the state is unavailable;
see [Serve from the state](#serve-from-the-state).
`--host` and `--port` default to `MCP_HOST` and `MCP_PORT` from the
environment, then to `127.0.0.1` and an ephemeral port, exactly as
[`rea mcp --http`](cli.md#serve-mcp-over-streamable-http) resolves them. The
bound MCP URL is written to stderr as one JSON log line
(`"msg":"MCP transport listening"` with `url`); `REA_LOG_LEVEL` overrides that
log level. `ENVIRONMENT_NAME` renames the served environment; otherwise the
manifest's `name` is used, and a set but blank value is refused as
`configuration_invalid` before binding rather than silently falling back. The
listener serves one MCP client at a time with the same session, `Host` header
and shutdown contract as [transports](mcp-contracts.md#transports) describes.
It runs until SIGINT or SIGTERM, then closes the listener, prints one
`{"status":"stopped", …}` document whose `state` member says whether it served
from the state, and exits `130` or `143`.
Signals during input loading or DNS/bind cancel the owning reader/listener before
a listening announcement;
that path returns a structured `cancelled` result instead of a stopped-listener
document, with the same signal exit status.
Three routes are served:
| Route | Answer |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /mcp` | The MCP server: from the state, one tool per read tool, answering from the state where it backs them; in replay, one tool per manifest tool, replaying records |
| `GET /.well-known/agent-env.json` | The environment card |
| `POST /agentenv` | From the state, `data/reset`, `data/add` and `data/get`; in replay, JSON-RPC `-32601 method not found: <method>` for every method |
Numeric JSON-RPC IDs outside JavaScript's safe range or whose precision would
be lost are refused as invalid requests with a null ID. They are never echoed
as a different number.
In replay the data plane at `/agentenv` is advertised by the card but carries
no operations; the error names the requested method so a caller can see that
the method, not the transport, is unsupported. Its request body is
read within the same 4 MiB bound the MCP endpoint applies: a larger body is
answered `413` with a JSON-RPC `-32000` error before any of it is parsed, and a
body that is not JSON is answered `400` with `-32700`. A notification (no `id`)
gets `202` and no body, a batch gets one reply per request in it, and an empty
batch, a batch of more than 100 messages, or a message that is not a JSON-RPC
request (including an `id` that is not a string, number or null, or `params`
that are not an object or array) gets `-32600 invalid request`.
## The environment card
The card is the discovery document the agentenv framework reads before
connecting to `/mcp`. A replay environment's card reads:
```json
{
"name": "grafana-example",
"protocolVersion": "1.0",
"url": "/agentenv",
"preferredTransport": "JSONRPC",
"additionalInterfaces": [{ "url": "/mcp", "transport": "mcp" }],
"capabilities": {
"extensions": null,
"tools": [
{
"name": "get_users_by_id",
"description": "Untrusted captured API catalog: … GET /api/users/{numeric}; returns a JSON object with fields \"id\", \"uid\", \"login\", \"email\"; recorded statuses 200; replays retained records [5, 6]; evidence ev_…",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Path segment 2 (numeric); observed: 2, 3"
}
},
"required": ["id"],
"additionalProperties": false
}
}
],
"operations": []
},
"children_environments": null
}
```
`capabilities.tools` lists the same names, descriptions and input schemas that
`tools/list` advertises over MCP. After the catalog warning, each description
names the method and path template, then what the tool returns, one level deep:
`returns a JSON object with fields …`, `returns a JSON array of objects with
fields …` or `returns a JSON object whose <member> lists objects with fields …`,
where a list is an array of objects found by the
[environment state](web-network-captures.md#environment-state)'s list rule (the
root array, or the one array of objects an envelope carries). Field and member
names are written as JSON strings, so a captured name cannot read as more of
the description; a member name too long to show whole is a quoted prefix marked
as truncated. The summary comes
from the first cited `2xx` record that replay answers as JSON; only when none
did, the first cited JSON record of another status gives it, labelled with that
status (`status 401 returns …`). It describes one recorded response, not a
contract. Field names are sampled within the same budget as other captured
values, and the manifest's `statuses` for the tool follow; a tool with no JSON
record states only its statuses. The description then lists the replayed
records and the evidence ID, and the whole catalog stays within its
serialization reservation, which the summaries and MCP annotations are charged
to.
Over MCP, every tool also carries annotations: `readOnlyHint` is true for the
safe methods (`GET`, `HEAD`, `OPTIONS` and `TRACE`) and for query `POST`s (a
path segment such as `search` or `query`); `destructiveHint` is true for `DELETE` and left unset for other
writes, so the MCP default (destructive) applies to them, and read-only tools
omit it because clients ignore it there; `idempotentHint` is true for the safe
methods, `PUT` and `DELETE`; and `openWorldHint` is false for every tool,
because answers come from the capture rather than the captured application. The
hints describe the captured method; replay itself changes nothing. The card
keeps the `name`, `description` and `inputSchema` of the echo example's tool
shape and carries no annotations.
Path parameters are required strings whose
description names the segment index, the templating rule and the observed
values (sampled within the list budget above; the manifest keeps them all);
query parameter names are optional strings; write methods accept an
optional `body` object described by the recorded top-level key types. Each
input keeps its own argument: a query name equal to a path parameter's name is
advertised as `query_<name>`, a query name longer than 64 characters as
`query_<n>` (its position) with the captured name sampled in its description,
and the write body as `request_body` when a query parameter is named `body`. Every
schema closes with `additionalProperties: false`, a key the echo example's
schema does not carry.
In replay, `extensions`, `operations` and `children_environments` are fixed to
`null`, `[]` and `null`: a replay environment declares no extensions, no
data-plane operations and no children. Served
[from the state](#serve-from-the-state), the card declares the three data-plane
operations and one intake extension instead, leaves write tools out and
describes each tool as answering from the state where the state backs it.
## Serve from the state
```sh
rea environment-serve manifest.json --evidence capture.json
```
Before it binds, the server derives the
[environment state](web-network-captures.md#environment-state) the capture
observed: it runs the `environment-state` view on the capture in-process with
the manifest's `template_rules` in the same order, exactly as
`inspect-analysis-view` projects it from the same capture, so the state
Evidence id it reports is the one that projection produces. The view's own
budget and refusals apply, and the result is checked like the view's Evidence
for this manifest: extracted from the served capture, with the manifest's
rules, naming only manifest tools. The server keeps one live state, shared by
every MCP session and the data plane, starting from the derived state.
A state that is unavailable does not stop the server: it logs a warning naming
the error `code` and message before it binds, then serves replay. The state is
unavailable when it cannot be derived, such as from a
`capture_browser_scenario` capture that selected header values but no response
bodies or over the view's budget, and when its catalog under the served name
exceeds the [discovery reservation](#what-a-manifest-is). That check runs
first, so no state is derived for it, and replay is then admitted exactly as
with `--replay-only`. `--replay-only`
serves replay without deriving anything; the card, tools and `/agentenv`
answers are then exactly those of replay. The stopped document's `state`
member reports which applied:
- `{"served": true, "evidence_id": "ev_…"}`: served from the derived state.
- `{"served": false, "reason": "replay-only"}`: `--replay-only` was given.
- `{"served": false, "reason": "unavailable", "code": "unsupported_target", "message": "…"}`:
the state is unavailable; `code` and `message` are those of the refusal
(`resource_constraint` for a catalog over the reservation), as the warning
logged them.
Each read tool answers according to its view in the state:
| View | Answer |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `item` | The entity the path arguments name, rendered into the recorded envelope of `envelope_ordinal`. Arguments match as replay matches them: each collection segment equals the held collection's segment as written or after percent-decoding, and the identity is the last argument percent-decoded, then as written; values are never re-split on `/`. Any entity the state holds answers, including one `data/add` loaded; query arguments only decide `replay.exact_match`. An entity the state does not hold, or one lacking a field every recording carried, is a tool error; a body is never invented. |
| `list` | When the arguments name one of the lines the view checked exactly (its latest recordings before the first related write; every path and query value equal to the recording's, and every recorded query parameter supplied), that recorded envelope with its array rendered from the state: every entity of the collection in state order for `membership: "all"`, or the recorded members still held. A member lacking a field every recording carried makes the call a tool error rather than a partial list. |
| `document` | When the arguments name the document's checked line exactly, the state's value for it; a tool error when the state holds none. |
| `recorded` | The recording, as replay answers it. |
A list or document call that names no checked line, including a line recorded
after a write or with other query values, answers from the recording. Every
answer has the replay shape plus `state`: `{"source": "state", "view": …}`
naming the entity, collection or document path, or `{"source": "recording",
"reason": …}` with the view's reason, `no-view` or `unrecorded-request`. A
state answer carries the base record's status, content type and `replay`
provenance with `truncated: false`; one whose JSON would exceed 256 KiB is
refused as a `resource_constraint` tool error rather than cut. Extraction does
not state-back a document whose rendered JSON exceeds 256 KiB; that read stays
recorded (`rendered-oversize`) and replays the captured body. Serving is
read-only: `POST`, `PUT`, `PATCH` and `DELETE` tools, other than query `POST`s,
are not served, so nothing a call does changes the state. Query `POST`s stay
served and answer from their recordings with the reason `query-body`.
The data plane serves three JSON-RPC methods:
| Method | Result |
| ------------ | --------------------------------------------------------------------------------------------------------- |
| `data/reset` | `{}` after restoring the state the Evidence holds |
| `data/add` | `{}` after replacing the whole state with one valid `rea-state/v1` document |
| `data/get` | `{"parts": [{"kind": "data", "data": <rea-state/v1 document>}]}` with `state_evidence_id` and the `types` |
Calls run one at a time in arrival order across requests. Every message of a
batch is queued when the batch arrives, so another request's call never lands
between them and each message sees the changes of those before it; a reset
sent while a download is loading applies after that load. `data/add`
takes exactly one part: a `data` part whose `data` is the document, or a
`file` part whose `file` carries `bytes` (base64 of UTF-8 JSON) or a `uri`,
either a `file://` URL of a local regular file, whose host is empty or
`localhost`, or an `https://` URL fetched without following redirects and
within 30 seconds, including reading the body; `mimeType`, when given, is
`application/json`. A `file://` URL naming another host, or a UNC path such as
`file:////server/share/state.json`, is refused before anything is opened, so a
load never reaches a network share. A loaded document is at most 32
MiB, and so is the state as `data/get` writes it back with the members a
document may omit (`types`, `state_evidence_id`, record citations), so a
reported state always loads again; an inline part also stays within the 4 MiB
request body bound, so larger states arrive by `uri`. Anything else, including `{"parts": []}`, is `-32602
invalid params`; a download that fails or answers a non-2xx status is
`-32000`. Errors never echo the uri or the content; a file or download failure
names its category in `error.data.reason`: `not-found`, `permission`,
`not-regular-file`, `changed` or `read-failed` for files, `timeout`,
`http-status` or `network` (connection, TLS or a refused redirect) for
downloads, and `cancelled` for a download the server's stop or its caller's
departure ended.
Stopping the server cancels every pending call, and a caller that leaves before
its reply cancels its own: a download in progress ends, and calls not yet run
are answered `-32000` with `error.data.reason` `cancelled` without running. A
cancelled call leaves the state unchanged, and shutdown never waits for a
download.
A `file://` state file whose close fails stays owned by the server, and
the `data/add` gets `-32000`. The next `file://` load retries that close first
and, while it still fails, answers `-32000` without reading another file;
inline and `https://` documents still load. Closing the server retries it once
more and fails with the unfinished close rather than dropping the descriptor.
One `/agentenv` response carries at most 64 MiB of replies, twice the 32 MiB
a loaded document may hold: room for a `data/get` of a loaded state, while a
batch of reads cannot multiply a large state into one body. Replies are
measured in order as they are produced, in bounded parts and before they are
assembled, and room is kept for every later reply's budget error and the
batch's brackets and commas, so one that would take the response past the
budget is never built whole and is answered instead with `-32000` whose `error.data` gives
`max_response_bytes` and the `reply_bytes` it would have taken. That call still
ran, so repeat such a read in another request. A reply no larger than that
error, such as a write's `{}`, is always kept.
```json
{
"rea_state": {
"version": 1,
"entities": [
{
"type": "/api/users",
"collection": "/api/users",
"id": "2",
"fields": { "id": 2, "login": "probe" }
}
],
"documents": []
}
}
```
Each entity's `type` is a state type's `collection_template`, its `collection`
matches that template segment by segment (a template parameter matches any one
segment), its identity field's value is its `id`, and its type, collection and
id are unique; `view_fields` is optional and names item or list views of its
type. Views render their values over the entity's fields, so a view's values
must not set the type's identity field to a value whose text differs from the
entity's `id`. Spell a collection as requests spell it, as `data/get` reports it: list
calls find entities under the checked line's recorded path. Each document
names a `document` view once, at its initial document's `path`. The `version`,
and the `state_evidence_id` and `types` that `data/get` reports, must match
the served state, so a `data/get` result loads back unchanged. A number without
an exact native value, or whose serialized spelling would not be read as exact
(an integer from 2^53 below 1e21, such as `1e20`, in any spelling), or a
`__proto__` member is refused rather than altered.
An invalid document is `-32602` naming the first problem by JSON pointer, as in
`/rea_state/entities/3/collection` (also in `error.data.path`); a problem
inside caller data (`fields`, `value`, `types`) is located at that member, so
the pointer never names the caller's keys. A refused document changes nothing;
a valid one replaces the whole state at once. The order of `entities` is the
state order lists use.
Record citations stay Evidence provenance. An entity's `record_ordinals` may
be omitted or empty and a document's `record_ordinal` omitted; otherwise they
must be the served Evidence's citations for that entity or document, or the
document is refused. After loading, an entity or document whose values equal the Evidence's cites
the Evidence's records, and one whose values were edited or added cites none
(`record_ordinals: []`, no `record_ordinal`), so `data/get` never presents a
loaded value as recorded.
The card declares the operations and what `data/add` accepts:
```json
{
"extensions": [
{
"uri": "urn:agentenv:intake/v1",
"description": "data/add replaces the whole environment state with one rea-state/v1 document; data/get returns the current state in the same format.",
"params": {
"add": [
{ "part": "data", "format": "rea-state/v1", "load": "replace" },
{
"part": "file",
"format": "rea-state/v1",
"mimeTypes": ["application/json"],
"load": "replace"
}
],
"get": [{ "part": "data", "format": "rea-state/v1" }]
}
}
],
"operations": ["data/reset", "data/add", "data/get"]
}
```
The state is a projection of recorded reads. List and document calls answer
from the state only for the lines their views checked, and every recorded view
answers from recordings; item calls answer for any held entity but render only
the envelope one recording carried. Values copied outside entity objects,
derived values and counters other than those that count a list stay as
recorded; no write has an effect. An exported bundle carries no state file:
its server derives the state at startup, as the export does to predict what it
serves.
## Export a bundle
`rea environment-export` writes the same pair as a bundle folder the agentenv
framework runs directly, shaped like its own echo example:
```sh
rea environment-export manifest.json --evidence capture.json ./grafana-example --json
agent-env run ./grafana-example
```
```text
grafana-example/
README.md provenance, what it serves, run command, rights note
envs/grafana-example/Dockerfile pinned image: node:24.18.0-bookworm-slim + rea-agents@<this version>
envs/grafana-example/env.toml environment_name = "grafana-example"
envs/grafana-example/manifest.json byte-exact copy of manifest.json
envs/grafana-example/evidence.json byte-exact copy of capture.json
artifacts/check_grafana-example/verify.py the verifier
tasks/smoke.json deploy_env (local sandbox), then env_outcome_verifier
```
The command reads each file once, after checking that reading and parsing the
whole file, including sealing traversal, fits the process's live heap headroom (a file that does not is
refused as a `resource_constraint` before it is read), then authenticates and cross-checks the
pair as `environment-serve` does, so a manifest projected from another capture
is refused with the same `invalid_request` before anything is written, and the
bytes it copies are the bytes it authenticated. The bundle directory must be
absent or empty; an occupied directory is refused and nothing in it changes.
After checking the bundle name, the export prepares the state from the capture
exactly as the bundle's server will at startup under that name, to predict what
the bundle serves; an unavailable state, including one whose catalog exceeds
the discovery reservation, does not stop the export, and the bundle then
serves replay. The complete tool catalog the bundle serves must also fit the
server's advertised catalog budget before any files are written. Privately parsed JSON is sealed once so authentication
and replay share immutable response trees rather than copying the capture repeatedly.
`--name` replaces the manifest's portable kebab-case name as the env folder and env id
(Windows device names such as `con` and `lpt1` are refused);
`--package-tarball <path>` copies a packed `rea-agents` tarball into the env
folder and makes the Dockerfile install it instead of the registry package and
remove it in the same layer, which is how a checkout rather than a release is
run. The command prints the
written files with their sizes, the pinned package source, the number of tools
the bundle serves as `tool_count`, and in `state` whether it serves from the
state, in the shape of the serve command's stopped document.
Export uses the shared output-tree owner to check directory identities around
exclusive creates, verify written bytes, and reject unowned entries before
reporting success. It does not delete an inspectable partial folder on failure.
Node's portable pathname APIs leave a syscall-boundary race, so the output's
parent directories must be trusted. On POSIX output files use mode `0600`;
Windows inherits ACLs and REA does not establish owner-only access there. Choose
an already private Windows destination when captured content needs it.
The Dockerfile sets `MCP_HOST=0.0.0.0` and `MCP_PORT=18765`, the port the
framework maps for an MCP server env; the framework's own deploy supplies
`MCP_HOST`, `MCP_PORT` and `ENVIRONMENT_NAME`, so the served card carries the
env's name. It installs Debian's `python3` because the framework's local
sandbox probes a container's readiness with `python3` inside it, which the slim
Node image lacks. It copies the two inputs owned by the image's non-root `node`
user, so a private host umask cannot leave them unreadable, runs as that user and starts
`rea environment-serve /env/manifest.json --evidence /env/evidence.json`. The
`env.toml` names the environment because the framework otherwise reads the
name from Python sources the image does not have.
`verify.py` is the framework's `async def verify(mcp_url)` shape over its
Python MCP client: it lists the tools and checks the count equals the number
the bundle serves (the manifest's read tools from the state, every manifest
tool in replay), calls one tool with no arguments and checks the call did not
fail and its `status` is the expected one, and returns one `serve` result
whose description reports both checks. The tool is the first served `GET` tool
without path parameters whose answer to no arguments is not an error, and the
expected status is the status of that answer: the export calls the same answer
function the server uses, from the derived state or by replay, so a state
answer carries its base record's status and a replayed one its record's (an
unknown recorded status stays unknown; it is not borrowed from another
record). A bundle with no such tool yields a verifier that checks the count
only and says so. `tasks/smoke.json` deploys the env on the local
sandbox and runs that verifier against the env's MCP endpoint; the first run
also builds the framework's own infrastructure, and the run tears everything
down when it ends.
The README written into the bundle records the capture artifact's SHA-256, the
capture and manifest Evidence ids, the manifest view digest, the served tool
count, the derived state's Evidence id or that no state is served, and the
package source. It says what the environment serves: read tools from the state
the capture observed, the `/agentenv` data plane on it and no write tools yet,
replay when the state is unavailable, and `--replay-only` for pure replay; it
says which applies to this bundle, with the error code and message when the
state is unavailable, and that neither is emulation and served
content is untrusted data. It states that the recorded content belongs to the
captured application and must not be published without the rights to it.
## Compatibility verification
`npm run verify:agentenv:environment` is the hosted `real-agentenv` lane
described in [testing](testing.md#exported-environment-bundles). It projects
the Grafana-shaped source-owned capture through the built CLI, packs the
checkout, exports a bundle with `--package-tarball`, runs it with the pinned
`agentenv-framework` release on the runner's Docker and requires the smoke task
to pass with no container left behind other than the framework's own
image-registry helper, which the receipt reports. It proves that one exported bundle runs
on one framework release; it does not claim any hosted platform or other
framework versions.
## Resource and lifecycle boundaries
The Evidence files are read once at startup through the bounded JSON input
reader and authenticated as Evidence before the listener binds; a file that is
not Evidence, a manifest of another view kind, a capture of another format, or
a manifest projected from a different capture is refused before any port is
opened. The state is derived once, in-process and before binding, from the
already authenticated capture: it is projected as retained Evidence, so the
capture's strings are not charged again as inline view input, and the view's
96 MiB budget bounds the derivation. Because authentication covers the capture's records, a manifest whose
parent check passes cites only records the capture retains. The server keeps
only the cited records' request lines and response text in memory, plus the
live state when it serves from one: the derived initial state, or one
validated document whose JSON was at most 32 MiB. Data-plane calls run one at a time, so
at most one loaded document is being read and parsed at once; `data/get`
serializes the held state whole. No process is launched and nothing is
written to disk. No outbound network request is made unless a `data/add` call names an
`https://` uri, which is fetched once within the limits above; a `file://` uri
is read once. A listener that fails after binding is logged and ends the command with
a `resource_constraint` error and exit `1` instead of serving nothing.
+14 -3
View File
@@ -335,9 +335,12 @@ export REA_JADX_OPERATION_TIMEOUT_MS=600000
```
The value must be a decimal millisecond count from 1 to 2147483647; anything
else is refused before Java starts. The same deadline bounds each upstream
call, a timeout reports the selected value, and a passing JADX configuration
check in `rea doctor` reports the effective `operation_timeout_ms`. Explicit
else is refused before Java starts. REA reads it from the environment captured
at process start. A change applies on the next process start; an already
running server keeps the deadline it started with. The same deadline bounds
each upstream call. A timeout names `REA_JADX_OPERATION_TIMEOUT_MS`, the
effective milliseconds, and that range. A passing JADX configuration check in
`rea doctor` reports the effective `operation_timeout_ms`. Explicit
cancellation still ends the operation immediately, and partial observations
and owned-process cleanup are unchanged. Raising the deadline does not extend
the bridge's 30-second startup handshake or the upstream **90-second**
@@ -363,6 +366,14 @@ export REA_ANDROID_TEST_APK="$PWD/_reference/apk-integration/ApiDemos-debug.apk"
npm run verify:android
```
The main lane and Windows Java-selection checks validate the selected JDK and
engine archive through `validateVerifierJadxConfiguration`. This shared verifier
boundary supplies the production validator's resource owner and waits for
retained cleanup before proceeding. Failed closes retain their exact owners for
retry; prerequisite failures must not be mistaken for completed bridge tests.
Recovery checks match the typed Java or archive failure and its applicable
remediation.
The lane also uses the selected full JDK's `jlink` to create a disposable JRE
without the compiler module. It checks real Java startup failures, missing
selectors, recovery after failures, and CLI cancellation with owned cleanup.
+34 -7
View File
@@ -8,7 +8,7 @@ installs Apktool or a Java runtime.
## Supply tools
Use Apktool 2.7.0 or newer (verified with 2.7.0) and a Java runtime the
Use Apktool 2.7.0 or newer (verified with 2.7.0 and 3.0.3 on Linux) and a Java runtime the
launcher can find. Select the launcher through the environment:
```sh
@@ -63,7 +63,9 @@ rea inspect-apktool-client
rea decode-android-resources /targets/Example.apk
rea decode-android-resources /targets/Example.apk --locale de
rea decode-android-resources /targets/Example.apk --locales de --locales pt-BR
rea decode-android-resources /targets/Example.apk --locales de --locales pt-BR --string-tables-only
rea decode-android-resources /targets/Example.apk --no-strings
rea decode-android-resources /targets/Example.apk --decode-timeout-ms 900000
```
Equivalent MCP methods are `inspect_apktool_client` and
@@ -71,8 +73,19 @@ Equivalent MCP methods are `inspect_apktool_client` and
primary `locale` (project `res/values-<locale>/strings.xml` instead of the default
table), `locales` (repeatable array of additional localized string tables to project
from the same single decode pass), and `include_strings` (default true). Regional locales such as `pt-BR`
select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
`b+zh+Hans+CN` may also be supplied directly.
select Android's `values-pt-rBR`. A three-digit region such as `es-419`
selects `values-b+es+419`; `es-r419` is rejected because Android's legacy
`-r` form requires a two-letter region. Android qualifiers such as `pt-rBR`
and `b+zh+Hans+CN` may also be supplied directly.
Set `string_tables_only: true` (CLI `--string-tables-only`) to return string
entries only inside `string_tables`, including when selecting a single table.
The top-level `strings` array is then empty by request; it does not establish
that the primary table is empty. Table status, counts and coverage still describe
the examined source. This avoids repeating primary entries in multi-locale
responses and charges the aggregate output budget for one copy per table.
Omitting the option preserves existing responses. `include_strings: false`
still suppresses all string projection, including in this mode.
## Interpret the result
@@ -108,7 +121,8 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
each projected table with its locale, status (`present`, `missing`,
`oversized`, `malformed`, or `skipped`), entry counts, and coverage,
bounded at an aggregate budget of 10,000 strings and 32 MiB XML. When `locales`
is omitted, legacy single-table payloads are preserved without adding `string_tables`.
is omitted and `string_tables_only` is not true, legacy single-table payloads are preserved
without adding `string_tables`.
- **Smali is skipped by design** (`apktool d --no-src`): Java-source
recovery belongs to the JADX family. Resource smali edits and rebuild are
a follow-up lane with mutation authority.
@@ -120,9 +134,14 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
## Resource and lifecycle limits
- The decode runs with a 600 s deadline and a 4 MiB output capture budget;
a stopped decode reports `provider_timeout` and exceeded budgets report
`resource_constraint`.
- The decode wall clock is `decode_timeout_ms` (CLI `--decode-timeout-ms`).
Omitted means 600000 ms. The integer range is 1 to 2147483647. A change
applies on the next decode. It does not raise the 4194304-byte (4 MiB)
output capture budget. That capture budget has no runtime override. A
stopped decode reports `provider_timeout` and names the effective
milliseconds; an exceeded capture budget reports `resource_constraint`.
- The version probe waits 20000 ms and retains 65536 bytes. This release has
no runtime override for that probe. `decode_timeout_ms` does not raise it.
- Manifest reads are bounded to 512 KiB before decoding UTF-8. Strings XML
reads are bounded to 8 MiB; larger documents are skipped with partial
coverage and an explicit limit, rather than reported as missing.
@@ -143,3 +162,11 @@ locales — launcher version, on-disk digest agreement, apktool.yml metadata
(1.2.3, SDK 24–34), manifest package agreement, default and `de` string
tables projected. Parser goldens in the test suite come from the same
decode. See `docs/testing.md` for the lane summary.
Multi-locale and table-only projection were also verified through real CLI and
stdio MCP workflows on Linux with Apktool 3.0.3/JDK 21 against NewPipe 0.29.1,
ApiDemos 6.0.18 and Appium Settings 8.2.1. Independent XML projection checks,
exact facts/Evidence parity and bounded task costs are recorded in the
[shared-decode and table-only checkpoint](../experiments/analysis-efficiency/apktool-string-tables.md).
This qualifies selected resource facts, not application execution or independent
binary resource-decoder completeness.
+57 -19
View File
@@ -180,8 +180,21 @@ rea trace-dylib-resolution MyApp.app --root Contents/MacOS/MyApp --architecture
Load commands are parsed in TypeScript from Mach-O and FAT headers, including
the `dylib_use_command` encoding newer linkers emit for flags such as delayed
initialization. Nothing is executed and no Apple tool is required, so the tool
also works off macOS.
initialization, and `LC_LAZY_LOAD_DYLIB_INFO` (`0x3a`). That command stores its
install name in a linkedit payload rather than in the load command itself.
Its flag and chain-start image offsets must lie in the slice VM range, which
is dyld's one-page floor extended by every segment except `__LINKEDIT`,
measured from the `__TEXT` vmaddr. Payload strings must start after the 24-byte
header. The load-path NUL must occur before the payload's final byte, matching
dyld's scan. Distinct payload bytes and payload-range lookups stay within the 16 MiB
limit, and a file range already read is reused. String scanning and UTF-8
checks count every reference, including repeats and overlaps, and stop at that
same aggregate. A slice retains at most 1024 of these commands; further copies are
unsupported instead of becoming one traced edge each. Symbol references,
including repeats, stop at 65536 per slice. A larger table is unsupported
instead of caching one string per offset.
Nothing is executed and no Apple tool is required, so the tool also works off
macOS.
Resolution follows dyld:
@@ -200,30 +213,55 @@ Resolution follows dyld:
Each edge lists every candidate path tried, with its outcome: `resolved`,
`absent`, `not-mach-o`, `malformed`, `unsupported` (recognized Mach-O outside
parser coverage, such as big-endian images), `architecture-missing`,
`outside-target`, `escapes-target`, or `undetermined`. Slices follow dyld's
graded architectures, so an `x86_64h` process also loads `x86_64`. The edge's `resolution` is one of:
`not-loadable`, `platform-mismatch`, `outside-target`, `escapes-target`, or
`undetermined`. `not-loadable` means a
matching-architecture Mach-O image was found but it is not a dylib and cannot
satisfy a dylib dependency. `platform-mismatch` means a matching-architecture
dylib was found but its observed platform is incompatible with the process.
These outcomes reject that candidate; dyld search may continue and resolve a
later candidate. Candidate outcomes describe individual search paths, while
`resolution.status` describes the final edge. Slices follow dyld's graded
architectures, so an `x86_64h` process also loads `x86_64`. The edge's
`resolution` is one of:
| Status | Meaning |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `resolved` | An image inside the analyzed root loads, and no earlier candidate was undeterminable. |
| `conditional` | An image inside the root resolves, but an earlier candidate outside the root (for example `/usr/lib/swift`) would win if it exists on the running system. |
| `unresolved` | Every candidate is definitively absent or unusable inside the root. |
| `undetermined` | No candidate resolves inside the root, and some candidate lies outside it or depends on the environment. |
| Status | Meaning |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `resolved` | An image inside the analyzed root loads, and no earlier candidate was undeterminable. |
| `conditional` | An in-root image may load, but an earlier outside candidate, unmodeled environment input, or unknown platform compatibility can change which image dyld loads. |
| `unresolved` | Every candidate is definitively absent or unusable inside the root. |
| `undetermined` | No candidate resolves inside the root, and some candidate lies outside it or depends on the environment. |
A `conditional` image is still traced, because it is the image the analyzed
root supplies. Every edge below it has `loader_conditional: true`, and a
request that reuses it by install name is `conditional` too. Findings on those
edges say that they apply only if the conditional image loads.
A `conditional` image is still traced, because it is an in-root candidate
that may load. Every edge below it has `loader_conditional: true`, and a
request that reuses it by install name is `conditional` too. An in-root dylib
with no platform load command remains unknown unless the root is an executable
with observed macOS platform and the candidate’s CPU type is x86_64, i386, or arm64. In that macOS context,
[Apple's dyld](https://github.com/apple-oss-distributions/dyld/blob/fd8d0c4d52320ebf64db34f3cb280310d905c5ae/mach_o/UnsafeHeader.cpp#L1137-L1145) supplies an implicit macOS platform to legacy dylibs on those CPU
types. The candidate records `platform_basis: "macos-dyld-implicit"`; the
reported slice fields `platform: null` and `platforms: []` remain the parsed
facts. For other process contexts the platform remains unknown, coverage is
partial, and the candidate is not treated as incompatible. If a later known
candidate resolves, it remains the traced image with conditional resolution;
the trace does not claim the unknown candidate's dependency graph. Findings on
conditional edges say that they apply only if the conditional image loads.
Absolute install names such as `/usr/lib/libSystem.B.dylib` are
`outside-target`. On macOS 11 and later most of them live in the dyld shared
cache rather than on disk, so REA does not check them against the host.
Absolute install names that name a path beneath the analyzed root are checked
within that root, with symlinks and `..` resolved by the same bounded tree
resolver. Absolute paths outside the root, such as
`/usr/lib/libSystem.B.dylib`, are `outside-target`; on macOS 11 and later most
system libraries live in the dyld shared cache rather than on disk, so REA does
not check them against the host. Mach-O path strings are not converted from
`file:` URLs or looked up through unrelated host paths.
`findings` are derived, not observed:
- `required-load-unresolved`, `weak-load-unresolved`, and `lazy-load-unresolved`.
`LC_LAZY_LOAD_DYLIB` dependencies are resolved but not traversed, because dyld
loads them on first use; an unresolved one is not a launch failure.
`LC_LAZY_LOAD_DYLIB` and `LC_LAZY_LOAD_DYLIB_INFO` dependencies are resolved
but not traversed, because dyld loads them on first use; an unresolved one is
not a launch failure. `LC_LAZY_LOAD_DYLIB_INFO` has no compatibility version,
so those fields are null. Its may-be-missing flag is reported as `weak`, and
an unresolved dependency with that flag is not a first-use failure: dyld
continues if the image is absent.
- `earlier-rpath-candidate-absent`: a compatible Mach-O placed at an earlier
modeled search path could take precedence, subject to unmodeled search inputs
and code-signing library validation. These findings do not establish which
+4 -4
View File
@@ -1,8 +1,8 @@
graph TD
subgraph "Entry Points"
CLI["src/cli.ts + src/cli/<br/>One-shot CLI adapter<br/>setup, diagnostics, analysis, decompilation"]
MAIN["src/main.ts + src/main/<br/>MCP stdio server adapter<br/>config, session, process lifetime"]
DISPATCH["scripts/rea.mjs<br/>Executable dispatcher<br/>routes mcp / one-shot"]
MAIN["src/main.ts + src/main/<br/>MCP server adapter: stdio default, streamable HTTP opt-in<br/>config, session, process lifetime"]
DISPATCH["scripts/rea.mjs<br/>Executable dispatcher<br/>routes mcp / mcp --http / one-shot"]
end
subgraph "Production Composition"
@@ -10,7 +10,7 @@ graph TD
end
subgraph "Adapters"
SERVER["src/server/<br/>MCP request translation<br/>createServer, tool registration, toolResult"]
SERVER["src/server/<br/>MCP request translation<br/>createServer, tool registration, toolResult<br/>http/: streamable HTTP listener and node:http bridge"]
HOPPER_BRIDGE["bridge/hopper_bridge.py<br/>Runs inside Hopper<br/>adapts operations to Hopper Python API"]
GHIDRA_BRIDGE["bridge/ghidra/ReaGhidraBridge.java<br/>Packaged HeadlessScript<br/>inventory, decompiler, references, CFG"]
INSTALL["src/cli/ + src/application/Setup*<br/>Host installation adapters<br/>macOS: verified vendor DMG to ~/Applications<br/>Linux: verified vendor package + apt/dnf/pacman"]
@@ -34,7 +34,7 @@ graph TD
GHIDRA["src/ghidra/<br/>Ghidra discovery, profile & function analysis<br/>snapshot, Unix/Windows transport, bounded lifecycle"]
IDA["src/ida/<br/>Upstream MCP contract adaptation<br/>live GUI binding or owned headless database"]
IDA_MCP["External ida-pro-mcp<br/>GUI proxy or database supervisor<br/>upstream installation and engine lifecycle"]
AUX["src/artifacts/ + src/native/<br/>artifact inventory and extraction<br/>format readers and native capabilities"]
AUX["src/artifacts/ + src/native/<br/>artifact inventory, bounded directory triage and extraction<br/>format readers and native capabilities"]
BROWSER["src/browser/<br/>CDP / Playwright capture<br/>captured scripts and native module resolution<br/>execution/: coverage, listener and source attribution"]
JS_CODEC["src/javascript/sourceMaps/<br/>pinned upstream map codec<br/>owned heap-limited Node process, complete point evidence"]
INSPECTOR["src/inspector/<br/>passive V8 Inspector discovery and capture<br/>script and target locations"]
+6 -1
View File
@@ -160,7 +160,12 @@ launch builder. It is a configuration fact, not measured memory use or proof of
the effective JVM limit; JVM environment options may affect that limit.
When a Windows script wrapper selects the JVM, this value remains unknown.
Historical stdout and stderr remain available, but classification uses only the
failing operation's `failure_output`. Output draining waits at most one second,
failing operation's `failure_output`. Retained stdout and stderr share an 8 MiB
budget, but every drained byte is scanned for `java.lang.OutOfMemoryError`:
`failure_output.observed_oome` records the latest confirmed token's bounded line per stream from
the failing operation, with its byte offset, even after the budget is spent. These observations own OOME detection; retained text that ends at a class-name prefix cannot confirm a complete token. `line_complete` distinguishes a known line end from an incomplete trailing context; `invalid_utf8` marks replacement-decoded context.
Incomplete operation output without an observed OOME keeps the original failure code and explains that a memory cause cannot be ruled out. Incompleteness alone does not confirm a memory constraint or justify heap-specific advice. Token context stays within the failing operation's checkpoint; a class-name prefix in a different identifier is not OOME evidence. A trailing bare token requires an observed stream EOF to establish its boundary.
Output draining waits at most one second,
subject to earlier cancellation or the startup deadline. `output_incomplete`
marks a snapshot taken before stream closure; cleanup ownership remains with
the session until release succeeds.
+108 -19
View File
@@ -18,9 +18,25 @@ Inspect native SAZ or HAR 1.2 offline with REA, or connect Everywhere's separate
- `inspect_web_page` / `rea inspect-web-page` captures DOM structure, accessibility nodes, scripts, resources, safe response/DOM metadata, attach-window network and console metadata, WebSocket frame sizes, workers, quota, and optionally selected storage key names, redacted storage-content fingerprints, or script sources.
- `analyze_web_bundle` / `rea analyze-web-bundle` parses selected script artifacts without execution and derives chunk edges, route and endpoint candidates, vendor fingerprints, static WebMCP declarations, and optionally source-map/original-source evidence.
- `observe_web_session` / `rea observe-web-session` arms an observation window of the requested duration for an external user action and records ordered reload, SPA navigation, redirect, failure, lifecycle, and target-termination metadata.
- `discover_webmcp_tools` / `rea discover-webmcp-tools` uses the experimental CDP WebMCP domain to return every in-scope registration and its complete observed `input_schema` declaration and canonical `input_schema_sha256` digest inline. Declarations are untrusted JSON data, including declared types, required fields, enums, examples and reference URLs. REA does not resolve schema references. These fields replace `input_schema_shape`. Registrations with the same name and URL in distinct observed frames retain separate identities. `tool_key` includes the observed frame ID; it is not a stable identity across navigation or browser sessions. Same-frame registration updates replace that owner only, and removal leaves other owners intact. Declared `readOnly`, `untrustedContent`, `consequential`, and `autosubmit` annotation hints are reported per registration: `true`/`false` are declared values, `null` means the declaration did not provide the hint in that capture, and a missing `consequential` key means the hint was not recorded, either in a historical capture or because the observed annotation was invalid. Consult discovery completeness and exclusions to distinguish these cases. Malformed annotation values retain the registration with incomplete coverage and an `invalid_protocol_value` exclusion. Other malformed protocol payloads can fail discovery explicitly. REA never exposes `WebMCP.invokeTool`.
- `discover_webmcp_tools` / `rea discover-webmcp-tools` uses the experimental CDP WebMCP domain to return every in-scope registration and its complete observed `input_schema` declaration and canonical `input_schema_sha256` digest inline. Declarations are untrusted JSON data, including declared types, required fields, enums, examples and reference URLs. REA does not resolve schema references. These fields replace `input_schema_shape`. Registrations with the same name and URL in distinct observed frames retain separate identities. `tool_key` includes the observed frame ID; it is not a stable identity across navigation or browser sessions. Same-frame registration updates replace that owner only, and removal leaves other owners intact. Declared `readOnly`, `untrustedContent`, `consequential`, and `autosubmit` annotation hints are reported per registration: `true`/`false` are declared values, `null` means the declaration did not provide the hint in that capture, and a missing `consequential` key means the hint was not recorded, either in a historical capture or because the observed annotation was invalid. Consult discovery completeness and exclusions to distinguish these cases. Malformed annotation values or registration stacks retain the registration with incomplete coverage and an `invalid_protocol_value` exclusion. Other malformed protocol payloads can fail discovery explicitly. REA never exposes `WebMCP.invokeTool`.
- `compare_web_captures` / `rea compare-web-captures` compares passive captures or exact-step-aligned browser scenarios. Scenario results commit reproducible literal normalization and expose alignment failures plus artifact-level action, screenshot, DOM, accessibility, URL, history, storage, and event differences. Missing or truncated evidence is never treated as equivalence.
For `analyze_web_bundle`, each `webmcp_declarations` entry's
`schema_property_names` is a source-derived projection of statically known own
property keys, not schema validation. `schema_property_names_coverage` reports
how complete that projection is: `complete` means a literal properties object
was fully enumerated (including an empty literal); `partial` means a literal
object was available but some computed or spread membership was unresolved,
and the name array retains keys that were known; `unknown` means the schema or
properties owner could not be enumerated as an object literal, including
explicit non-object values; `not_present` means no effective schema or own
`properties` member was present after the `inputSchema ?? input_schema` alias
selection. `not_present` describes this projection only: it does not validate a
schema or rule out properties expressed through other schema constructs. Older
observations may omit the coverage field; treat omission as `unknown` rather
than inferring completeness from the array.
Passive DOM comparison checks complete node inventories and complete frame
parent/child structure independently. Frame IDs and sibling enumeration order
are capture-local and do not establish a change; duplicate IDs, missing parents,
@@ -109,14 +125,11 @@ bundle, for example
`"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"`. Fedora installs
Chromium as `chromium-browser`.
REA needs the browser's HTTP discovery endpoint on a loopback port. A browser
driven over `--remote-debugging-pipe` or a private channel, for example by an
automation SDK, exposes no such endpoint, so `list_browser_targets` has nothing
to attach to. Connection failures report `endpoint_unreachable`; a reachable
HTTP service that returns a non-200 or non-JSON discovery response reports
`invalid_endpoint_response`.
Reproduce that flow in a Chromium-family browser started with
`--remote-debugging-port`.
REA attaches through the browser's HTTP discovery endpoint on a loopback port,
or, for some passive tools, through a
[browser socket](#browsers-without-http-discovery). Connection failures report
`endpoint_unreachable`; a reachable HTTP service that returns a non-200 or
non-JSON discovery response reports `invalid_endpoint_response`.
In a minimal Linux container, headed Chromium under Xvfb can keep running while
its DevTools port never opens. Install the GLES, EGL, and Mesa DRI libraries
@@ -168,7 +181,9 @@ file for you.
the origins you are investigating.
A browser driven only through `--remote-debugging-pipe` or a vendor's private
automation channel has neither endpoint, and REA cannot attach to it.
automation channel has neither endpoint, and REA cannot attach to it. To
inspect such a page, reproduce it in a Chromium-family browser started with
`--remote-debugging-port`.
## Request boundary
@@ -201,6 +216,11 @@ rea inspect-web-page http://127.0.0.1:9222 TARGET_ID \
--json
```
Passive observation honors the requested duration using cancellable waits within
the runtime's timer range. Long windows stay pending across successive waits;
caller cancellation, target termination or leaving the allowed origins ends
collection early. `window_elapsed` identifies completion of the requested wait.
Static bundle analysis and a user-driven observation window are separate operations:
```bash
@@ -283,6 +303,20 @@ Call `list_browser_targets` first because target IDs are browser-instance-specif
REA establishes a main-frame origin boundary before enabling Runtime, Debugger, or Network observation, rechecks it before document capture, and validates it again afterward. If the main frame navigates during final capture, REA discards the mixed result and returns `target_changed`.
The web-session timeline uses CDP monotonic seconds where the event producer
provides a comparable timestamp; absent or invalid timestamps are `null` rather
than a synthetic zero. Events buffered while REA samples the window boundary are
retained only when their timestamp places them after that boundary; older events
are excluded. A buffered event without a comparable timestamp may remain as
contextual evidence with `timestamp: null`, accompanied by a limitation stating
that it does not establish activity in the selected window. Main-frame scope
enforcement still applies to contextual navigation events. Network redirect
events retain their paired prior-hop response context when the timestamped
next-request event falls inside the window. The pre-arm timeline buffer is bounded
by original CDP message bytes. If clock sampling completes after that budget is
exhausted, the operation returns `payload_limit` instead of a partial window.
Cancellation and clock-request failures retain their own outcomes.
## Data minimization
The Link projection parses repeated CDP header field lines independently and
@@ -326,8 +360,8 @@ REA retains local observation data and removes only URL userinfo credentials, ex
WebSocket stream inventories and connection counts likewise require complete
WebSocket coverage. Redirect resource types use only shared known metadata:
an omitted type leaves equality unknown rather than proving a modification.
- Console observations with a stack source retain call type, argument types, timestamp, and source location. When console text capture is selected, already-delivered primitive values are retained verbatim; objects, getters, and remote properties are never expanded.
- WebSocket observations retain direction, opcode, and payload byte length. When shape capture is selected, text frames are classified as text or complete value-free JSON shape; binary bytes, hashes, prefixes, and raw frames are never retained.
- Console observations with a stack source retain call type, argument types, the CDP `Runtime.Timestamp` in milliseconds since Unix epoch, and source location. An absent or invalid timestamp is `null` and makes `console_events` incomplete; an observed zero remains zero. Argument types are listed by CDP argument position. An absent or non-array argument inventory is `null`, and a malformed argument keeps its position as `unknown`; either makes `console_events` incomplete, while an observed empty inventory remains `[]`. A malformed stack or top stack frame is not replaced by its caller: the console event is excluded, and a request initiator location or WebMCP `registration_source` is `null`; each is reported as `invalid_protocol_value`. This epoch-millisecond clock is separate from the monotonic-second timestamps in `observe-web-session`. When console text capture is selected, already-delivered primitive values are retained verbatim with their original `argument_index`; objects, getters, and remote properties are never expanded. Text capture is `unavailable` when the argument inventory is unknown.
- WebSocket observations retain direction, opcode, and payload byte length. A missing or malformed CDP opcode is returned as `null`, with opcode-dependent payload byte length and shape also `null`, and marks `websocket_frames` incomplete. Missing or wrong-typed payload data is not treated as empty; its byte length is `null`, and a text payload shape is unknown. Numeric opcode `0` and an observed empty payload remain distinct from missing data. Opcode is nullable in the public inspection schema, so clients must handle unknown protocol values. When shape capture is selected, text messages are classified as text or complete value-free JSON shape; binary bytes, hashes, prefixes, and raw payloads are never retained.
- Storage observations always redact values. Key names, IndexedDB names, and cache names require `include_storage_keys`; stable content fingerprints require the additional `include_storage_fingerprints` selection. Cookie fingerprints cover cookies applicable to the current main-frame URL, including its path, rather than every cookie path on that origin. Other storage remains scoped to the origin. Cache fingerprints hash all decoded response bytes, including bodies above 64 KiB, subject to the [64 MiB per-message CDP limit](#request-boundary). Missing or undecodable cache bodies and partial IndexedDB remote objects make fingerprint coverage incomplete, so identical observations remain `unknown`.
- Unavailable or malformed storage inventories mark `storage_keys` unavailable, even without fingerprints. Comparisons suppress inferred key additions and removals while preserving modifications proven by complete fingerprints on both sides. Previously exported captures are not retroactively corrected; recapture them to obtain these coverage markers.
- Script metadata is included only when CDP supplies a URL on an allowed origin. Stable keys exclude transient CDP script IDs, and exact transient raw URLs are used only during script/resource reconciliation. URL-less scripts are excluded because their origin cannot be established. When CDP supplies an execution-context association, the accepted script retains its authorized frame ID for later attribution. Script metadata admission bounds retained identity and source-map strings to 8 MiB and 50,000 records. When a source-map URL cannot fit, the script identity remains and source-map coverage reports `resource_budget_exhausted`; rejected script observations are counted without retaining their IDs. Source content is omitted unless explicitly requested and is returned inline as a self-verifying artifact with its SHA-256 digest.
@@ -350,6 +384,49 @@ validation and resource bounds. Omitted script metadata makes its affected
section explicitly truncated.
Disallowed-origin entries are filtered before retention.
Selected script-source collection shares a 32 MiB aggregate UTF-8 retention
budget and the `command_timeout_ms` deadline (default 20000 ms) across the
capture. The byte budget has no runtime override. An oversized source is
omitted while later smaller sources may still fit. When the deadline expires,
remaining source reads are skipped. Script metadata, per-item omission reasons,
and `script_sources` completeness remain available. A single CDP response can
still be materialized up to the separate 64 MiB transport limit before source
admission; the retention budget does not bound that transient allocation.
Bundle parsing and semantic inspection run sequentially in an owned child,
without executing captured code. These are separate phases. `max_heap_mb`
defaults to 1024 MiB V8 old-space (range 128..16384). `analysis_timeout_ms`
defaults to 30000 per script, including startup and transfer.
`total_analysis_timeout_ms` defaults to 300000 across script analysis. A
per-script deadline above the effective total is rejected. A failed or
timed-out script becomes an explicit unknown while completed findings and later
scripts remain available. Total-deadline expiry returns a typed timeout with
partial Evidence and identifies unstarted scripts. `source_map_fetch_timeout_ms`
defaults to 30000 and is an item limitation, not that analysis timeout. These
controls are also available as CLI flags with hyphenated names. Worker protocol
and result byte budgets have no runtime override.
One web-bundle capture/analysis is admitted per REA process at a time. Completed
script results share an 8 MiB serialized transfer budget, with host heap
reservation checked before decoding and validating another result.
When the host reservation is what reaches zero, the failure names that heap
headroom and the remaining fixed budget. When the 8 MiB allowance itself is
exhausted, the failure names that fixed budget and says it has no runtime
override. Either stop ends further script launches and returns a typed
resource failure with completed facts and explicit unstarted-script unknowns.
Worker control frames are limited to 64 KiB. Cleanup must confirm child termination
before releasing its private files; failed cleanup retains its exact owner and
blocks replacement until retry succeeds. Cancellation retains completed bundle
facts, including cancellation during final cleanup.
The worker heap setting is not a process-family RSS limit. Node enforces V8
old-space flags; Bun ignores them. Windows Bun instead uses an owned process
commit limit with a 512 MiB runtime reserve; other Bun hosts have no enforced
memory limit. An allocation failure before that Windows limit is reported as
reached still names the configured limit and says it was not reached. These
bounds do not establish an aggregate host-memory limit across other REA
operations or external processes.
Resource-tree inventories distinguish a valid empty `resources` array from a
missing or malformed collection. Invalid resource entries are omitted with
incomplete coverage, while valid resources from that frame and other frames
@@ -362,12 +439,24 @@ an invalid supplied size remains unknown with incomplete resource coverage while
the resource's other facts are retained. Zero and nonnegative fractional sizes
are preserved.
CDP discovery has a 10-second deadline. Each WebSocket handshake and command
response has its own 20-second deadline, separate from the caller-selected
observation window. A stalled handshake or command reports `provider_timeout`;
caller cancellation still reports cancellation. WebSocket messages remain subject
to the [64 MiB limit](#request-boundary). REA does not impose a message-count or
pending-command quota. On cancellation, it closes only its own WebSocket,
CDP discovery has a 10-second response deadline. HTTP discovery documents
use an 8 MiB budget. Browser-socket discovery (`Browser.getVersion`,
`Target.getTargets`) uses the 64 MiB protocol message budget. Neither budget
nor the discovery deadline has a runtime override. `list_browser_targets` accepts no
`command_timeout_ms`: HTTP discovery and browser-socket discovery
(`Browser.getVersion`, `Target.getTargets`) stay on that fixed deadline, and
the socket closes without a later command. Other CDP tools use
`command_timeout_ms` (default 20000) for each WebSocket handshake and command
response, separate from the caller-selected observation window, discovery, and
the 5000 ms cleanup grace. A browser-level socket's handshake and the following
`Target.attachToTarget` each receive that full deadline; they do not share one
budget. A stalled handshake or command reports
`provider_timeout` and names `command_timeout_ms` only when that operation
accepts it; caller cancellation still reports cancellation. WebSocket messages
remain subject to the [64 MiB limit](#request-boundary), which has no runtime
override. REA does
not impose a message-count or pending-command quota. On cancellation, it closes
only its own WebSocket,
waiting up to one second before terminating it. Malformed unsolicited events
and malformed replies to pending commands poison the connection so later
commands fail closed. A correlated reply's session ID must match the command's
@@ -376,7 +465,7 @@ rejects it as unknown; other command rejections retain their reported failure.
Network and console coverage starts only after REA attaches and enables the relevant CDP domains. `prior_activity_available` is always `false`; absence from these arrays is not evidence that an event never occurred. Scripts are different: scripts the page parsed before REA attached are still reported under `scripts`. A page that loaded before attach can therefore list its scripts while `network.requests` lacks the requests that fetched them. If CDP reuses a request ID without supplying redirect metadata, REA retains the predecessor observation and marks network coverage incomplete.
Source maps are not fetched by inspection. Bundle analysis fetches them only when `fetch_source_maps` is selected, with exact-origin redirect checks and no credentials, cookies, or referrer. Each fetch operation has a 30-second deadline and a 64 MiB aggregate streamed-response budget across redirects. A deadline or byte-limit failure remains explicitly unavailable and makes bundle completeness partial. Source-map decoding also bounds raw resolved identities to 64 MiB and aggregate inline evidence to 32 MiB. Failed maps preserve their failure context when it fits; if another context cannot fit, collection stops with the full requested count, the returned processed count, and an explicit unknown-results limitation. Retained mappings and original sources are returned inline. See [source-location limits](web-source-location.md) for the structural decoder bounds. Original source artifacts with `.ts`, `.tsx`, `.mts`, or `.cts` suffixes carry `text/typescript`; other source names retain `text/javascript`.
Source maps are not fetched by inspection. Bundle analysis fetches them only when `fetch_source_maps` is selected, with exact-origin redirect checks and no credentials, cookies, or referrer. Each fetch operation uses `source_map_fetch_timeout_ms` (default 30000) and a 64 MiB aggregate streamed-response budget across redirects. The byte budget has no runtime override. A fetch overrun is an item limitation, not a thrown analysis timeout. A deadline or byte-limit failure remains explicitly unavailable and makes bundle completeness partial. Source-map decoding also bounds raw resolved identities to 64 MiB and aggregate inline evidence to 32 MiB. Failed maps preserve their failure context when it fits; if another context cannot fit, collection stops with the full requested count, the returned processed count, and an explicit unknown-results limitation. Retained mappings and original sources are returned inline. See [source-location limits](web-source-location.md) for the structural decoder bounds. Original source artifacts with `.ts`, `.tsx`, `.mts`, or `.cts` suffixes carry `text/typescript`; other source names retain `text/javascript`.
source-map items retain the script's `declared_url` separately from the observed
`effective_url`. successful maps use the latter as their source-resolution base.
+23 -4
View File
@@ -23,9 +23,21 @@ that rejection does not roll back browser effects. REA removes its owned
future-document scripts, restores live frame methods, then disconnects.
Add secret declarations, storage seeds, and additional artifact or event
capture only when needed. Action, secret, and storage counts are not capped.
Duration, action, and navigation timeouts remain fixed provider-owned liveness
limits. `capture.limits` controls retained event and network-content budgets;
it does not change those liveness deadlines.
Duration, action, and navigation timeouts remain separate from CDP command
deadlines. `command_timeout_ms` (default 20000; omit it to keep that default
and leave it out of Evidence) bounds launch startup, the connect-over-CDP
handshake, target lookup, environment commands, and storage CDP commands,
including replies from attached child targets. Set it in the scenario JSON.
`capture-browser-scenario` has no `--command-timeout-ms` option.
It does not change action `timeout_ms`, `wait_for_timeout.duration_ms`, or
navigation. Service-worker restoration keeps a fixed 5000 ms grace and does
not inherit a raised `command_timeout_ms`. CDP discovery stays on its own
fixed deadline. When service workers are blocked, the registration check
before discovery has its own fixed 10000 ms deadline; `command_timeout_ms`
does not apply because discovery has not started. The discovery deadline
covers endpoint discovery only. The following WebSocket handshake and
`Target.attachToTarget` each use `command_timeout_ms`. `capture.limits` controls retained event and network-content
budgets; it does not change those liveness deadlines.
## Minimal launch example
@@ -107,6 +119,11 @@ Through MCP, pass the same object as the `capture_browser_scenario` arguments.
The final step's DOM and accessibility artifacts retain the page state at that
capture time inline. REA still launches and cleans up the browser profile.
Action `timeout_ms` and `wait_for_timeout.duration_ms` accept integers from 1
through 2,147,483,647 milliseconds, matching the underlying timer representation.
Larger values receive an input error before browser launch. Omit `timeout_ms`
to keep an action pending until completion or request cancellation.
The click's `timeout_ms` covers the click action. A non-navigating `fetch` or
delayed render can finish later, so use `wait_for` to observe a page-specific
ready condition before final capture. A page that updates synchronously can
@@ -207,7 +224,9 @@ statements remain under the attached debugger client's control.
The result is Evidence with an initial state followed by one record per
declared action. Each step reports action status, elapsed time, sanitized URLs,
event bounds, and independently typed capture states for screenshot, DOM,
accessibility, URL, history, and storage. Console, page-error, network,
accessibility, URL, history, and storage. Actions after a failed or cancelled
action are not run and are recorded as `cancelled` with a not-executed error.
Console, page-error, network,
WebSocket, frame, worker, popup, and cancelled-download events are attributed to
steps. Retained events and requested artifacts are returned inline; omitted
events are counted by kind and identify affected network transactions.
+203 -5
View File
@@ -30,6 +30,13 @@ jq -c '{source: {kind: "inline", evidence: .}, view: {kind: "summary"}}' app-evi
rea inspect-analysis-view app-view.json
```
The request can also name the saved file instead of embedding it:
`{"source": {"kind": "evidence-file", "path": "app-evidence.json"}, "view": {"kind": "summary"}}`.
The CLI resolves a relative path against the working directory; MCP clients
pass an absolute path. REA reads and authenticates the file, then projects it
like retained Evidence, so a large file is bounded by the file reader rather
than charged as inline input.
For example, a 334 MB Obsidian application Evidence file yields a summary view
of about 10 KB. Replace the view with
`{"kind": "page", "collection": "modules", "offset": 0, "limit": 32}` for a
@@ -56,10 +63,22 @@ or repeat it to select several types.
Selection limits decoding to the selected types; member references remain an
assembly-wide inventory, so the output can still be large.
Select `--detail summary --evidence-bundle /absolute/path/members.json` to
receive identity, selection, coverage, limitations and collection counts while
saving the complete original Evidence in a new bundle. Summary requires that
explicit destination; existing files are preserved. Later
`inspect-analysis-view` calls can page the exact parent from the saved bundle
without reopening the assembly. See
[CLI summary and saved member rows](managed-code-analysis.md#cli-summary-and-saved-member-rows)
for the complete command sequence. Omitted or `--detail complete` retains the
full inline response.
Choose the workflow from the artifact's contents rather than its `.exe` or
`.dll` extension. The managed parser requires PE/CLI metadata; it does not
unpack .NET single-file hosts or decode IL2CPP metadata. NativeAOT method bodies
require native analysis. See the [managed-code guide](managed-code-analysis.md)
unpack .NET single-file hosts or decode IL2CPP. For the image, type and method
names in a Unity `global-metadata.dat`, use
[IL2CPP metadata](il2cpp-metadata.md). NativeAOT method bodies require native
analysis. See the [managed-code guide](managed-code-analysis.md)
for supported deployment forms, selection semantics, and coverage limits.
## SQLite snapshots
@@ -83,6 +102,47 @@ The shared CLI/MCP workflow reports compiler version, modules, replacements,
build settings, original bytes and SHA-256. See [Go binaries](go-binaries.md)
for supported containers and absent or malformed metadata.
Inspect a Godot PCK without running the game:
```sh
rea inspect-artifact game.pck --detail summary --evidence_output evidence.json --json
rea extract-artifact game.pck --json
```
Formats 2, 3 and 4 retain header, directory and integrity facts. Compact delivery
keeps complete Evidence in the requested bundle. See [Godot PCK](godot-pck.md)
for embedded packs, batch queries and unknown encrypted coverage.
Inspect local model declarations without loading weights:
```bash
rea inspect-model-artifact /absolute/path/model.gguf --json
rea inspect-model-artifact /absolute/path/model.safetensors --hash full --json
```
Default hashing reads only headers and leaves full-file identity unknown.
`--hash full` streams the complete file for SHA-256. Both return typed metadata,
original tensor declarations and derived totals. MCP summaries retain complete
Evidence for filtered metadata, tensor and type-total pages; CLI compact delivery
uses `--detail summary --evidence_output FILE`. See [model files](model-artifacts.md).
Inspect Unity IL2CPP metadata names without Unity or a disassembler:
```bash
rea inspect-il2cpp-metadata /absolute/path/global-metadata.dat --json
```
The command decodes a version 24, 27, 29, 31 or 39 `global-metadata.dat` and reports assembly
images, type, method and member names, string literals, index ranges, header
sections and SHA-256. With `--binary PATH` it also reads the matching
`GameAssembly.dylib`, `GameAssembly.dll` or `libil2cpp.so` (never runs it) and
links each method to its code address; `--ghidra-seeds PATH` then writes Ghidra
function seeds. It does not decrypt metadata. MCP defaults to compact counts
with retained Evidence; query indexed rows with filters, batch indices and
selected fields. The CLI defaults to complete Evidence;
`--detail summary --evidence_output FILE` exports the full result to a new file
and returns a compact overview. See [IL2CPP metadata](il2cpp-metadata.md).
Inspect an embedded cargo-auditable Rust dependency list without installing
Rust or configuring a disassembler:
@@ -154,7 +214,7 @@ The selected provider remains bound to the session until an explicit switch
or close. Provider failures are returned with their original reason. For an
`ambiguous` selection error, choose from `details.candidate_ids`; for
`provider_unavailable`, follow `message`, `remediation.action`, and the original
reasons in `details.rejections`. For Hopper, Ghidra, IDA, and JADX, run
reasons in `details.rejections`. For Hopper, Ghidra, IDA, JADX, and Kuna, run
`rea doctor --provider ID --json` to diagnose the selected engine. Other adapters,
such as `pwntools-elf`, report their configuration requirements directly and are
not accepted by `doctor --provider`. See
@@ -229,7 +289,12 @@ Exports preserve an existing destination unless `--overwrite` is explicit.
For application traces and version comparisons, see
[JavaScript application workflows](javascript-application-workflows.md).
MCP [retained Evidence references](mcp-contracts.md#retained-application-evidence-inputs)
belong to one connection. Separate CLI calls consume full saved records.
belong to one connection. Separate CLI calls can consume full saved records.
`inspect-analysis-view REQUEST.json --evidence-bundle BUNDLE.json` resolves
the request's `retained-evidence` source ID from that authenticated bundle,
including bundles exported from an MCP session. The same view JSON works for
every supported parent kind; no target is reopened and no record is selected
by file order. Omit `--evidence-bundle` when the request supplies inline Evidence.
## Import historical source
@@ -286,6 +351,12 @@ reported separately as configured-secret exclusions.
Re-import saved graphs whose pattern-based exclusions lack `pattern` before
using them in source-to-bundle comparisons.
Entries that change during an import retain an unavailable-entry diagnostic
alongside readable siblings. If enumeration of an already admitted root fails,
the graph keeps its observed children and records the root failure as a
top-level limitation. That partial inventory does not establish absence among
unexamined children.
JavaScript and TypeScript import parsing requires valid UTF-8. Malformed source
bytes retain their original hashes and sizes with a decoding diagnostic; REA
does not infer module targets from replacement characters.
@@ -310,6 +381,95 @@ Choose the guide for the target and intended interaction:
Runtime requests name the target and actions. Launched targets run with your
user permissions; consult the chosen guide for host requirements and effects.
## Serve MCP over streamable HTTP
`rea mcp` speaks stdio to the client that launched it. To serve the same MCP
catalog over streamable HTTP for one local client, such as an agent environment
runtime, start the dispatcher entry with `--http`:
```sh
rea mcp --http --port 8765
```
`--host` and `--port` default to `MCP_HOST` and `MCP_PORT` from the environment,
then to `127.0.0.1` and an ephemeral port. The bound URL is written to stderr as
one JSON log line (`"msg":"MCP transport listening"`) whatever `REA_LOG_LEVEL`
is set to; nothing is written to stdout. `rea mcp --http --help` lists the accepted options. The listener serves
one client at a time: a session ends with the client's `DELETE`, and a client
that connects while another session is open takes it over, so a client that
exited without ending its session needs no restart. The listener runs until
SIGINT or SIGTERM and does not stop when stdin closes. See
[transports](mcp-contracts.md#transports) for the session, `Host` header and
shutdown contract. Client registrations written by setup and the MCP registry
entry keep stdio.
## Serve an environment manifest
`rea environment-serve <manifest.json> --evidence <capture.json>
[--replay-only] [--host H] [--port N]` serves an environment manifest
projected by `inspect-analysis-view` as an agent environment: an MCP server at
`/mcp`, the environment card at `/.well-known/agent-env.json`, and a
`/agentenv` data plane. The manifest's `parent_evidence_id` must equal the
evidence file's `evidence_id`; otherwise the command refuses with
`invalid_request` before binding. Before binding it derives the
`environment-state` view of the capture with the manifest's `template_rules`,
as `inspect-analysis-view` would, and serves from it: read tools whose views
are state-backed answer from a live state, write tools are not served, and
`/agentenv` serves `data/reset`, `data/add` and `data/get`. When the state
cannot be derived, or its catalog exceeds the discovery reservation, it logs a
warning with the error code and message and serves replay; `--replay-only` serves replay without deriving. In replay every
manifest tool replays the retained capture records it cites and `/agentenv`
answers every method with JSON-RPC `-32601`. The stopped document's `state`
member is `{"served": true, "evidence_id": …}`,
`{"served": false, "reason": "replay-only"}` or
`{"served": false, "reason": "unavailable", "code": …, "message": …}`; see
[serve from the state](agent-environments.md#serve-from-the-state).
```sh
rea environment-serve manifest.json --evidence capture.json --port 8765
```
`--host` and `--port` resolve like `rea mcp --http`: flags, then `MCP_HOST` and
`MCP_PORT`, then `127.0.0.1` and an ephemeral port. `ENVIRONMENT_NAME` renames
the served environment; set but blank, it is refused as `configuration_invalid`
like a blank `MCP_HOST`. The bound URL is written to stderr as one JSON log line
(`"msg":"MCP transport listening"`). See
[agent environments](agent-environments.md) for what the state and replay
return and do not establish.
## Export an environment bundle
`rea environment-export <manifest.json> --evidence <capture.json> <dir>
[--package-tarball <path>] [--name <override>]` writes the same manifest and
capture pair as a bundle folder the agentenv framework runs with
`agent-env run <dir>`. It reads each file once, authenticates and cross-checks
the pair with the same checks as `environment-serve`, checks the bundle name,
then prepares the state under that name as the bundle's server will at startup
to predict what the bundle serves (replay when the state is unavailable),
copies the bytes it authenticated, refuses to write into a directory that
exists and is not empty, and never overwrites a file.
```sh
rea environment-export manifest.json --evidence capture.json ./grafana-example --json
```
The folder holds a `README.md` with the bundle's provenance, an env folder
`envs/<name>/` with a `Dockerfile` that installs this exact `rea-agents`
version and serves the copied `manifest.json` and `evidence.json` (written
with mode `0600` on POSIX; Windows retains inherited ACLs) with
`environment-serve` (from the state by default), a Python verifier under
`artifacts/check_<name>/` that checks the served tool count and one served
answer, and the smoke task `tasks/smoke.json`. `--package-tarball` copies a packed `rea-agents`
tarball into the env folder and installs it instead of the registry package,
which is how the hosted lane proves a checkout rather than a release. `--name`
replaces the manifest's kebab-case name as the env folder and env id; a device
name Windows reserves (`con`, `nul`, `com1` and the like) is refused. The
command prints one JSON document listing the written files with their sizes,
the pinned package source, the served `tool_count`, and `state` in the shape
of the serve command's stopped document. See
[agent environments](agent-environments.md#export-a-bundle) for the folder
layout and what the smoke task checks.
## Output and exit status
`rea mcp doctor --json` checks production MCP startup and reports child logs in
@@ -328,6 +488,11 @@ redirected, which keeps large results smaller for agents and scripts; pipe
through `jq .` for indented files. Output selection and formatting do not change
operation status.
`--filter-output` selects fields from successful command data. Classified failures
retain their complete typed diagnostic projection even when the selector matches
a field such as `code` or `message`, or names a missing field. `--full-output`
controls whether the outer `{ok, error, meta}` envelope is included.
For `cutter-command`, `--json-output` requests command-specific JSON from
Cutter when available. This is separate from `--format json`, which selects the
CLI result representation; the global `--json` flag selects that same CLI
@@ -344,6 +509,30 @@ output formatting.
| `1` | The operation could not complete. Structured output identifies invalid input, permissions, cancellation, timeouts or another failure when available. |
| `128 + N` | Signal-derived status. An unhandled signal may have ended the process, with the shell or runtime preserving the conventional status; a command may instead have handled the signal, waited for its operation and cleanup to settle, and assigned the same status (`130` for SIGINT, `143` for SIGTERM). In the handled case, it may also have printed a structured `cancelled` result. |
`rea mcp --http` is long-running and prints no structured result. It exits
`130` on SIGINT or `143` on SIGTERM after closing the listener, the session and
its providers, and `1` when that cleanup fails.
`rea environment-serve` is also long-running: it serves until SIGINT or
SIGTERM, closes the listener, then prints one structured
`{"status":"stopped", …}` document naming the URL, environment and tool count
and exits `130` or `143` through the shared cancellation handler below.
Refusals before binding (unreadable files, non-Evidence JSON, capture Evidence
in a format other than HAR, a manifest or state whose parent is not the
supplied evidence, an unbindable port) print a structured
error and exit `1`, as does a listener that fails after binding.
`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 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; it depends on
the command's signal handling. Commands routed through the shared
`withCommandCancellation` handler in the CLI set status `130` for SIGINT or
@@ -356,11 +545,20 @@ browser, web and Electron commands (including `analyze-web-bundle`,
`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. In these paths, a returned structured
command, objdump, Rizin and GDB, and the agent environment server
(`environment-serve`). 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 the reader of piped output closes early, as `rea ... | head` does, the
CLI stops writing, prints no error and exits `141` (`128 + 13`, the status of a
SIGPIPE-terminated writer). The operation itself may have completed; only its
+2 -2
View File
@@ -153,8 +153,8 @@ headroom. The default is 450000 ms, covering the default 330-second Ghidra
startup; an explicit Ghidra startup timeout of 2700000 ms produces a 2820000 ms
tool timeout. The startup allowance follows an explicitly selected Ghidra or
Hopper provider, and otherwise uses the larger known Ghidra/Hopper deadline.
An explicit `REA_JEB_MCP_TIMEOUT_MS` request budget also contributes to that
maximum. For `ida` or `auto` selection, a valid IDA registration's parsed
An explicit `REA_JEB_MCP_TIMEOUT_MS` deadline, shared by catalog discovery and
each tools/call, also contributes to that maximum. For `ida` or `auto` selection, a valid IDA registration's parsed
`timeoutMs` also contributes to that maximum; its default is 300000 ms.
Setup forwards these explicitly selected REA deadlines and the input schema
profile into the registration; unrelated process values are omitted. An
+15 -4
View File
@@ -17,8 +17,8 @@ shared form would leave later fields unknown instead. The existing
`REA_MCP_INPUT_SCHEMA_PROFILE=compact` profile lets callers stay below
its character limit by advertising reduced nested validation structure, while
REA continues to validate calls against the complete canonical input schema.
Compact applies to the server's advertised inputs and is not an automatic
full-profile fallback; see the [compact input schema profile](mcp-contracts.md#compact-input-schema-profile)
Compact is the default for the server's advertised inputs; an explicit `full`
choice is preserved. See the [compact input schema profile](mcp-contracts.md#compact-input-schema-profile)
for details of its reduced forms.
Custom renderer hosts can raise `inputMaxChars` through `renderToolSignature` or
@@ -457,11 +457,22 @@ disposable HOME and CODEX_HOME under `~/.cache/rea-agent-evaluations/`. Set
`REA_AGENT_EVAL_ROOT` to choose another parent directory outside the OS temporary
directory: current Codex refuses helper aliases under `/tmp`, preventing shell
commands and skill reads even if MCP works. Each owned run directory is removed
after verification unless fixture retention is requested. The lane
after verification unless fixture retention is requested. Commands share the
owned-process supervisor: native ownership preparation has its own bounded
deadline before each short command budget, and timeouts join bounded process-tree
and output cleanup before returning. If cleanup remains incomplete, the lane retries its retained
owner and preserves the run directory (including disposable auth) rather than
removing files still in use; the error retains ownership and recovery details.
Command stderr is limited to 32 KiB and combined version output to 8 KiB;
exceeding these diagnostic budgets fails explicitly. Scenario JSON events stream
to the evaluator without retaining a second raw stdout copy. Cleanup attempts the
remaining run tree even if auth removal fails, and reports unresolved cleanup
together with the original verification failure. The lane
installs the packaged skill and MCP registration through public `rea setup`,
rather than copying a skill into a project that also inherits the caller's
skills and configuration. Only authentication is copied, when present, and it
is removed even with `REA_AGENT_EVAL_KEEP_FIXTURES=true`. No user configuration,
is removed after confirmed process cleanup even with
`REA_AGENT_EVAL_KEEP_FIXTURES=true`. No user configuration,
rules, plugins or history is copied; shell snapshots and additional agents are
disabled. Existing API-key environment authentication remains available.
The native missing-provider scenario preapproves only `open_binary` and
+150
View File
@@ -0,0 +1,150 @@
# Desktop installation directories
Use `inspect_desktop_application` when an installation directory is the target
and its runtime is unknown. It reads directory entries, selected headers and
bounded metadata, then reports runtime candidates, supporting files, component
path markers and concrete follow-up operations. No native provider or active
binary session is needed. It does not run the application, extract archives,
follow child symlinks, contact services or change target files.
## MCP
```json
{ "path": "/artifacts/MyApplication" }
```
Default `detail: "summary"` retains complete source Evidence in the session and
returns candidates with representative supporting paths, counts, coverage,
limitations and grouped next probes. `normalized_result.parent_evidence_id`
identifies the complete record. A server without Evidence retention refuses
summary delivery before reading the target; select `detail: "complete"` to
receive every retained fact inline.
Read exact files in one request:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "ev_<parent-sha256>"
},
"view": {
"kind": "desktop-application",
"collection": "files",
"paths": ["Game_Data/Managed/Assembly-CSharp.dll", "GameAssembly.dll"],
"fields": ["path", "read_status", "ranges", "facts", "issues"],
"offset": 0,
"limit": 16
}
}
```
Collections are `files`, `omissions`, `candidates`, `components` and `next_probes`.
Files and omissions accept exact `paths` and batched `file_ids` / `omission_ids`.
Files also accept `has_issues: true` to select probe diagnostics directly, or
`false` to select rows without reported issues. This filter uses the retained
issue facts; it does not re-read targets or infer that uninspected files are healthy.
When both are supplied, all filters apply; an empty selection returns no rows.
Omission records retain the observed path, kind and stable `omission_id`; their
payloads are not read, and other special-entry metadata remains unavailable.
`candidates` accepts exact `families`.
Omitted selectors match all retained rows; an empty selector matches none.
Every collection supports `fields`, `offset` and `limit`; its stable row ID is
always included. Selection changes delivery, not source inspection. Pages keep
source coverage and parent Evidence links. Page exhaustion does not establish
absence in a partial source. Complete Evidence remains accessible through
`get_evidence` and Evidence bundle export.
The summary's `probe_issues` counts files with reported issues and their retained
issue entries. It previews at most two such files, including stable `file_id`,
read status and the first issue. Path/reason previews use at most 256 UTF-16 units
each without splitting surrogate pairs; `text_truncated` marks shortened text,
and `preview_truncated` marks additional files. These are display prefixes;
full caller paths and all reasons remain in Evidence. Counts describe retained
observations, while source coverage still identifies partial inspection.
Use `inspect_analysis_view` with `collection: "files", has_issues: true` and
`fields: ["path", "read_status", "issues"]` for exact reasons, with the usual
paging and parent links. It intersects with exact paths and batched file IDs.
An ASAR inventory probe first selects its exact path with `open_binary`; then
call `inspect_artifact` on that active target. Directory inspection itself does
not select or replace the session target. The JavaScript application workflow
accepts its own selected path directly.
## CLI
The one-shot CLI returns complete Evidence by default. For compact output,
explicitly retain it in a bundle:
```bash
rea inspect-desktop-application /artifacts/MyApplication \
--detail summary --evidence_output /reports/application.evidence.json --json
```
This returns `summary` Evidence and an `evidence_bundle` publication receipt.
Existing output files are never overwritten. Summary delivery requires
`--evidence_output`, checked before analysis. `inspect-evidence-bundle` selects
saved records; an exact saved record can also feed `inspect-analysis-view`.
`--detail complete` returns source Evidence inline and can optionally write the
same bundle. Export writes only the caller-selected output file.
## Facts and uncertainty
| Family | Evidence used |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| .NET | A PE optional header declares a nonempty CLI directory. |
| Unity Mono | A managed assembly below `*_Data/Managed` or `Contents/Resources/Data/Managed` has an exact UnityEngine assembly reference. |
| Unity IL2CPP | A recognized IL2CPP metadata magic (with the raw version when complete) coexists with a conventionally named native `GameAssembly.dll`, `GameAssembly.so`, `GameAssembly.dylib` or `libil2cpp.so` image. Build correspondence remains unknown. |
| Godot | A `GDPC` header at file start or a validated executable trailer offset. |
| GameMaker | A bounded `FORM` container starts with a `GEN8` chunk. |
| Unreal | `Content/Paks` path conventions or an IoStore TOC signature; arbitrary `.pak` filenames are insufficient. |
| Electron | A `resources/app.asar` or `resources/default_app.asar` path convention; archive validity is unverified. |
When the four-byte metadata magic is present but version bytes are incomplete,
the fact retains `raw_version: null`; it does not offer an IL2CPP metadata
inspection probe. A complete magic/version prefix with supported raw version 29,
31 or 39 offers an
`inspect_il2cpp_metadata` follow-up at its admitted file path, including when no
native library was found. This probe does not establish full metadata validity
or correspondence to a native binary. See [IL2CPP metadata](il2cpp-metadata.md).
Candidates are derived or inferred from these facts and do not prove loading or
execution. BepInEx, MelonLoader, Easy Anti-Cheat and BattlEye labels identify
path conventions only; runtime presence stays unknown. No bypass is provided.
`file_id` includes the admitted root namespace, recorded path and available filesystem identity. The caller-selected root path and admitted canonical path/root identity are both retained; `local_path` identifies each observed file for follow-up operations. The selected root may be a symlink; child symlinks are not followed. Exact
metadata integers remain decimal strings. Read ranges have offsets, byte counts
and SHA-256 digests; typed facts expose CLI RVAs, metadata/pack versions and
assembly tokens. Directory and symlink identities unavailable from traversal
remain null.
The directory's `snapshot_sha256` commits to retained paths, omission kinds,
available metadata and range digests, composed through the admitted root,
entry and omission identities. Caller ceilings, coverage counters, diagnostic
wording and interpretation facts remain in Evidence, outside source identity.
The same observations under different generous limits share a snapshot digest;
Evidence IDs still preserve request parameters and reported coverage. Different
retained entries or read ranges change the source snapshot.
Omission records share the entry and representation budgets and can be fetched
independently through their view.
**It is not a digest of all file contents.** These are sequential stable entry
observations, not an atomic directory snapshot. Unread bytes remain unknown.
## Resource bounds and reuse
Defaults are 20,000 examined entries and 8 MiB of total probe reads. Callers may
select up to 100,000 entries and 64 MiB. A separate 32 MiB conservative
representation budget bounds retained paths and facts before growth. Limits
and failed probes produce partial coverage. Traversal and reads are serial.
Each reader admits one inspection at a time; overlapping requests receive a
retryable capacity refusal without cancelling the admitted caller.
Unity reference decoding stops after a witness in each `Data/Managed` directory;
other assemblies' references remain unexamined, while their headers are still
checked. AssemblyRef facts decode names and tokens only; they do not decode or
hash unrelated key/culture/hash payloads or establish runtime binding. Pack contents, encrypted data, metadata/address correspondence and
section-embedded PCKs without a trailer are separate capabilities.
Filesystem results are not cached across calls. Retained views reuse validated
immutable metadata without rescanning files or retaining another inventory.
+41 -5
View File
@@ -33,6 +33,12 @@ encoded path separators, ASAR directories or links, and nonexistent paths are
rejected. The endpoint exposes every eligible target and its local path
metadata.
Cancellation stops further file authorization after an already-started filesystem
operation settles. ASAR descriptor-close failures remain typed incomplete cleanup
with an exact retryable owner; they are not treated as a missing or unauthorized
page. A later authorization and provider shutdown retry retained descriptors
before reporting their release.
## Workflow
`list_electron_targets` returns every eligible target served by the supplied endpoint in one inline array.
@@ -68,7 +74,12 @@ Script metadata retains its execution-context frame ID when CDP supplies one. Th
inventories worker, service-worker, and shared-worker targets with
validated opener-target and parent-frame IDs. Worker discovery uses passive
target metadata; REA does not attach to or execute code in those targets.
Collection counts and aggregate script-source bytes are not capped. Like every
Script-source collection retains at most 32 MiB of UTF-8 text across scripts
and shares a 20-second collection deadline. Omitted sources retain their script
metadata and an explicit reason; later smaller sources may still fit after an
oversized source is omitted. The separate 64 MiB CDP response limit bounds one
wire message before retention admission, rather than total transient memory.
The source budget adds no script-count cap. Like every
target, frame, script, and resource, a worker URL must resolve to a local
file before it is retained. Relationship IDs improve
attribution but do not prove which static module started a worker or that its
@@ -105,7 +116,9 @@ The CLI and MCP surfaces accept the same schema. For a JSON request file:
rea capture-electron-scenario scenario.json --json
```
The result records action status and targets, correlated app/window/WebContents,
The result records one status and target per declared action; actions after a
failed or cancelled action are not run and are recorded as `cancelled` with a
not-executed error. It also records correlated app/window/WebContents,
preload, session, navigation, shell, permission, popup, download, protocol,
native-addon, process, and IPC timeline events. IPC channels and argument-shape
metadata retain their observed lengths; payload values are never retained.
@@ -193,8 +206,25 @@ Caller-defined `.listener` properties can change the identity exposed by
wrapper recognition. Re-registering a raw recording wrapper on another channel
retains the original registration's channel attribution.
Mutating `.listener` on a raw recording wrapper can also prevent removal through
application decorators; the reproduced identity conflict is tracked in
[#4513](https://github.com/morluto/rea/issues/4513).
application decorators that bypass the hook's removal methods. When a removal
request reaches the hook's methods and its registration order is known, private
callback ownership preserves removal by the original function and the newest
matching registration when public metadata is changed or deleted. Native removal
still determines getter execution, exceptions and removal meta-events.
If registration or removal methods differ from the Node methods captured at hook
initialization, the hook leaves listener callbacks unwrapped and records a
`listener-registration` observation gap. The application keeps its original
callback and receiver; callback execution remains unobserved. This comparison
assumes Node's EventEmitter prototype has not itself been globally decorated
before hook initialization. The provider loads the hook before the application
and excludes `NODE_OPTIONS` from the child environment.
An opaque later listener or unsupported emitter state can prevent proof of
removal order. The hook then delegates removal
to the native method and records a `listener-removal` gap rather than claiming
which registration was removed. These gaps are distinct from dropped records
and do not establish IPC delivery or successful removal.
### Target fuse prerequisites
@@ -215,4 +245,10 @@ application path and capture outcome to the static graph, while frames, scripts,
workers, and execution claims remain unavailable until a separate passive runtime
capture provides them.
ASAR observation reads the header through one open file handle, validates its declared lengths against the archive size, and limits encoded JSON headers to 16 MiB before parsing. The header cache also retains at most 16 MiB of encoded headers across eight archives. Oversized headers produce a scope refusal.
ASAR observation reads the header through one open file handle and validates its
declared lengths against the archive size. Header/index admission is the same
fixed 16 MiB / 16777216 byte budget used by static ASAR reads. This release has
no runtime override. An oversized header is not parsed; selecting a member path
does not bypass admission, and the page stays unauthorized. The header cache
separately retains at most 16 MiB of already-admitted encoded headers across
eight archives. Evicting that cache does not raise admission.
+587 -17
View File
@@ -28,6 +28,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -64,6 +91,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -100,6 +154,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -136,6 +217,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -172,6 +280,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -208,6 +343,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -244,6 +406,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -280,6 +469,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -316,6 +532,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -352,6 +595,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -388,25 +658,82 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"properties": {
"logical_path": { "type": "string" },
"declared_sha256": {
"anyOf": [{ "type": "string" }, { "type": "null" }]
"anyOf": [
{
"type": "object",
"properties": {
"logical_path": { "type": "string" },
"declared_sha256": {
"anyOf": [{ "type": "string" }, { "type": "null" }]
},
"calculated_sha256": {
"anyOf": [{ "type": "string" }, { "type": "null" }]
},
"unpacked": { "type": "boolean" }
},
"required": [
"logical_path",
"declared_sha256",
"calculated_sha256",
"unpacked"
],
"additionalProperties": false
},
"calculated_sha256": {
"anyOf": [{ "type": "string" }, { "type": "null" }]
},
"unpacked": { "type": "boolean" }
},
"required": [
"logical_path",
"declared_sha256",
"calculated_sha256",
"unpacked"
],
"additionalProperties": false
{
"type": "object",
"properties": {
"logical_path": { "type": "string" },
"algorithm": { "type": "string", "const": "md5" },
"declared_md5": {
"type": "string",
"pattern": "^[a-f0-9]{32}$"
},
"calculated_md5": {
"anyOf": [
{ "type": "string", "pattern": "^[a-f0-9]{32}$" },
{ "type": "null" }
]
},
"unpacked": { "type": "boolean" }
},
"required": [
"logical_path",
"algorithm",
"declared_md5",
"calculated_md5",
"unpacked"
],
"additionalProperties": false
}
]
}
},
"required": [
@@ -446,6 +773,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -482,6 +836,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -518,6 +899,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -554,6 +962,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -590,6 +1025,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -626,6 +1088,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -662,6 +1151,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -698,6 +1214,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
@@ -734,6 +1277,33 @@
"required": ["action"],
"additionalProperties": false
},
"recovery": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_input_contract" },
"operation": { "type": "string", "minLength": 1 }
},
"required": ["kind", "operation"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "inspect_timeout_state" },
"operation": { "type": "string", "minLength": 1 },
"timeout_ms": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": ["kind", "operation", "timeout_ms"],
"additionalProperties": false
}
]
},
"details": {
"type": "object",
"propertyNames": { "type": "string" },
+5 -1
View File
@@ -106,7 +106,11 @@ CLI keeps its existing complete result.
Inputs are limited to 4 MiB, complete replies to 16 MiB and combined diagnostic
output to 1 MiB. An owned worker has a 256 MiB JavaScript heap, 3 GiB virtual
address-space limit, 30 CPU seconds and a 30-second command deadline. Virtual
address-space limit and 30 CPU seconds. The worker command deadline is
`timeout_ms` (default 30000 ms, integer 1 through 2147483647) on the next call,
or `--timeout-ms` on `rea inspect-evm-interface`. Omission keeps 30000 ms.
Those byte, address-space, and CPU ceilings have no runtime override, and
`timeout_ms` does not raise them. Virtual
address space differs from resident memory. The worker retains inherited tighter
soft/hard limits, reports its configured soft limits inline and leaves hard limits
unchanged. WASM trap reservations are disabled
+25 -1
View File
@@ -158,10 +158,34 @@ tree semantics, vulnerability scanning, emulation or hardware runtime capture.
Supply a stable copy within the allowance. No in-place source modification.
- One queued heavy operation per provider instance; Binwalk one thread and
Unblob one worker. No automatic parallel extraction engines.
- **120-second** deadline; inherited **1 GiB per-process address-space** limit,
- Analysis defaults to **120 seconds**, from tool resolution and input snapshot
through inspection and its final private-workspace cleanup, or extraction
through report consumption and inventory, excluding queue waiting and retained
cleanup admission. Inspection has no publication phase. Select `analysis_timeout_ms` in either MCP operation or
`--analysis-timeout-ms` in either CLI command for slower analysis. Current
results retain the actual budget; an absent historical value means unknown.
Extraction publication and its final
cleanup start a separate **120-second** budget; select
`publication_timeout_ms` in MCP or `--publication-timeout-ms` in CLI for a slow
destination. Valid budgets are integers from 1 through 2,147,483,647 ms (the
timer representation limit). Publication timeouts identify their phase and
verified file progress; verified writes before atomic commit are not a claim
that output remains published after rollback. Caller cancellation applies to
both phases and final cleanup. Phase handoff, publication commit and final
completion also check monotonic elapsed time, so delayed timer callbacks
cannot revive an expired budget.
- Analysis timeout recovery names the selected budget and the analysis control,
not the later publication control. Keep the client call timeout above analysis,
publication and cleanup headroom; keep the input/range/question unchanged.
Resolve any reported incomplete cleanup before retrying. Raising wall time
does not raise fixed CPU, memory, report, diagnostic or input limits.
- Inherited **1 GiB per-process address-space** limit,
120 CPU seconds and zero core-dump allowance through `prlimit`.
- JSON reports: at most **8 MiB** and valid UTF-8; malformed encoding and
oversized reports fail without repairing or truncating producer data.
Exit status 0 is not an empty result: a missing, empty, malformed or
oversized report fails with `unreadable_output`, its `report_state`, the
command, exit status and captured output. REA does not retry automatically.
Diagnostic output is bounded with exact captured byte counts.
- Default staging budget: **256 MiB** and **10,000 entries**, configurable using
`max_output_bytes` / `max_output_files` (CLI `--max-output-bytes` /
+3 -1
View File
@@ -23,7 +23,9 @@ rea inspect-dart-aot /targets/Example.apk --abi armeabi-v7a
The equivalent MCP methods are `identify_flutter_build` (with `path`) and
`inspect_dart_aot` (with `path` and an optional `abi`; the default prefers
arm64-v8a, then x86_64, then x86, then armeabi-v7a, then the remaining
ABIs alphabetically).
ABIs alphabetically). An explicit `abi` is the directory label exactly as
`identify_flutter_build` reports it, so a payload under a nonstandard label
stays selectable and keeps that label in the result.
## Optional retained AOT delivery
+17 -1
View File
@@ -6,8 +6,24 @@ For remote devices, pass a host with an optional port (`host[:port]`; bracket IP
MCP exposes `list_frida_devices`, `list_frida_processes`, `start_frida_session`, `load_frida_script`, `resume_frida_session`, `unload_frida_script`, `frida_session_status`, and `close_frida_session`. A spawned process starts paused so scripts can load first. Closing unloads session scripts and detaches. If a spawn remains paused, REA resumes it only after script cleanup or session detach confirms the instrumentation is released; if both cleanup paths fail, the target stays paused and the cleanup error is retained. REA never kills the target. MCP sessions end with the server process. The one-shot CLI command `instrument-with-frida` accepts one inline script or script file, observes messages for a bounded duration, and returns Evidence with the source hash and captured messages.
For state and capture-coverage checks, pass `{"session_id":"SESSION_ID","detail":"summary"}` to `frida_session_status`. Each call reads the observed session state and retains the complete observation. The reply is an `inspect_analysis_view` Evidence summary with the session identity, state, scripts, `messages_retained`, and `messages_truncated`; message payloads remain in its `parent_evidence_id`. The count covers retained queued messages, not every target event. Omitted `detail` or `detail=complete` preserves the existing complete reply.
A summary's selected fields look like this (excerpt):
```json
{
"summary": {
"state": "running",
"messages_retained": 50,
"messages_truncated": false
}
}
```
Use `get_evidence_bundle` with `detail="summary"` and `filters={"evidence_id":"PARENT_ID"}` to discover parent metadata without message payloads. Filters apply only to summary delivery. Use `export_evidence_bundle` for the complete canonical bundle, then select the record whose `evidence_id` matches `normalized_result.parent_evidence_id` from the status summary. To use the existing CLI `inspect-analysis-view`, extract that record into a standalone Evidence JSON file and select it as an Evidence-file source with `view={"kind":"summary"}`. Reading retained Evidence does not refresh a live session or verify a process after exit or PID reuse.
Failed startup cleanup retains acquired Frida handles, including a paused spawn that has not attached, for later cleanup retries. Its remote connection stays leased until session detach and target resume complete. CLI commands await provider cleanup before returning; MCP retains these resources for cleanup when its server closes. Server shutdown stops admitting new Frida operations and waits for admitted startup, discovery, and queued work before releasing their resources. A failed cleanup remains reported and can be retried by closing the server again, rather than treating an unregistered session as fully released.
Frida scripts execute inside the selected target with that process's memory, filesystem, and network authority. Message capture is bounded to 16 MiB and reports truncation. Script source is not stored in Evidence; its selected path and SHA-256 digest are. Evidence retains non-authentication target selection such as device or endpoint, mode, program or PID, and spawn arguments. Authentication values remain excluded. Results report the observed session and messages, while unsupported platform metadata remains unknown. A request cancelled before a Frida operation starts has no provider effects. If cancellation arrives during a native Frida call, REA waits for that call to return, then closes any session it created and returns the observed session as a partial observation. A cancelled script load on an existing session releases only its new script before queued operations can run; the session and previously loaded scripts remain available. Once the provider commits a successful load, later request cancellation does not unload that script; use `unload_frida_script` to release it. If script cleanup fails, the script remains owned and a paused target cannot resume until the pending instrumentation is released. Queued script loads, resumes, and unloads check cancellation before dispatching native effects. Cancellation Evidence separately reports whether a target resume was observed, whether instrumentation cleanup completed, and that final target liveness remains unknown. REA does not kill the target. Remote discovery retains its observations and reports a separate cleanup error if the temporary connection cannot be removed.
Frida scripts execute inside the selected target with that process's memory, filesystem, and network authority. Local device lookup waits 1000 ms. This release has no runtime override for that lookup; another REA timeout does not raise it. Remote endpoints do not use that lookup. Message capture is bounded to 16 MiB and reports truncation. Metadata, type, and text field caps, and the JSON node cap, are also fixed. Evidence names a cap when that observation actually dropped data. This release has no runtime override for those capture caps. Script source is not stored in Evidence; its selected path and SHA-256 digest are. For a file, `source_sha256` identifies the original selected bytes. Invalid UTF-8 continues to use replacement decoding; Evidence then records that limitation and `raw_result.source_representation` with the encoding, decoding mode, and `loaded_source_sha256` of the UTF-8 string passed to Frida. Valid UTF-8 files and inline scripts do not need this additional representation fact. Evidence retains non-authentication target selection such as device or endpoint, mode, program or PID, and spawn arguments. Authentication values remain excluded. Results report the observed session and messages, while unsupported platform metadata remains unknown. A request cancelled before a Frida operation starts has no provider effects. If cancellation arrives during a native Frida call, REA waits for that call to return, then closes any session it created and returns the observed session as a partial observation. A cancelled script load on an existing session releases only its new script before queued operations can run; the session and previously loaded scripts remain available. If cancellation is observed when the native call returns, partial Evidence retains the source identity and captured messages even if that call rejects, including messages emitted during awaited cleanup. The caller's cancellation reason remains primary and a native rejection is retained as a sanitized diagnostic. A failure already observed before cleanup stays primary if cancellation arrives during cleanup. The cancellation cutoff is REA's observation of native completion, rather than a claim about unobservable native event order. `script_id` is REA's load-attempt identity. When creation rejects without returning a handle, `script_cleanup: "no_handle"` means REA acquired no handle to unload; it does not prove that the engine performed no work. Once the provider commits a successful load, later request cancellation does not unload that script; use `unload_frida_script` to release it. If script cleanup fails, the script remains owned and a paused target cannot resume until the pending instrumentation is released. Queued script loads, resumes, and unloads check cancellation before dispatching native effects. Cancellation Evidence separately reports whether a target resume was observed, whether instrumentation cleanup completed, and that final target liveness remains unknown. REA does not kill the target. Remote discovery retains its observations and reports a separate cleanup error if the temporary connection cannot be removed.
The [Frida Core API](https://frida.re/docs/frida-core-api/) documents device management, sessions, and script loading; the [JavaScript API](https://frida.re/docs/javascript-api/) documents target-side instrumentation. [Luma](https://luma.frida.re/) is Frida's standalone GUI; REA does not automate or control it. `npm run verify:frida` requires a Linux host with the optional Frida binding and uses a short-lived local Node.js fixture created by the verifier. Add `-- --address HOST:PORT --pid PID` to run the separate remote attach lane against a caller-selected target. Mock tests do not establish real device/server compatibility.
+50
View File
@@ -19,6 +19,56 @@ requires an absolute filesystem path and preserves that exact selection:
}
```
For build identity and counts, select `detail: "summary"`. MCP retains the same
complete Evidence and returns `normalized_result.parent_evidence_id`. Read
selected dependency versions without reopening the file:
```json
{
"name": "inspect_analysis_view",
"arguments": {
"source": {
"kind": "retained-evidence",
"evidence_id": "ev_<parent digest>"
},
"view": {
"kind": "go",
"collection": "dependencies",
"paths": ["golang.org/x/crypto"],
"fields": ["path", "version", "replacement"],
"offset": 0,
"limit": 10
}
}
}
```
Go views support `dependencies` (exact `paths`) and `settings` (exact `keys`),
optional original `indices`, field selection, and pagination. Filters intersect;
empty filter arrays select no rows and `fields: []` returns only row identity.
Each row keeps its original `index`, scoped to the parent Evidence and collection;
duplicate module paths and setting keys keep distinct indices. Page offsets
count matching records. Exhausting retained rows does not establish complete
runtime dependencies. Original bytes, unknown lines and all complete metadata
remain in the parent and can be exported as an Evidence bundle.
One-shot CLI summaries save complete Evidence before returning the projection:
```bash
rea inspect-go-binary ./application --detail summary --evidence_output ./go-evidence.json --json
```
`--evidence_output` is required for CLI summary delivery and never overwrites an
existing file. The default CLI/MCP reply remains complete.
[Measured workflows](../experiments/analysis-efficiency/go-build-views.md) include
catalog repetition and extra calls. Identity/count questions benefit from a
single summary. In the tested Codex full-catalog configuration, a compound
question about identity and one dependency uses fewer tokens in captured request JSON with
one complete inspection than with a summary followed by a lookup. The complete
reply remains useful for that initial question; retained views support later
selected reads. Token figures are serialization estimates, not model usage.
## Observations
The inline Evidence result contains the artifact path, SHA-256, byte length,
+108
View File
@@ -0,0 +1,108 @@
# Godot PCK archives
`inspect-artifact` and `extract-artifact` read ordinary Godot PCK formats 2, 3
and 4 without running the game or requiring Godot. Official Godot 4.4.1, 4.6.1
and 4.7.1 produced these respective formats in verification; other engine
releases have not been verified. Format 1 is unsupported.
Inspection retains the original header and directory facts, including engine
version, flags, declared file count, source paths, offsets and declared MD5.
Observed plaintext bytes receive content-addressed SHA-256 identities. MD5 is a
container integrity claim, separate from the observed SHA-256. A mismatch fails
by default; `--integrity-policy record-and-continue` retains the observed bytes
and an explicit untrusted contradiction. An all-zero MD5 is an unknown claim,
not a verified digest.
## CLI
Start with a compact summary and keep the complete Evidence bundle:
```sh
rea inspect-artifact /artifacts/game.pck --detail summary \
--evidence_output /evidence/game.json --json
rea extract-artifact /artifacts/game.pck --json
```
Summary delivery requires `--evidence_output` and never overwrites that file.
The response contains `summary` Evidence and an `evidence_bundle` receipt.
Without `--detail summary`, inspection keeps its complete inline delivery.
Extraction creates a new temporary directory and returns its path. It rejects
unsafe paths and verifies container identity before creating output.
The same CLI commands locate a PCK at the beginning of a file or through its
12-byte EOF trailer in an executable carrier. They do not scan arbitrary
payloads or discover packs behind additional trailing signatures. The root
content SHA-256 covers the whole carrier; its content classification remains
native, while the inventory records the PCK role and exact pack bounds.
Ordinary native `open_binary` detection remains unchanged.
## MCP and selected facts
For a standalone pack, call `open_binary` with its absolute path, then
`inspect_artifact` with `{"detail":"summary"}`. The complete inspection and its
nested inventory stay in the session. Use the summary's
`normalized_result.parent_evidence_id` as the source of subsequent views:
```json
{
"name": "inspect_analysis_view",
"arguments": {
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": {
"kind": "inventory",
"collection": "occurrences",
"logical_paths": ["scripts/main.gd", "project.binary"],
"fields": [
"logical_path",
"declared_integrity",
"hash_status",
"format_metadata"
],
"offset": 0,
"limit": 32
}
}
}
```
Occurrences retain `occurrence_id`, `artifact_id` and `parent_occurrence_id`
even when `fields` is empty. Batch occurrence IDs with `occurrence_ids`, or
join returned content IDs to `collection: "nodes"`, `artifact_ids: [...]` and
`fields: ["sha256", "size"]`. Filters intersect; an omitted filter selects all
available rows and an empty array selects none. Pagination follows the filtered
canonical order. Multiple occurrences may share one content ID.
Views reuse authenticated immutable inventory facts and lazy lookup indexes;
they do not reopen the source. These are historical observations, including
after the source changes or disappears. Close the target with `close_binary`
when finished. To read an exported bundle through the CLI, select its complete
inspection record as `source: {kind: "inline", evidence: ...}` in a JSON request
file for `rea inspect-analysis-view request.json --json`.
## Coverage and limits
PCK summaries expose root format metadata, available graph counts,
`available_hash_status_counts`, and `source_coverage`. Inventory pages preserve
producer coverage alongside page coverage. `source_complete` means all declared
retained graph rows are available; it does not establish that an encrypted or
otherwise unknown directory was examined. Missing matches in unknown coverage
are not evidence of absence.
Encrypted directories retain their header and declared file count with unknown
entry coverage. Individually encrypted members retain directory metadata with
unknown content identity; REA does not decrypt them. Sparse bundles likewise
retain header facts with unknown member coverage. Extraction refuses an
unreadable directory or encrypted member. This capability does not recover
keys, decode Godot resources, decompile GDScript bytecode, analyze signals,
apply patch/removal entries or execute targets.
Readable logical member bytes, including repeated physical ranges, share the ZIP
archive expansion policy: at most the larger of 256 MiB or 500 times the PCK's
encoded byte span. Embedded carrier bytes do not enlarge that budget. The full
directory is checked before any member is yielded, hashed or extracted. Encrypted
members are not read and do not consume this plaintext-work allowance. Small
bounded aliases remain valid. This is a processing/output resource bound, separate
from the directory metadata retention budget and format validity.
+166
View File
@@ -0,0 +1,166 @@
# Static CUDA and HIP code objects
`inspect_gpu_code_objects` answers which GPU targets and kernel declarations a
local artifact carries. It reads ELF/PE sections, standalone CUDA fatbins,
CUBIN/PTX and Clang HIP bundles, including CCOB v1/v2/v3. It neither executes the
artifact nor invokes CUDA/ROCm tools. GPU execution, SASS disassembly and host
launch correlation remain outside coverage.
Start with a target inventory:
```json
{ "path": "/artifacts/library.so", "view": { "collection": "targets" } }
```
Target rows aggregate inventoried payloads and distinguish an unrequested kernel
analysis from a complete or partial one. `objects` pages expose exact object
IDs, compression declarations and encoded/header locations. Fields, exact
filters, batch IDs and stable pagination select the facts delivered to the
caller. IDs are positional within the recorded artifact SHA-256. Selecting `object_ids`
in a new inspection requires `expected_sha256` from that inventory; a changed
file is rejected before parsing selected payloads.
`target` is the inventory declaration used for selection; `payload_target` is
the independently observed inner declaration when available. Object pages keep
both values, their kind, `target_consistency` and inspection coverage even with
selected fields.
Conflicting base architectures retain both values, mark object/report/target
coverage partial and annotate the affected kernels. CUBIN flags establish a base
architecture: `base-only` explicitly leaves feature-profile agreement unknown,
including `a` variants. A standalone declaration is `single-source`, and
unexamined payloads remain `unexamined`. An exact AMDGPU target is normalized at
its note owner for comparison with a Clang bundle declaration; raw values remain
intact. Unresolved feature comparisons stay `unknown`.
`cuda_target_header` retains the OS ABI, normalized raw `e_flags` and exact
header location. CUDA OS ABI `0x33` and the observed `0x41` flags layout use
different architecture fields; they are decoded at one ABI-aware owner.
Unrecognized layouts keep the header and an unknown target instead of
inventing an SM label. Header provenance is validated against its CUBIN object.
Target filters select inventory declarations. An unselected payload's inner
target remains unexamined; an empty filtered result does not establish that
no enclosed code declares that target. Discovering every inner declaration
requires decoding those payloads.
HIP IDs with one or two separators before the architecture retain the declared
target. If a recognized AMDGPU bundle ID does not expose a target, the same
bounded note-discovery owner used for standalone AMDGPU files establishes it
before filtering. Those directory/note reads share the inspection work budget;
successive queries can select the target returned by inventory.
Decode selected targets and return a kernel page in the same call:
```json
{
"path": "/artifacts/library.so",
"analysis": "kernels",
"targets": ["sm_100"],
"view": {
"collection": "kernels",
"names": ["kernel_name"],
"fields": [
"name",
"parameter_count",
"parameter_bytes",
"parameters",
"registers",
"shared_bytes"
]
}
}
```
Only selected payloads are decoded. Other inventory entries remain present with
`not-selected` states, and overall payload coverage remains partial. An empty
kernel page proves no matching retained fact; it does not establish that an
unexamined payload contains no kernel. Missing fields remain null.
Kernel representations have different meanings:
- PTX reports parameter declarations and virtual registers. Shared bytes cover
supported static declarations inside that entry; they do not establish module
shared memory, dynamic allocation or physical device resources.
Scalar register declarations count each bare or percent-prefixed name and
each parameterized range. Unsupported declaration forms or overflowing totals
retain an unknown count and partial decoding coverage. Unsupported parameter
layouts and unknown shared-memory declarations likewise retain their known
facts, explicit limitations and partial coverage through retained pages.
- CUBIN identifies CUDA entry symbols and reads numeric `nv.info` records and
native section declarations. Global register declarations also cover compiler
versions that leave the older text-section register field empty.
- AMDGPU reads v3+ MessagePack notes. Argument counts include hidden ABI arguments
when present; SGPR/VGPR counts and fixed group/private segment sizes retain
their declared meanings. Legacy YAML metadata remains unsupported.
Each selected PTX payload becomes a retained UTF-8 text artifact with a SHA-256,
byte length and source coordinates. It is omitted from compact replies. Read it
with `inspect_analysis_view` and the parent Evidence ID returned by the compact
receipt:
```json
{
"source": { "kind": "retained-evidence", "evidence_id": "ev_..." },
"view": {
"kind": "gpu-code-objects",
"collection": "ptx",
"object_id": "...",
"offset": 0,
"limit": 4096
}
}
```
Text offsets use UTF-16 code units and must fall on Unicode scalar boundaries.
Complete Evidence retains the selected text; `export_evidence_bundle` provides
its portable source record. Historical pages never reopen the input file.
A location with `container_id: null` uses original file offsets. Other locations
use that inventoried object's decoded byte coordinates. Follow its parent,
encoded location and digest to trace decompressed metadata back to a native
section and the original file. Decoded offsets are never presented as physical
file offsets.
The CLI uses the same service and contracts:
```sh
rea inspect-gpu-code-objects /artifacts/library.so --analysis kernels \
--targets '["sm_100"]' --detail summary \
--view '{"collection":"kernels","names":["kernel_name"]}' \
--evidence_output /analysis/library-gpu.evidence.json --json
```
A full-file SHA-256 always streams every byte. Inventory then reads bounded
native directories and bundle headers; CCOB requires decompression to discover
its inner directory. Kernel analysis reads selected payloads. `bytes_read`
includes hashing and subsequent descriptor reads, so this is not a header-only
hashing workflow.
CUDA raw LZ4 blocks and Zstd, and CCOB zlib/Zstd are supported. Unknown versions
or codecs retain declarations with explicit limitations. Lengths are checked
before decoding, and CCOB's truncated MD5 is verified against decoded bytes.
Resource limits are one active inspection, 128 MiB per input/output buffer,
512 MiB of payload input, decoded output and AMD note-read work per inspection,
and 16 MiB retained facts including selected PTX. Payload work is reserved before
reading or allocating; a capacity refusal does not reread an aliased payload.
Native tables and decoded section names each have a 16 MiB structural budget;
AMDGPU ELF note discovery admits at most 8 MiB of source note bytes, with
bounded depth and container/string allocations. Standalone AMD targets are read
from those notes before target selection; selected kernel analysis reuses the
same parsed declarations. Pages have a
1 MiB response budget. Resource refusals and interrupted observations preserve
known facts and explicit uncertainty.
CUDA ELF parsing additionally shares a 262,144 record/symbol visit limit,
128 MiB of cumulative metadata section reads, and a 16 MiB serialized-size
accounting budget for temporary index facts. These limits are checked before
index growth; they are not claims about JavaScript heap size. Equivalent scoped
metadata byte ranges and repeated equal register declarations are coalesced;
conflicting values remain unknown. Parameter sections are parsed once per ELF.
Missing CUBIN symbol tables or unresolved section names produce `partial`
object, report and target coverage even when some kernel facts survive. AMD note
failures preserve earlier successfully parsed declarations and the original
failure reason. Standalone PTX recognition tries a small header first, then
continues within the existing 16 MiB text budget when leading comments or
whitespace obscure its directives; admitted full-file probe bytes are reused.
+10 -1
View File
@@ -41,6 +41,15 @@ rea function /absolute/path/to/program main --json
rea decompile /absolute/path/to/program main --json
```
If the registration cannot be read or validated, provider diagnostics retain its
selected `registration_path` and the configuration owner's setting/constraint
facts in `configuration_details.settings`, plus `configuration_remediation`.
`configured` means a path was selected, not that it is valid or an IDA connection
was established; failed registrations remain unavailable. Correct
`REA_IDA_MCP_CONFIG` in the next CLI invocation's environment or the MCP server's
launch environment. Restart/reconnect that server after changing its environment;
an export in another shell does not update a running server.
Open the **original input binary** in REA, not an `.idb` or `.i64` database. Its SHA-256 must match IDA's recorded input hash. REA checks the attached identity and image base around each analysis request. A mismatch or target switch fails with recovery guidance. The original input must remain readable by REA; WSL can use its mounted alias while the GUI runs on Windows. Attached profiles, including native mode, refuse universal Mach-O inputs at admission: every slice shares the recorded whole-file hash, so REA cannot verify which slice the GUI loaded. Open a thin file extracted with `lipo -thin` in both IDA and REA, or use headless mode, which analyzes the selected slice.
REA's close operation releases its MCP connection or proxy. It never saves or closes the existing GUI database. External edits remain visible because results are live and are not replayed from snapshots. These checks do not lock the GUI or prove that the database is unpatched.
@@ -133,7 +142,7 @@ Use a package version that actually includes this adapter; repository main can b
{"name":"close_binary","arguments":{}}
```
Opening an MCP target starts its selected provider session; headless opening waits for auto-analysis. Set the agent's MCP request deadline long enough for the target. The registration's optional `timeoutMs` defaults to 300000 for upstream requests. An upstream SDK request that reaches this limit returns `provider_timeout` with its operation and actual request budget. A freshly opened headless worker can briefly report `status: "busy"` from `server_health`; REA re-reads health every 100 ms until the worker answers, the caller cancels, or `timeoutMs` has elapsed since the first read. Each health request is capped by the time remaining in that overall wait, so a stalled read cannot extend the readiness deadline by another full request timeout. Expiry while the worker is still busy produces a retryable `provider_timeout`; no further read is started after the deadline. That error names the busy tool from the last observation, or `unknown` when the worker reported none or a value that is not tool-name-shaped. If a health request itself consumes the remaining wait budget, the same last-busy timeout is returned with the stalled request's captured output. Cancellation during the wait produces `cancelled`. Any other unexpected health payload, including a busy payload with an invalid shape, remains `unreadable_output`. Cancellation drains the current upstream request before cleanup; it does not force-stop GUI analysis. An open request that times out without a completed response retains the private workspace because worker inventory alone cannot prove the request has stopped. `binary_session` reports actual tool availability. Repeated doctor/setup calls are unnecessary when the registration already works.
Opening an MCP target starts its selected provider session; headless opening waits for auto-analysis. Set the agent's MCP request deadline long enough for the target. The registration JSON named by `REA_IDA_MCP_CONFIG` has an optional `timeoutMs` integer from 1 to 2147483647. Omitted means 300000. REA applies an edited value on the next IDA connection after it re-reads that file; an already open session keeps the timeout it connected with. Changing the `REA_IDA_MCP_CONFIG` path itself is read at process start. An upstream SDK request that reaches this limit returns `provider_timeout` naming the effective milliseconds and `timeoutMs`. A shorter inner request is the time remaining inside that ceiling, and the error names both when they differ. A freshly opened headless worker can briefly report `status: "busy"` from `server_health`; REA re-reads health every 100 ms until the worker answers, the caller cancels, or `timeoutMs` has elapsed since the first read. Each health request is capped by the time remaining in that overall wait, so a stalled read cannot extend the readiness deadline by another full request timeout. Expiry while the worker is still busy produces a retryable `provider_timeout`; no further read is started after the deadline. That error names the busy tool from the last observation, or `unknown` when the worker reported none or a value that is not tool-name-shaped. If a health request itself consumes the remaining wait budget, the same last-busy timeout is returned with the stalled request's captured output. Cancellation during the wait produces `cancelled`. Any other unexpected health payload, including a busy payload with an invalid shape, remains `unreadable_output`. Cancellation drains the current upstream request before cleanup; it does not force-stop GUI analysis. An open request that times out without a completed response retains the private workspace because worker inventory alone cannot prove the request has stopped. `binary_session` reports actual tool availability. Repeated doctor/setup calls are unnecessary when the registration already works.
For guided registration, set `REA_IDA_MCP_CONFIG` before `rea setup --client <client>`. Setup includes that file reference in its reviewed plan and preserves it after approval; it does not copy upstream credentials into the agent configuration. For `ida` or `auto` selection, Codex/Kimi setup and doctor use the effective client registration's parsed `timeoutMs` (default 300000 ms) when recommending the agent's per-tool deadline. Existing positive client deadlines remain caller choices. `rea doctor --provider ida --json` validates the registration without starting IDA and explicitly leaves runtime compatibility and target binding for analysis.
+419
View File
@@ -0,0 +1,419 @@
# IL2CPP metadata
`inspect_il2cpp_metadata` / `inspect-il2cpp-metadata` decodes one selected local
Unity IL2CPP `global-metadata.dat` file and returns its assembly images, type
definitions, methods and named members with their owners, plus managed string
literals, by stable index, namespace, range and count,
with the header sections and serialized index widths. It reads the file without
running it and requires no Unity installation, IL2CPP binary, active target,
Hopper, Ghidra or IDA.
Metadata versions 24, 27, 29, 31 and 39 are supported. For example, Unity 2019.4.41f2
wrote version 24, 2020.3.49f1 version 27, 2022.3.30f1
wrote version 29, 2022.3.62f3 wrote 31 and 6000.4.2f1 wrote 39; other Unity
releases that write these numbers have not been checked. Other versions are
rejected as unsupported. Version 24 decoding covers the 264-byte header layout
used by the cited Unity 2019.4 build; earlier 24.x layouts are not inferred from
the version number and are refused when their header or records differ. The path
must name a regular file; directories and symbolic links are rejected.
With `binary_path`, the tool also reads the matching native binary and links
each method to its code address. See [Native method addresses](#native-method-addresses).
## MCP
MCP defaults to a compact summary and retains the complete decoded Evidence in
the session. MCP requires an absolute filesystem path:
```json
{
"name": "inspect_il2cpp_metadata",
"arguments": {
"path": "/artifacts/Data/Managed/Metadata/global-metadata.dat"
}
}
```
The summary retains the complete decoded Evidence in the session and returns a
linked `inspect_analysis_view` overview: artifact identity, metadata version,
index widths and `counts` (`sections`, `images`, `types`, `methods`,
`nested_types`, `fields`, `properties`, `events`, `parameters` and
`string_literals`) without rows. Use `normalized_result.parent_evidence_id` to page
the original rows without reopening or decoding the file:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": {
"kind": "il2cpp-metadata",
"collection": "types",
"offset": 0,
"limit": 64
}
}
```
Collections are `sections`, `images`, `types`, `methods`, `fields`,
`properties`, `events`, `parameters`, `string_literals`, `method_addresses`,
`return_types`, `field_types`, `parameter_types` and `code_gen_modules`. Every returned row includes
its source `index`, scoped by artifact SHA-256 and collection. All collections
accept batch `indices` and `fields`; collections whose rows have a `name` also
accept exact `names`. Types also accept `image_indices`, `namespaces` and
`declaring_types`; methods, fields, properties and events accept
`declaring_types`. Parameters accept exact `method_indices`, so a batch of
method indices retrieves their parameters without reading the entire parameter
table. `parameter_types` accepts the same `method_indices`, resolved through the
retained `parameters` owners; Evidence without `parameters` refuses that filter. Filters intersect, duplicate indices are returned once, and
rows retain metadata order. An empty filter selects no rows; `fields: []`
returns indices only. Omitted fields return the complete selected rows.
For example, after resolving a type index, retrieve selected method facts:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": {
"kind": "il2cpp-metadata",
"collection": "methods",
"declaring_types": [1555],
"names": ["SendMessage"],
"fields": ["name", "declaring_type"]
}
}
```
After finding method indices, parameters can be requested directly:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": {
"kind": "il2cpp-metadata",
"collection": "parameters",
"method_indices": [9785],
"fields": ["name", "method"],
"limit": 64
}
}
```
Historical Evidence that predates these member collections remains queryable.
A missing collection has an unknown (`null`) summary count, and requesting it
reports that it was not collected; it is never presented as an empty inventory. The same holds for Evidence that predates binary linking: its summary
omits `binary`, and `method_addresses`, `method_address_states`,
`return_types`, `field_types` and `parameter_types` counts are `null`.
Existing empty collections retain a zero count. Full Evidence is preserved.
`offset` counts matching rows, not source indices. `limit` defaults to 64;
`coverage.next_offset` continues that filtered page. Coverage describes retained
metadata facts only; runtime behavior and correspondence to native code remain
unknown. Each view preserves the parent Evidence link, artifact identity and
limitations. Queries work after the source file is removed. Select
`detail: "complete"` to return every row inline within the separate MCP response
budget.
## CLI
```bash
rea inspect-il2cpp-metadata /absolute/path/global-metadata.dat --json
```
The CLI defaults to complete Evidence. For compact delivery, explicitly preserve
the full Evidence in a new file:
```bash
rea inspect-il2cpp-metadata /absolute/path/global-metadata.dat \
--detail summary --evidence_output /tmp/metadata-evidence.json --json
jq -c '{source: {kind: "inline", evidence: .records[0]}, view: {kind: "il2cpp-metadata", collection: "methods", indices: [9785], fields: ["name", "declaring_type"]}}' \
/tmp/metadata-evidence.json > /tmp/metadata-query.json
rea inspect-analysis-view /tmp/metadata-query.json --json
```
Use the exported Evidence with the CLI's inline Evidence source format described
in [CLI and Evidence](cli.md#run-a-command). Compact delivery requires
`--evidence_output`; existing files are never overwritten. The full export
preserves every decoded row for subsequent queries without the original file.
`--binary PATH` links method addresses and `--architecture arm64|amd64` selects
the slice of a universal Mach-O.
## Observations
The result contains:
- `artifact`: path, SHA-256 and byte length;
- `magic`: unsigned little-endian header signature (`0xFAB11BAF`, delivered as a JSON number);
- `metadata_version`: `24`, `27`, `29`, `31` or `39`;
- `index_widths`: the serialized widths (1, 2 or 4 bytes) of
`type_definition`, `generic_container`, `parameter` and `type` indices, and
`type_width_source`. Version 39 derives the type index width from the
`interface-offsets-record` or the `type-definition-record`; versions 24, 27, 29
and 31 always use 4-byte indices (`fixed-width-version`);
- `sections`: all version-specific header sections in header order, each with `offset`, `size`
and `count`. Versions 24 to 31 record no counts, so `count` is `null` and
record counts come from the section sizes;
- `images`: `name`, `type_start` and `type_count`;
- `types`: `name`, `namespace`, `method_start`, `method_count`,
`nested_type_start`, `nested_type_count` and `declaring_type`;
- `methods`: `name` and `declaring_type`;
- `fields`, `properties` and `events`: `name` and `declaring_type`, the type
whose member range holds the row (`-1` when none does);
- `parameters`: `name` and `method`, the method whose parameter range holds it;
- `string_literals`: managed string literals as `value`, or `value_base64` with
the exact bytes when they are not valid UTF-8;
- `limitations`.
A row's position in its collection is its metadata index, so `type_start`,
`method_start` and `declaring_type` refer to positions in `types` or `methods`.
`nested_type_start` instead indexes the metadata's `nestedTypes` table, which is
not returned; each nested type's `declaring_type` carries that relationship.
A type's `declaring_type` is derived from the `nestedTypes` section and is `-1`
for top-level types. The start of an empty range can retain the original value
`-1`.
The complete inventory of a large game is several megabytes and can exceed
the MCP response budget. Summary delivery and filtered, projected pages keep
unneeded rows out of agent context without discarding the source Evidence.
## Native method addresses
`binary_path` names the native binary built with the metadata: macOS
`GameAssembly.dylib` (Mach-O), Windows `GameAssembly.dll` (64-bit PE) or
Android `libil2cpp.so` (64-bit ELF, AArch64 or x86-64). A
universal Mach-O needs `binary_architecture` (`arm64` or `amd64`); a thin binary
rejects it. The file is read, never loaded or executed.
A position-independent `libil2cpp.so` stores zero in most pointer slots and
keeps the value in `R_AARCH64_RELATIVE` or `R_X86_64_RELATIVE` relocations
(`DT_RELA`). The reader writes those values into a private copy before
searching it, so addresses are the link-time addresses and RVAs are relative to
the first loaded segment. Android packed
relocations (`DT_ANDROID_RELA`) are refused. No target code is executed.
The binary's `Il2CppCodeRegistration` points to one `Il2CppCodeGenModule` per
assembly image. Each module record starts with its module name, its method
pointer count and its method pointer array. The reader finds, for every metadata
image, the single record whose name pointer reaches that image's name string and
whose count equals the image's method count. It then requires exactly one
`codeGenModulesCount`/`codeGenModules` pair that lists exactly those records. No
symbols are needed, so stripped builds work. A method's token row id selects its
slot in the module's method pointer array.
Module records establish names through their declared NUL-terminated string pointers. NUL/0xFF padding, spaces, Unicode and suffix-shared storage are supported. A pointer to a longer string does not match just its suffix; a pointer directly into a shared suffix may name it. Exact reversed UTF-8 matching avoids rescanning the file for every name and retains duplicate-name owners until module records resolve them. A contributor investigated a Linux
`GameAssembly.so` from Unity 2023.2.13f1 whose static registration was not located. When no static pair is resolved on x86-64, the reader searches executable ranges for bytes consistent with RIP-relative LEA/MOV references to module-array candidates. Exactly one referenced array candidate must remain. `code_gen_modules_field` is then `null`, and Evidence is **inferred**: instruction boundaries, the absence of a static registration elsewhere, and runtime use were not verified. The module records and slots themselves remain file observations. Static-table associations are **derived**. Otherwise the result is `code-registration-not-found`.
The binary/metadata pair is caller-selected. Name/count/token agreement is structural evidence, not a cryptographic same-build proof. File-offset locations refer to the primary metadata artifact; linked virtual addresses refer to `binary.artifact`. Both SHA-256 identities remain available in compact native pages as `artifact` and `binary_source`.
Contributor-reported verification (not all rerun by the follow-up): macOS arm64 and x86_64 slices from Unity 2021.3.45f2, 2022.3.30f1, 2022.3.62f3 and
6000.0.84f1 against dSYM symbols; Android arm64 and x86-64 from 2022.3.62f3
against `libil2cpp.sym.so`; Windows x64 from 2023.2.13f1 (metadata version 29,
the MIT-licensed game Between Two Worlds 1.0.5, `GameAssembly.dll` SHA-256
`a3ae7f6ecd1f671297b7d98d12713ef024062d93cd7a4205298102656c93b67a`) against
Il2CppDumper, where all 43,198 linked methods share an address with a
same-named Il2CppDumper method and identical code folding groups 10,448 methods
into 1,735 addresses. A macOS x86_64 build from Unity 2020.3.49f1 (metadata version 27, which Il2CppDumper reads as 27.1) links 10,555 methods, all at addresses where Il2CppDumper names the same method; its other addresses are generic instances. A build from Unity 2021.1.28f1 (also read as 27.1) gives the same result: 10,345 methods linked, every address named the same by Il2CppDumper, and its other 3,486 addresses generic instances.
These checks compare addresses with symbols or with another static tool. They
do not establish that a linked address is the code the game runs (a runtime may
patch, hook or replace it), that builds from other Unity versions, compilers or
obfuscators link the same way, or that a method without an address has no code:
generic instances, adjustor thunks and invokers are not linked, and an
`unknown` row was not looked up at all.
The result adds:
- `binary`: artifact identity, `format`, `architecture`, `image_base`,
`code_gen_modules_field` (the address of `codeGenModulesCount`, or `null` as
described above), `code_gen_modules_array` (the module pointer array) and
`code_gen_modules` (`image`, record `address`, `method_pointer_count`);
- `method_addresses`: one row per method index with `state`, `address` and
`rva` (address minus `image_base`), both hexadecimal strings. `state` is
`code` when the module slot holds an unambiguously mapped executable address, `no-body` when an observed slot is zero,
as for abstract, extern and most generic methods, and `unknown` when no type
range in any image holds the method or a symbol relocation leaves its slot unresolved.
`address` and `rva` are `null` unless `state` is `code`. The summary counts
each state in `counts.method_address_states`. Ghidra seeds are written only
for `code` rows.
- `return_types`, `field_types` and `parameter_types`: one row per method,
field and parameter index with `type`, the index into the binary's
`Il2CppType` table, and `name`, rendered from that table: C# keywords for
primitives (`int`, `string`, `object`), `Namespace.Outer+Inner` for type
definitions, `T[]`, `T[,]` and `T*`, generic instances as
`System.Collections.Generic.List<string>` and generic parameters by their
metadata name (`TKey`). A trailing `&` marks a by-reference type. `name` is
`null` only for type index `-1`.
`binary` also records `types_field` and `types_count`: the address of
`Il2CppMetadataRegistration.typesCount` and its value. That record is found as
the single place whose `fieldOffsetsCount` and `typeDefinitionsSizesCount` both
equal the metadata type-definition count and whose type table is file mapped.
Without `binary_path`, `binary` is `null` and the four binary collections are
empty in the complete producer report to indicate unrequested observations. Their summary counts, including state counts, are `null`, and native page requests report unavailable observations. This does not establish an empty native inventory. Missing native fields in historical Evidence remain unknown too.
For metadata version 27, type names are `null` and only type indices are
reported: versions 27.0 to 27.2 share that header number but place the
Il2CppType byref flag in different bits, so a rendered name could gain or lose
`&` without warning.
The builds checked are listed after the module search rules above.
| Reason | Category | Meaning |
| --------------------------------- | ----------- | ------------------------------------------------------------------------------------------------- |
| `unsupported-container` | unsupported | Not a 64-bit little-endian Mach-O, PE or ELF image (ELF: AArch64 or x86-64 with dynamic section). |
| `slice-selection-required` | unsupported | A universal Mach-O was given without `binary_architecture`. |
| `slice-not-found` | unsupported | The requested slice is absent, or a thin binary was given an architecture. |
| `unsupported-pointer-encoding` | unsupported | Mach-O chained fixups or Android packed (APS2) ELF relocations; pointers not decoded. |
| `malformed-container` | input error | The container headers are damaged. |
| `code-gen-modules-not-found` | input error | An image has no module record; often a binary from a different build. |
| `ambiguous-code-gen-module` | input error | More than one module record matches an image. |
| `code-registration-not-found` | input error | No unique module table or executable-byte array candidate was resolved. |
| `invalid-method-token` | input error | A method token is not a method row inside its module's pointer count. |
| `invalid-method-pointer` | input error | A slot is unavailable or its nonzero address lacks unambiguous executable file coverage. |
| `metadata-registration-not-found` | input error | No single MetadataRegistration matches the type-definition count. |
| `invalid-type` | input error | A type index or `Il2CppType` record is out of range, unmapped or malformed. |
| `unsupported-type-kind` | unsupported | A valid type kind has no implemented rendering. |
Format and selection failures name `binary_path`; capacity refusals remain typed resource errors. Failed linking preserves the metadata source identity, validated counts, selected binary path/architecture and its SHA-256 when observed, plus prior producer observations. It never publishes an incomplete native table as complete. The binary input is bounded to1GiB.
Scans yield cooperatively in bounded batches. Name-address retention and reverse-trie construction are each limited to65,536 entries/nodes and fallback module-array candidates to64 (`native-index-capacity`); exceeding capacity does not prove absence. Rendered type text has a64MiB UTF-8 cache-workspace guard, separate from the64MiB encoded-report admission, and64 nested rendering frames (`native-type-text-capacity` / `type-nesting-capacity`). Genuine cycles are malformed; unsupported type kinds are explicit coverage failures. Native row/text admission runs before allocation or retention. Unused generic parameter names are read on demand from the same stable metadata snapshot. There is no cross-inspection file cache; validated immutable Evidence is reused for session views.
ELF RELATIVE writes into zero-fill are kept as a private virtual-pointer overlay. Unresolved supported-width symbol relocations, including RELA PLT entries, remain unknown; stored zeros never establish no-body. COPY, TLS descriptor, REL, packed APS2 and other unsupported relocation encodings fail closed. Input bytes are unchanged.
Native address queries batch exact64-bit hexadecimal `addresses` and `states` (`code`, `no-body`, `unknown`), intersecting indices and pagination. Numerically equal address spellings match; original row indices and every shared-body alternative survive:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": {
"kind": "il2cpp-metadata",
"collection": "method_addresses",
"addresses": ["0x180c56ed0"],
"states": ["code"],
"fields": ["address", "rva"],
"offset": 0,
"limit": 64
}
}
```
## Ghidra function names
The CLI can turn a linked report into a
[`REA_GHIDRA_SEED_FILE`](installation.md) so Ghidra names every IL2CPP method
before auto-analysis:
```bash
rea inspect-il2cpp-metadata global-metadata.dat --binary libil2cpp.so \
--ghidra-seeds il2cpp-seeds.tsv --json > /dev/null
export REA_GHIDRA_SEED_FILE="$PWD/il2cpp-seeds.tsv"
```
Each linked method becomes one `function` seed named `Namespace.Type$$Method`
(nested types joined with `.`, whitespace replaced by `_`), the Il2CppDumper
convention. Seeds are at `seed-base + rva`. The default base is where Ghidra's
loaders place the binary: `0x100000` for an ELF linked at 0, and the link base
for Mach-O and PE; `--seed-base 0x...` overrides it for a different import. When
identical code folding gives several methods one address, the first method names
the function and a `# folded <address> <kept> also <names>` comment line after
the seeds lists the others, so the kept name is visibly one of several. Ghidra still names a seeded function that is a thunk after its
target. The file is atomically published with exclusive creation; an existing destination is never replaced. Failed staging retains its cleanup owner for retry. Source digest and link/seed-base comments make the mapping inspectable. Unknown slots are skipped separately from observed no-body slots. `--seed-base` requires `--ghidra-seeds`; overflowing rebased addresses and names/outputs beyond the existing Ghidra protocol limits (2,000 name characters,32MiB file,1,000,000 entries) are refused before publication. The CLI and reusable service use one formatter and owned output workflow; ordinary MCP inspection remains read-only.
## Failures
A file whose magic is not `0xFAB11BAF` fails as an unsupported target with
`unrecognized-magic`. The file may be encrypted or may not be IL2CPP metadata.
A version other than 24, 27, 29, 31 or 39 fails as an unsupported target with
`unsupported-version`.
Damaged metadata returns an input error (`invalid_format`) whose
message names one reason:
| Reason | Meaning |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `truncated-header` | The file is shorter than the header. |
| `unexpected-header-size` | `stringLiterals.offset` is not the header size: 264 bytes for version 24, 256 for 27, 29 and 31, 380 for 39. |
| `section-out-of-bounds` | A section extends beyond the file, or a non-empty section starts inside the header. |
| `section-overlap` | Two sections overlap. Zero-size sections are exempt and gaps are allowed. |
| `record-size-mismatch` | A section size does not divide into its records, or the record size differs from the one the index widths imply. |
| `type-index-width` | The record used to derive the type index width implies no 1, 2 or 4 byte width. |
| `index-out-of-range` | A serialized index or range points outside its target collection. |
| `nested-type-conflict` | A type is listed as nested in two types, in itself, or in a cycle of declaring types. |
| `declaring-type-mismatch` | A method inside a type's method range names a different type, or a method lies outside its type's range. |
| `image-range-overlap` | Two images claim the same type definitions. |
| `invalid-string` | A name index does not start a string, or the name is unterminated or not valid UTF-8. |
A version field that disagrees with the file's layout, for example a version
39 file relabeled as 29, usually surfaces as `unexpected-header-size` or
`record-size-mismatch`.
Two checks are stricter than the IL2CPP runtime: a name index must start a
string, and an empty range's start must lie between -1 and the collection size.
Every Unity-written file checked so far satisfies both; metadata rewritten by
other tools may be rejected.
An incomplete inventory is never reported as complete. Failures after a verified
snapshot retain partial source Evidence with its SHA-256, byte length and any
validated section row counts; these counts do not establish that names and
relationships were decoded. A file that changes during reading and a cancelled
request keep distinct errors. Decode checkpoints yield for cancellation, and
close waits for active work. Each reader admits one inspection at a time.
Resource guards bound the selected file to 256 MiB and the encoded complete
report to 64 MiB, checking row counts before allocation and JSON/UTF-8/base64 expansion during
decoding, before serialization. Names and identical literal spans are decoded
once within one stable file snapshot; no filesystem results are cached across
inspections. Ownership assignment also yields to cancellation. MCP also applies its
[response transport budget](mcp-contracts.md); a complete report within the
report limit can still require the summary and paging path.
## Outside this tool
- Decrypting or deobfuscating protected metadata.
- Linking Mach-O binaries that use chained fixups, ELF images with Android
packed (APS2) relocations, and 32-bit images; generic method instances,
adjustor thunks and invokers.
- Full method signatures beyond the rendered field, parameter and return type
names, generic method instances, and type names for metadata version 27.
- Running Ghidra or another disassembler. `--ghidra-seeds` only writes a seed
file for [`REA_GHIDRA_SEED_FILE`](installation.md); use the
[native workflow](native-investigation.md) for native code.
- Metadata versions other than 24, 27, 29, 31 and 39.
Names come from the metadata file only. They do not establish which methods
were compiled into the native binary or how they behave at runtime.
## Real producer verification
`npm run verify:il2cpp:metadata -- --metadata PATH` exercises a caller-supplied
`global-metadata.dat` through the public CLI and MCP. It is opt-in, like
`verify:pcap`, because no real game metadata ships with the repository. Normal
inspection does not need it.
The follow-up was checked against the public Cpp2IL
[`Simple_2022_3_35` sample](https://github.com/SamboyCoding/Cpp2IL/tree/b5ad444b82267cb1e4b88b8b373c008105bdea52/TestFiles/Simple_2022_3_35):
version 31, 1,892,268 bytes, SHA-256
`2441635a7c234a1a34deccc6a9906d6f5abcbdab078a38b2bf488a52a4962c48`.
An independent byte-layout oracle matched all 36 images, 2,468 types and 12,409
methods. Corresponding managed DLLs independently matched names and ownership
for 35 images, 2,463 types and 12,406 methods; the generated image has no matching
DLL. This does not establish real-producer coverage for versions 29 or 39.
Compact native summaries omit the `binary.code_gen_modules` table and keep its
count in `counts.code_gen_modules`. Query `collection: "code_gen_modules"`
with batch `image_indices` or source `indices`, selected `fields` and pagination.
Module row `index` is its retained collection position; `image` joins the
metadata image collection. Scalar registration facts and both source identities
remain inline. Complete Evidence retains the original full table.
+13 -11
View File
@@ -47,17 +47,19 @@ For runtime instrumentation, see the [Frida guide](./frida-instrumentation.md).
## Choose a guide
| Task | Guides |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-binaries.md), [Rust dependencies](rust-binaries.md), [offline ELF layout](binary-diagnostics.md), [recorded crashes](recorded-crashes.md) |
| Select a native provider or import format | [Ghidra semantics](ghidra-provider.md), [Windows](windows-ghidra-p0.md), [DOS](ghidra-dos.md), [raw bytes](raw-binary.md), [MIPS](ghidra-mips.md), [PSP](ghidra-psp.md), [NativeAOT](ghidra-nativeaot.md), [IDA](ida-provider.md), [Kuna](kuna-provider.md), [JEB](jeb-analysis.md) |
| Analyze JavaScript or Electron artifacts | [Static analysis](javascript-artifact-reconstruction.md), [tracing and comparisons](javascript-application-workflows.md), [application graph](javascript-application-graph.md), [source recovery](javascript-recovery.md) |
| Compare static JavaScript with runtime observations | [Runtime attribution](javascript-runtime-observation.md), [reconciliation](javascript-runtime-reconciliation.md), [Electron observation](electron-observation.md), [Electron fuses](electron-fuses.md) |
| Inspect assemblies, packages, or firmware | [.NET](managed-code-analysis.md), [Android](android-analysis.md), [Apktool resources](apktool-resource-analysis.md), [ADB acquisition](adb-device-analysis.md), [Apple](apple-application-analysis.md), [Harmony](harmony-analysis.md), [firmware](firmware-analysis.md), [WASM](wasm-artifacts.md), [EVM](evm-bytecode.md) |
| Observe or compare a browser scenario | [CDP observation](browser-observation.md), [scenarios](browser-scenario-contract.md), [runtime evidence](web-runtime.md), [historical captures](web-network-captures.md) |
| Trace captured website source | [Source locations](web-source-location.md), [module traces](website-module-trace.md), [script export](website-script-export.md) |
| Capture and compare a command | [Process capture](process-capture.md) |
| Use CLI/MCP and retain evidence | [CLI](cli.md), [MCP contracts](mcp-contracts.md), [agent prompts](mcp-prompts.md), [obligation ledgers](reconstruction-obligation-ledgers.md) |
| Task | Guides |
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Identify a desktop installation | [Runtime candidates, evidence and follow-up files](desktop-applications.md) |
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-binaries.md), [Rust dependencies](rust-binaries.md), [offline ELF layout](binary-diagnostics.md), [recorded crashes](recorded-crashes.md) |
| Select a native provider or import format | [Ghidra semantics](ghidra-provider.md), [Windows](windows-ghidra-p0.md), [DOS](ghidra-dos.md), [raw bytes](raw-binary.md), [MIPS](ghidra-mips.md), [PSP](ghidra-psp.md), [NativeAOT](ghidra-nativeaot.md), [IDA](ida-provider.md), [Kuna](kuna-provider.md), [JEB](jeb-analysis.md) |
| Analyze JavaScript or Electron artifacts | [Static analysis](javascript-artifact-reconstruction.md), [tracing and comparisons](javascript-application-workflows.md), [application graph](javascript-application-graph.md), [source recovery](javascript-recovery.md) |
| Compare static JavaScript with runtime observations | [Runtime attribution](javascript-runtime-observation.md), [reconciliation](javascript-runtime-reconciliation.md), [Electron observation](electron-observation.md), [Electron fuses](electron-fuses.md) |
| Inspect assemblies, packages, or firmware | [Godot PCK](godot-pck.md), [.NET](managed-code-analysis.md), [Python packages](python-packaged-applications.md), [Android](android-analysis.md), [Apktool resources](apktool-resource-analysis.md), [ADB acquisition](adb-device-analysis.md), [Apple](apple-application-analysis.md), [Harmony](harmony-analysis.md), [firmware](firmware-analysis.md), [WASM](wasm-artifacts.md), [EVM](evm-bytecode.md) |
| Observe or compare a browser scenario | [CDP observation](browser-observation.md), [scenarios](browser-scenario-contract.md), [runtime evidence](web-runtime.md), [historical captures](web-network-captures.md) |
| Serve recorded behavior as an agent environment | [Agent environments](agent-environments.md) |
| Trace captured website source | [Source locations](web-source-location.md), [module traces](website-module-trace.md), [script export](website-script-export.md) |
| Capture and compare a command | [Process capture](process-capture.md) |
| Use CLI/MCP and retain evidence | [CLI](cli.md), [MCP contracts](mcp-contracts.md), [agent prompts](mcp-prompts.md), [obligation ledgers](reconstruction-obligation-ledgers.md) |
For development, use [testing](testing.md), [client verification](client-verification.md),
[tool design](tool-design.md), and [releasing](releasing.md).
+66 -6
View File
@@ -24,6 +24,10 @@ Restart the agents named in the completion message. Quit Claude Desktop fully
before approving, because a running app can overwrite the registration; on
Windows, see [where Claude Desktop reads its configuration](client-configuration.md#claude-desktop).
During package resolution, npm may print a deprecation warning for `prebuild-install`
from transitive native dependencies (such as Frida). This warning originates from
the upstream dependency tree and does not affect REA or indicate setup failure.
For the latest published release, use `npx rea-agents@latest setup`.
[Package-runner and global-installation options](#package-runners-and-global-installation)
cover explicit versions, Bun, runtime requirements, and the curl wrapper.
@@ -340,6 +344,13 @@ A scoped report has `scope.mode: "explicit"`. Its `scope_checks` determine
`environment_healthy` summarizes the full audit. `--target` adds a target check,
but the report remains audit-wide unless a scope option is also supplied.
An invalid `REA_LOG_LEVEL` fails every scope, including one client or the
installed skill, because the executable rejects it before any command. A
selected client also fails for every other setting that MCP startup rejects,
including `REA_GHIDRA_STARTUP_TIMEOUT_MS` and `REA_HOPPER_STARTUP_TIMEOUT_MS`.
Those settings still fail a selected provider and the audit-wide result. A
skill-only report leaves them informational.
Follow the remediation for the failed check. If a native target has several
available providers, choose one with `--provider` on the CLI or `provider_id`
on `open_binary`. A `capability_unavailable` failure carries
@@ -376,7 +387,17 @@ Uninstall preserves Hopper, Node.js, Evidence files, captures, unrelated skills
and other MCP servers. Purging removes only REA's cache and state under
`~/.rea`. A client configuration that is malformed, unreadable, or at an unsafe
path stops the operation before anything is removed, and a client that fails
while being updated stops the remaining removals. A purge path that is a
while being updated stops the remaining removals. Uninstall reports each
candidate `configuration_path` with its outcome. A client with multiple files
keeps their individual `actions` alongside its aggregate status and detail,
including earlier removals when a later file fails. The paths name
the discovered configuration candidates, not resolved physical file identities.
For JSON clients, uninstall removes every repeated `rea` member in the effective
server table only when each registration is REA-owned. An unowned earlier
member, or an unowned OpenCode V1 entry that removing V2 would expose, stops
preflight before any
removal. Repeats inside an inactive earlier copy of the server table stay
unchanged. A purge path that is a
symbolic link is retained and reported rather than followed. Uninstall checks
REA's managed shared and Claude Code personal skill locations. See the
[CLI guide](cli.md#output-and-exit-status) for exit statuses.
@@ -599,6 +620,20 @@ host mount and the rest of `/tmp` remain unchanged; this fallback never invokes
`sudo`. `rea doctor --provider hopper --json` reports the selected
strategy and both host and effective mount facts.
Hopper also embeds Python; the Python executable and standard library alone
are insufficient on Ubuntu. Approved setup checks the system interpreter
at `/usr/bin/python3` and, when necessary, installs its matching
`libpython3.X` package, then verifies that its shared library can load.
APT resolves the concrete package (for example, `libpython3.12t64` on Ubuntu
24.04). Doctor includes these fresh observations in the `embedded_python`
details of its `hopper-demo-runtime` check, alongside the private-display
diagnostic. Failed inspections remain unknown rather than proving a library
absent. Run `rea setup --yes --install-hopper` to repair a supported install.
This prerequisite check does not launch the bridge or validate a custom Python
interpreter configured inside Hopper; that interpreter needs its own matching
shared runtime. Custom installation prefixes or shared-library ABIs require
manual dependency repair.
When the package-manager step fails, setup reports the failing command and its
captured output, so a package conflict is distinguishable from an authorization
failure. On CachyOS, an unversioned compatibility package such as
@@ -963,6 +998,24 @@ can time out earlier even when Ghidra would complete within its startup deadline
See [Ghidra first-query deadlines and recovery](mcp-contracts.md#ghidra-first-query-deadlines-and-recovery)
for client options and the close/reopen recovery flow.
The 330-second default is configurable. Configuration is read when REA starts:
changing an environment variable in another shell, or closing and reopening a
binary in the same MCP server, does not change that server's startup allowance.
For a CLI retry with an example 30-minute allowance:
```sh
REA_GHIDRA_STARTUP_TIMEOUT_MS=1800000 rea analyze /absolute/path/to/app.exe --provider ghidra --json
```
For MCP, export useful Evidence before restarting, close the binary and resolve
any cleanup failure, update the environment in the client's REA server launch
configuration, then restart REA and reconnect before reopening the target. Allow
startup plus the query in the client's own tool-call deadline. Every retry uses
a fresh ephemeral import; smaller result requests do not reduce the prerequisite
auto-analysis. A larger time allowance does not raise the JVM heap limit or
guarantee completion. Keep [heap and host CPU controls](#ghidra-heap-and-cpu-controls)
appropriate for the machine.
One session contains exactly one imported Program; use `provider_id: "ghidra"`, `--provider ghidra`, or
`REA_ANALYSIS_PROVIDER=ghidra` when both Hopper and Ghidra support the target.
One persistent decompiler is owned by the Program, and a serial queue keeps
@@ -1065,9 +1118,14 @@ and hyphens; at most 32 names are admitted, each at most 120 characters.
Names must identify analyzers registered for the selected program. Unknown names
or options that remain enabled abort the headless import before auto-analysis
and the bridge, so an unsuccessful override cannot produce a session claiming
that the analyzer was disabled. For Windows PE resource analysis, the exact name
is `WindowsResourceReference`. Disabling an analyzer skips the facts it would
have produced.
that the analyzer was disabled. The setting applies to every import in the REA
server. A format-specific analyzer may not be registered for another target, so
the same override can prevent that target from opening. For mixed-target work,
omit the override or use a separate REA server configured for the affected
format. Changing the environment requires restarting the server; reopening a
target alone keeps the current setting. For Windows PE resource analysis, the
exact name is `WindowsResourceReference`. Disabling an analyzer skips the facts
it would have produced.
### Ghidra heap and CPU controls
@@ -1135,8 +1193,10 @@ truncation markers. Darwin ownership-helper compilation failures also retain
the compiler outcome, exit code or signal, and bounded stderr; a timed-out
compiler remains distinguishable from a compiler that exited with an error.
The helper compile deadline defaults to 120,000 ms; set
`REA_SWIFTC_COMPILE_TIMEOUT_MS` to an integer between 1 and 2,147,483,647 when
a busy host needs longer.
`REA_SWIFTC_COMPILE_TIMEOUT_MS` to an integer between 1 and 2,147,483,647 in
the environment that starts REA when a busy host needs longer. Restart REA to
apply a change; the next ownership-helper compile uses the new value. A
timeout names that effective deadline.
On macOS, the Java prerequisite probe waits for this independently bounded
preparation before starting its five-second command deadline. Caller cancellation
still interrupts preparation, and failed helper cleanup remains owned for retry.
+11
View File
@@ -195,6 +195,17 @@ earlier read or captured alias. Unproved ordering across branches or function
activations remains conservative. Returned-reference effects use the same
read-position facts as call resolution.
Returned-reference effects share one property-projection state per source read.
When several paths reach that read, differing keys at the same depth become
wildcards; differing depths become an unknown-depth selection. This retains a
conservative superset of the represented local targets rather than enumerating
every alias history or dropping paths at a query cap. It can add possible effects,
including for finite projection cycles. Static limitations disclose this loss of
precision; semantic graphs retain `dynamic-property` unknowns at the affected
callee coordinates, and captured web bundles identify the affected script keys.
These candidates do not prove runtime calls or mutations. Existing source-worker
and result-admission limits still apply.
Mutation tracking covers explicit member assignments, updates, deletion, and
loop assignment targets, including the supported local aliases and shared
nested references. Calls conservatively invalidate exposed mutable references;
+58 -8
View File
@@ -50,6 +50,12 @@ The equivalent MCP input is:
`input_path` must be absolute. `format` accepts `auto`, `asar`, or `directory`.
`integrity_policy` accepts `fail` or `record-and-continue`; both CLI routes and
the MCP tool default to `fail`.
Evidence parameters retain the caller-selected `input_path`, including a
symlink alias. Both CLI routes anchor relative inputs to their working
directory without resolving symlinks. The subject and normalized result use
the resolved path for artifact identity; the selected path remains a separate
request fact. Older Evidence can omit this parameter; retained records are
validated without resolving their paths against the live filesystem.
The result retains the canonical local path, root artifact digest, artifact
manifest and graph commitments, JavaScript Application Graph, static
Electron summary, reconstruction statistics, and explicit limitations. It does
@@ -100,6 +106,15 @@ only reduces delivery; source selection reduces text acquisition and analysis.
Explicit native provider or snapshot routing rejects `--source-path` rather
than ignoring it.
ASAR header/index admission is a fixed 16 MiB / 16777216 bytes for this
release. There is no runtime override. The archive index is read before any
member can be selected, so `source_paths`, `--source-path`, `detail:
"summary"`, `max_heap_mb`, and available host memory do not bypass or raise
it. When the header exceeds that allowance, the failure names this budget.
Analyze an extracted application directory, which does not admit an ASAR
header, or supply an archive whose header fits. Repeating the unchanged
request fails the same way.
## Read the analysis
`analyze_javascript_application` returns the complete analysis Evidence by
@@ -166,7 +181,8 @@ for the tool-result contract.
Use MCP `detail: "summary"` for a large application, then read selected views of
the retained analysis. Summary changes delivery only. To reduce source parsing,
select exact [source paths](#select-sources-before-analysis).
select exact [source paths](#select-sources-before-analysis). Source selection
does not bypass ASAR header/index admission.
If a complete response exceeds the transport budget, use its retained Evidence
ID for a summary, module page, or item, or export the bundle. See
@@ -365,7 +381,15 @@ Recognized literal module-table bootstraps also support bounded lexical
substitution through module exports, import helper bodies, local wrapper calls,
returned closures, object spreads, and callback parameters. Recovered Electron
paths retain source ranges, module identities, literal channels and branch
conditions as static candidates. Unknown spreads, reassigned bindings, accessors,
conditions as static candidates. A channel the IPC call site itself
determines, such as a local constant, resolves that call's observation rather
than adding a second one. A channel or registration handler supplied through
a wrapper argument is a candidate beside the call's own unresolved
observation, because callers outside the traced paths may pass other values.
A wrapper call that is both its own entry and reached through another entry
is recorded once when both paths find the same facts; calls that supply
different handlers or channels stay distinct.
Unknown spreads, reassigned bindings, accessors,
dynamic channels and unsupported syntax do not become exact implementations.
This pass neither executes the bundle nor proves that runtime guards pass.
An ambiguous or unresolved handler retains its channel registration but does
@@ -583,8 +607,9 @@ The default semantic capacities are 100000 nodes across the application and
`--max-semantic-nodes-per-file`), each from 1 to 1000000. The per-file offer is
also bounded by the remaining application capacity. Raising these controls does
not bypass worker heap, execution deadline or parent result admission. Truncated
coverage reports both effective node ceilings; omitted relationships remain
unknown.
coverage lists both effective ceilings, `max_semantic_nodes` and
`max_semantic_nodes_per_file`. The limitation names only the ceiling that
stopped retention. Omitted relationships remain unknown.
Unknown records have independent defaults of 100000 across the application and
20000 per source. Select `max_semantic_unknowns` and
@@ -592,8 +617,10 @@ Unknown records have independent defaults of 100000 across the application and
`--max-semantic-unknowns-per-file`), each from 1 to 1000000. The parent offers the
remaining capacity to the worker, and rejects excess records before adoption.
Unknown admission happens before canonical identity and provenance construction.
When capacity is exhausted, coverage is partial and truncated and names both
effective unknown ceilings. `coverage.omitted_unknown_occurrences` counts examined
When capacity is exhausted, coverage is partial and truncated. Coverage lists
both effective unknown ceilings, `max_semantic_unknowns` and
`max_semantic_unknowns_per_file`. The limitation names only the ceiling that
stopped retention. `coverage.omitted_unknown_occurrences` counts examined
emission occurrences by family and reason, including repeated emissions. It does
not claim distinct discarded identities or count frontiers in unexamined source.
Omitted unknown provenance and IDs are not retained. Existing source, node,
@@ -606,12 +633,35 @@ checkpoint at its 8 MiB bound with the same 6x retention expansion used at
admission. Earlier checkpoints are already charged to retained bytes; the
remaining inventory does not multiply the reserve. Streamed file transfers keep the default 512 MiB
allowance, and can grow with the parent's offered retention budget (8x byte
expansion), up to 2 GiB. Individual records remain bounded to 8 MiB. The parent
expansion), up to 2 GiB. Individual records remain bounded to 8 MiB. The 8 MiB
record ceiling and the 2 GiB file maximum have no runtime override, and raising
`max_heap_mb` does not raise them. The effective file ceiling follows the
parent's offered result budget. On Node, a larger CLI/MCP process heap
(`NODE_OPTIONS`, for example `--max-old-space-size=<MiB>`, after restarting that
process) can raise it up to 2 GiB. Selecting fewer `source_paths` can also
raise that effective allowance, because the reserve for remaining sources and
earlier retained results reduce the offered budget. Neither change raises the
record ceiling or the 2 GiB maximum. The parent
still independently checks actual bytes, record overhead, digests and source
identities before adopting results.
A source that exhausts the analyzer heap does not terminate the CLI/MCP
process. Completed static facts are retained, other files can still be analyzed,
process. On Node, the failure names `max_heap_mb` (CLI `--max-heap-mb`), the
effective mebibytes, the inclusive range 128 to 16384, and the 1024 MiB
default. A changed value applies on the next analysis, which starts a new
worker. It does not change a worker that is already running and does not
require restarting the REA server. On Bun, the same heap-exhaustion diagnostic
is not attributed to that V8 old-space limit, because Bun ignores the flag.
Raising `max_heap_mb` does not raise the parent result budget,
the transfer record ceiling, the 2 GiB transfer file maximum, the CLI/MCP
process heap, or fixed parser limits. The parent result budget follows that
process heap. On Node, set `NODE_OPTIONS` (for example `--max-old-space-size=<MiB>`)
in the environment that starts the CLI or MCP server, then restart that
process, to raise the parent heap and the result budget. A completed static
checkpoint that does not fit the parent's remaining heap names that parent
process heap. Increasing `max_heap_mb` does not raise it. On Node, the same
`NODE_OPTIONS` restart can raise the parent heap and admit the checkpoint.
Completed static facts are retained, other files can still be analyzed,
and unexamined semantic relationships remain explicit unknowns. The parent
also checks transfer expansion and accumulated results against its remaining
heap before accepting semantic facts. A resource-limited result has partial
+9 -4
View File
@@ -129,10 +129,15 @@ equivalence remain unknown. No network fetching occurs.
## Resource policy and verification
Each operation uses one worker, a 1 GiB address-space ceiling and a 120-second
deadline; it accepts up to 64 MiB of total input across all selected files and
128 MiB/10000 entries of staged
output, with 8 MiB per diagnostic/report stream. Exceeding a limit is an explicit
Each operation uses one worker, a 1 GiB address-space ceiling and a 120000 ms
deadline. That deadline has no runtime override: raising `analysis_timeout_ms`
or `max_heap_mb` does not raise it. An unchanged retry may hit the deadline
again. The operation accepts up to 64 MiB of total
input across all selected files and 128 MiB/10000 entries of staged output,
with 8 MiB per diagnostic/report stream. A `provenance.json` over that report
allowance names the fixed limit: this release has no runtime override, and
raising `max_heap_mb` or `analysis_timeout_ms` does not raise it. Malformed
reports stay distinct from that size refusal. Exceeding a limit is an explicit
failure with rollback. Selected inputs beyond the total input allowance return a
non-retryable `resource_constraint` with `resource: "file-size"` and
`reported_limits.maximum_input_bytes`/`remaining_input_bytes`; input that is not
+9
View File
@@ -152,6 +152,15 @@ and uncollected scripts, but scripts collected before attachment may be
missing. Absence from the observation window never proves that a script or
behavior does not occur.
Cancellation stops new target-file authorization after the current filesystem
operation settles. Cancellation diagnostics retain the examined target prefix;
unexamined targets remain unknown. Observation cancellation keeps its original
reason and any completed Evidence. Finalization waits for REA's bounded socket
close (up to two seconds for graceful and forced confirmation). A failed close
retains its exact transport owner and blocks replacement connections until
cleanup succeeds; CLI finalization and MCP shutdown also retry retained cleanup.
Closing REA's connection does not stop the caller-owned runtime.
## Static correlation
Pass the resulting observation Evidence and an
+5 -1
View File
@@ -106,7 +106,11 @@ nodes. REA evaluates compatible static candidates conservatively:
that disagreement. If a mapped candidate's digest is unavailable and no
mapped content match is known, the comparison remains `unknown`.
6. Missing authorization mappings and incomplete or truncated input coverage
remain unknown or truncated rather than becoming absence claims.
remain unknown or truncated rather than becoming absence claims. A runtime
location with no automatic artifact-root or caller-declared mapping into
any layer, and no unique content match, is `unknown` with
`no-authorized-location-mapping`, with or without captured bytes. Only a
mapped location can be `unmatched` with `no-static-content-match`.
Every successful cross-layer `observed_as` edge has
`authority: cross-layer-reconciliation` and `state: inferred`. The underlying
+26 -14
View File
@@ -8,7 +8,16 @@ Start a JEB client that serves MCP and point REA at it:
- Default endpoint: `http://127.0.0.1:8425/mcp`. Override with `REA_JEB_MCP_URL` (absolute `http`/`https` URL with literal host `127.0.0.1` or `[::1]`; redirects, remote hosts, credentials, query strings, and fragments are rejected rather than silently dropped).
- In the JEB GUI client, start the MCP server from the _File_ menu (or via the VIBRE assistant).
- Headless, use JEB's documented programmatic route (`JebMcpServerInstance` from the JEB API) with the JEB client on your classpath; JEB 5.48's `-c` headless mode does not accept `--mcp` directly.
- Headless, the official Linux CE build `5.48.0.202610071539` supports `-c --mcp`. From the JEB installation directory, select JDK 21 or newer through `JAVA_HOME`, choose your target and bind explicitly to loopback:
```sh
"$JAVA_HOME/bin/java" -jar bin/app/jeb.jar -c --mcp --interface=127.0.0.1 \
--port=8425 --infile=/absolute/path/to/target
```
Complete the vendor's first-use EULA and license-key activation when prompted. The Linux audit used an isolated installation, a 1536 MiB Java heap and one active processor inside a separately bounded process family; JVM heap limits alone do not bound the whole family.
- JEB's documented programmatic route (`JebMcpServerInstance` from the JEB API) remains an alternative. The earlier licensed 5.48 headless verification used that route because its CLI did not accept `--mcp`. Check your installed build's `-c --help` and live tool catalog; the version number alone does not establish the launcher options or supported operations.
For setup registration, set `REA_JEB_MCP_URL` in the REA process environment
before running `rea setup`. The approved setup plan preserves the exact selected
@@ -19,19 +28,21 @@ JEB service is reachable or that a project is open; use the existing
MCP `binary_session` probes the live JEB service and its advertised tool catalog.
Availability is reported per operation: a reachable headless client can support
inspection and decompilation while refusing `open_jeb_project`. Catalog discovery
uses one 60-second deadline across connection and pagination; a responsive server
cannot keep discovery running indefinitely by returning more pages.
is one deadline across connection and pagination; a responsive server cannot keep
discovery running indefinitely by returning more pages.
Each upstream tool call has an absolute 60-second request deadline by default.
Set `REA_JEB_MCP_TIMEOUT_MS` to a positive decimal number of milliseconds to
select a different per-request budget, for example `REA_JEB_MCP_TIMEOUT_MS=300000`
for a five-minute decompilation. This budget starts after discovery and applies
to each individual `tools/call`; it does not extend the separate catalog deadline
or establish one end-to-end deadline across a whole CLI or MCP operation. A
request that reaches its budget returns a typed timeout, while caller
cancellation remains a cancellation.
Catalog discovery and each `tools/call` share `REA_JEB_MCP_TIMEOUT_MS`. Set it
in REA's launch environment to an integer from 1 to 2147483647 milliseconds,
for example `REA_JEB_MCP_TIMEOUT_MS=300000` for a five-minute budget. Omitted
means the pinned MCP client SDK default of 60000 ms (`@modelcontextprotocol/client`
2.3.1). Restart REA and reconnect to apply a change. Raising the setting raises
both phases. It does not make one end-to-end deadline across a whole CLI or MCP
operation: discovery and each `tools/call` each get that budget. A request that
reaches its budget returns a typed timeout naming the phase and the effective
milliseconds, while caller cancellation remains a cancellation. Allow execution,
cleanup, and delivery headroom in the outer MCP client deadline.
Verified against JEB 5.48.0 (Linux x64, licensed build) serving `jeb-mcp-server` 1.3.0 over streamable HTTP.
Earlier verification used JEB 5.48.0 (Linux x64, licensed build) serving `jeb-mcp-server` 1.3.0 over streamable HTTP. The official Linux x64 CE build `5.48.0.202610071539` was also verified through real CLI and production stdio MCP native-code workflows; see the [Linux CE audit](../experiments/analysis-efficiency/jeb-linux-native.md) for measurements and limits. CE verification does not establish licensed/Demo Android decompilation or GUI behavior.
## Operations
@@ -42,15 +53,16 @@ Verified against JEB 5.48.0 (Linux x64, licensed build) serving `jeb-mcp-server`
| `list_jeb_units` / `list-jeb-units` | Page units by stable path and type (`filter`, `parent-unit-path`, `index`, `count`) |
| `decompile_jeb_item` / `decompile-jeb-item` | Decompile one type or method to engine pseudo-code |
All four are read-only with respect to the target file; only `open_jeb_project` changes engine-side project state, and Evidence records the endpoint, the caller-selected parameters, and the engine-reported digests. Mutation workflows the engine also offers (renames, comments, `save_project`, `close_project`) are intentionally not exposed yet.
All four preserve target-file bytes. `open_jeb_project` selects or creates an engine-side project; analysis queries can populate computed analysis within it. Evidence records the endpoint, caller-selected parameters, and available engine-reported digests. Mutation workflows the engine also offers (renames, comments, `save_project`, `close_project`) are intentionally not exposed yet.
**Engine coverage note (verified):** JEB 5.48.0 headless MCP instances do not advertise `open_project` — the target must be selected when the engine client starts (`--infile` on the programmatic launcher, or the GUI's file opening). REA preserves that refusal with the engine's reason instead of failing silently; `open_jeb_project` completes only against engine builds that advertise the tool, such as GUI clients.
**Engine coverage note:** The earlier licensed 5.48.0 headless verification did not advertise `open_project`; it selected the target when the engine client started. For that build, use `--infile` on the programmatic launcher or open the file in the GUI. The audited CE headless catalog also omitted `open_project`; the verified CLI route above selects its input at startup. Use `binary_session` to inspect the current engine's advertised operations. REA preserves an unavailable tool's refusal; `open_jeb_project` requires an engine that advertises `open_project`. The CE audit does not establish GUI project-opening support.
## Semantics
- Paths in `open_jeb_project` are resolved by the JEB process, not by REA; REA does not require the artifact to exist locally.
- The engine caps `list_units` pages at 100; a full page is reported as `coverage: "partial"` because more units may exist. An empty remainder is `complete` only when fewer units than requested were returned.
- When `decompile_jeb_item` omits `unit_path`, the engine implicitly selects the project's first code unit; REA reports `unit_path: null` and a limitation instead of guessing the effective unit.
- `item_address` is a JEB code-item reference, such as a value returned by the engine's `list_code_items`. Preserve that representation and select its code unit explicitly. For the audited CE SQLite unit, the exported method reference was `sqlite3_libversion_number`; using its raw ELF symbol address did not produce a successful decompilation. File offsets, ELF virtual addresses and engine item references have different semantics. REA currently exposes unit listing, while code-item discovery remains an upstream JEB operation.
- Engine refusals (`success: false` envelopes) are preserved as unsupported-target errors carrying the engine's own message, for example a nonexistent item address.
- Successfully parsed client information is reused for the lifetime of the MCP connection, including when the engine omits its version. Explicit client inspection and availability probes refresh it.
- An unreachable endpoint is a provider-availability failure with recovery guidance; REA does not retry or spawn the engine.
+9 -1
View File
@@ -13,6 +13,14 @@ rea doctor --provider kuna
Select it explicitly with `--provider kuna`, MCP's `open_binary.provider_id: "kuna"`, or `REA_ANALYSIS_PROVIDER=kuna`. With Kuna and another provider configured for the same target, `auto` reports `ambiguous` instead of choosing one.
Ordinary readiness cancellation returns `cancelled` (CLI SIGINT/SIGTERM exits
130/143); an earlier recorded timeout or physical failure keeps its diagnostic.
Completed version, hash and script observations remain in `kuna_installation`
with `status: "partial"` and `completed_hash` when available. Typed errors carry
this in `details.diagnostics`; doctor cleanup checks carry it in their `details`.
Omitted fields remain unobserved; availability remains unknown until readiness
completes. Cleanup retries keep both the observations and the exact file owner.
| Setting | Default | Meaning |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REA_KUNA_COMMAND` | none (required) | Absolute path of the `kuna` executable. |
@@ -60,7 +68,7 @@ The background export belongs to the session. `close_binary`, or the end of a CL
The assembly label index is scanned once per export reader. Cancelling a request stops its wait without interrupting other readers; closing the session aborts and drains the shared scan before releasing its files.
Regex procedure and string search uses ECMAScript Unicode matching in a cancellable worker with a five-second matching deadline. Literal matching remains the default. Cancellation or a matching deadline leaves the session available.
Regex procedure and string search uses ECMAScript Unicode matching in a cancellable worker with a five-second matching deadline and a worker old-generation heap. Literal matching remains the default. Cancellation or a matching deadline leaves the session available. This release has no runtime override for that deadline. The worker requests 128 MiB. A positive Node.js `--max-old-space-size` on the process that starts REA, including `NODE_OPTIONS`, overrides that request and sets the effective heap. `--max-old-space-size-percentage` takes precedence over that flag in either order. REA does not turn the percentage into a MiB, so the effective heap stays unestablished instead of the 128 MiB request or the absolute flag. The reported `NODE_OPTIONS` value is the process initial environment when that block can be read. A later edit to the environment is not the value Node applied, and an unreadable initial value leaves the effective heap unestablished. The launch Node options are the initial command line on Linux when that buffer still has a program entry, not a later edit to `process.execArgv`. A preload can clear that array after V8 has applied the flags. Setting `process.title` or `--title` overwrites the command line, so a buffer without a program entry leaves the effective heap unestablished. `--env-file` or `--env-file-if-exists` can supply `NODE_OPTIONS` when the initial environment has none. That file is not part of the initial environment block, so the effective heap stays unestablished instead of the 128 MiB request. An initial `NODE_OPTIONS` is still used, because Node does not let the file replace it. A positive `--max-heap-size`, including the underscore form and launch `NODE_OPTIONS` on Node versions that allow it, sets the total heap rather than the old generation and can be lower than the 128 MiB request. The effective old generation stays unestablished while that value is in effect. A zero or empty value clears it. `--experimental-config-file` or `--experimental-default-config-file` can set `nodeOptions`, including a heap percentage, from a file that is not read back. The effective heap stays unestablished when either flag is present, including when an absolute `--max-old-space-size` is also on the command line or in the recovered `NODE_OPTIONS`. Node accepts the config path as `=` or the next argument.
Single-function subprocess output and each cached source facet share a 16 MiB buffered-text capacity. Cached spans are checked before allocation; larger text remains in the local export and the error identifies the file and range. `analyze_function` initially returns the complete dossier, which can still be large; later retained views do not remove that first transfer. Prefer the individual text tools for a focused question.
+55 -7
View File
@@ -85,7 +85,7 @@ rejects selected summary before analysis; complete delivery remains available.
Complete `inspect_managed_members` delivery always includes the assembly-wide
`member_refs` and `exported_types`, which `type_names` does not narrow, so even
one selected or unmatched type can return megabytes. Select
one selected or unmatched type can return megabytes. In MCP, select
`{"path":"/absolute/path/Assembly.dll","type_names":["Namespace.Type"],"detail":"summary"}`
to keep the complete source in the session and receive identity, metadata
status, the selection with its unmatched names, coverage/issues, the separate
@@ -115,13 +115,58 @@ literal pool's own coverage. Older Evidence that never examined exported types
or user strings reports a null count and refuses those pages rather than
returning an empty one.
#### CLI summary and saved member rows
The CLI accepts the same `complete` and `summary` detail choices. Omitted or
`--detail complete` returns complete Evidence. To receive a summary, choose a
new Evidence bundle destination so its original complete parent remains
available after the command exits:
```bash
rea inspect-managed-members /absolute/path/Assembly.dll --type Namespace.Type \
--detail summary --evidence-bundle /absolute/path/evidence/members.json --json
```
`--evidence-bundle` writes the complete original Evidence in REA's canonical
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`.
Copy `normalized_result.parent_evidence_id` from the summary into the
`source.evidence_id` field of the `managed-members` request above, then save that
small request as `members-page.json` and run:
```bash
rea inspect-analysis-view /absolute/path/evidence/members-page.json \
--evidence-bundle /absolute/path/evidence/members.json --json
```
The view command authenticates the selected bundle and resolves that exact
parent ID. It does not reopen the assembly, so the original target may have
been moved or removed. Subsequent calls can select another collection or use
the returned `coverage.next_offset` to continue the same collection. An inline
source already includes its parent and cannot also select `--evidence-bundle`.
Summary changes delivery, while type selection still controls decoding and the
same inspection resource limits apply. Each separate CLI page reads and
authenticates the saved bundle; the full source is retained on disk.
## Shipped scope
The canonical parser admits PE/CLI bytes and their metadata/CIL without loading
an assembly. It reports observed implementation markers and unavailable facts;
it does not unpack .NET single-file hosts, decode IL2CPP metadata, or infer a
NativeAOT identity from an ordinary native PE. Inputs without admitted CLI
metadata do not become managed assemblies through naming or routing guesses.
it does not unpack .NET single-file hosts or infer a NativeAOT identity from an
ordinary native PE. It does not decode IL2CPP; use
[IL2CPP metadata](il2cpp-metadata.md) for the image, type and method names in a
Unity `global-metadata.dat`. Inputs without admitted CLI metadata do not
become managed assemblies through naming or routing guesses.
Inspect separately obtained components explicitly and preserve their identities.
A valid implementation marker establishes a candidate native boundary, not
@@ -620,6 +665,9 @@ which managed methods executed or how the CLR resolved them.
Managed member comparisons report a `metadata` dimension when an observed
MethodDef flags or implementation flags value differs, including accessibility
or synchronization changes. This is separate from the CIL/signature matching
tiers: identical instructions do not establish unchanged method metadata. The
reported difference is static metadata evidence, not proof of runtime behavior.
or synchronization changes. Observed method-body `init_locals` and `max_stack`
differences also contribute to `metadata`, even when CIL decoding is incomplete.
An unavailable header value keeps body coverage unknown rather than establishing
equality or a difference. These comparisons are separate from the CIL/signature
matching tiers: identical instructions do not establish unchanged method metadata.
The reported difference is static metadata evidence, not proof of runtime behavior.
+324 -24
View File
@@ -1,8 +1,13 @@
# MCP runtime contracts
For pairing native functions before comparing selected dossiers, see
[native function matching](native-function-matching.md). It operates on retained
inventories, preserves aliases/unknowns and exposes selected fact pages.
Use this reference to call REA tools and interpret their replies on one MCP
connection. Start with [tool results](#tool-results), [retained Evidence](#retained-application-evidence-inputs),
and [session discovery](#identity-and-discovery). See [cancellation](#progress-and-cancellation)
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.
@@ -21,6 +26,14 @@ directly to `compare_functions`, and `inspect_artifact` Evidence to
`compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
retained session history or an explicit bundle for transfer.
Ghidra inventories and function replies use `raw_result: null` when their facts
are already preserved in `normalized_result`, limitations, locations and
relationship coverage. Distinct overview details, measured load-image
observations, file-offset selection roles and database types supplemented with
derived metadata keep their upstream representation. Read function results from
`normalized_result`; older retained Evidence keeps its original representation
and identity.
Artifact inventories declare `coverage.scope` (`root` or `container-entries`)
and `coverage.status` (`complete` or `unknown`) independently of diagnostic
wording. Comparison requires matching scopes, complete graph members and complete
@@ -58,7 +71,13 @@ Call comparison additionally retains the Evidence relationship coverage
checks. Ghidra and Hopper declare their observed dossier facets and complete
provider-observed caller/callee sets, including empty sets. Missing decompiler
output remains unavailable; complete call coverage does not claim every runtime
target. Hopper's unavailable reference-kind metadata and reported unresolved
target. When Ghidra's decompiler fails on one function, its dossier is still
returned: `pseudocode`, `native_api` and `native_value_flow` are unavailable
with the decompiler's failure as the reason, while the listing-backed facets
are collected as usual. These failed decompiler observations and workflows
derived from them retain Evidence but skip snapshot reuse, so a later request
can observe backend recovery; healthy dossiers keep their existing cache policy.
`procedure_pseudo_code` still fails for that function. Hopper's unavailable reference-kind metadata and reported unresolved
calls still prevent equality conclusions for those dimensions. Analysis profiles
version these declarations so older snapshots are not reused as current results.
IDA declares the facets its selected adapter cannot provide; an empty
@@ -71,13 +90,31 @@ metadata in the supported JSON payloads (`parameters`, `raw_result`,
Tool execution failures return `isError: true` and the complete canonical
`{ "error": ... }` diagnostic as JSON in text `content`. Read that diagnostic
for the error code, target details, partial observations, and remediation.
for the error code, target details, partial observations, remediation, and the
optional bounded `recovery` next step. `recovery.kind=inspect_input_contract`
names the rejected operation: re-read that operation's advertised input schema
(call `tools/list` if the catalog may be stale), correct the listed fields, and
do not repeat the unchanged call. `recovery.kind=inspect_timeout_state` names
the operation and the REA server/provider deadline; inspect partial Evidence
and reported cleanup state, then follow producer-specific remediation or reduce
supported work. Generic errors do not assume adjustable timeout controls. Raising
only the MCP client's deadline cannot extend this budget. These hints never
include the complete catalog or caller arguments.
Failures omit `structuredContent`, since each advertised `outputSchema`
describes successful results. Successful replies retain their schema-validated
structured data and matching text projection. Oversized errors are retained
as Evidence before delivery of a bounded diagnostic with an export reference;
if retention is unavailable or fails, the diagnostic reports that reason.
SDK-generated input validation failures are normalized into the same canonical
`invalid_request` text when the bounded diagnostic fits the response budget.
The complete field/type diagnostic is preserved when normalization fits the
response budget, including request-specific rejected fields and reasons. Oversized
SDK diagnostics keep the existing retained-Evidence recovery path. An unknown
tool remains an MCP JSON-RPC `-32602` error, but its message directs the caller
to `tools/list` and an advertised operation instead of repeating the unknown
name.
`get_call_graph` returns a `graph` keyed by traversal depth and a top-level
`limitations` array with deduplicated execution caveats. Each node keeps its
relationship coverage and read-specific `limitations`, alongside observed
@@ -92,8 +129,9 @@ unresolved relationship reads. Cancellation remains a tool error.
REA prepares complete MCP results within the pinned stdio client's 10 MiB
receive-buffer budget, including both text and structured representations and
room for the JSON-RPC envelope. Tool errors carry only their text
representation and `isError` flag, so only those count against the budget. Response budget settings are captured at startup;
room for the JSON-RPC envelope. Tool errors omit `structuredContent` from the
wire; their text, `isError`, provenance marker and negotiated protocol framing
count toward the wire budget. Response budget settings are captured at startup;
restart or recreate the server to apply changes. If a result cannot fit, REA returns
`resource_constraint` with `details.resource: "transport"` before constructing
a document-sized string. Analysis Evidence remains complete in the current
@@ -103,6 +141,52 @@ that reference for a summary, one section/module, or a stable page, or call
`export_evidence_bundle` with a destination path. Complete
bundle exports stream canonical JSON into an atomically published file.
On protocol revision `2026-07-28`, completed replies retain the SDK's
`resultType: "complete"`, including the replacement for an oversized error.
This marks completion of the MCP exchange; Evidence coverage, partial facts
and unknowns retain their separate meaning. Legacy replies keep their existing
framing.
`list_procedures`, `search_procedures`, `list_strings`, `search_strings` and
`list_names` accept `detail: "summary"`. Complete inline delivery remains the
default. Summary retains the original complete Evidence and returns its row
count, provider identity, analysis-profile digest, original query, parent Evidence
ID, limitations and explicit unknown discovery coverage. Delivery detail is excluded from provider arguments
and original Evidence identity.
Read selected rows with `inspect_analysis_view`:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "ev_<source digest>"
},
"view": {
"kind": "native-inventory",
"offset": 0,
"limit": 32,
"fields": ["value"]
}
}
```
Each row has `source_index` and `record`; parent Evidence ID plus source index
identifies same-address alternatives. Order is the original retained order.
Omit `fields` for complete records; a selected field list always retains
`record.address`. Selecting `value` also retains available `string` and
`decoding` qualifications, so native display text and unterminated fragments
remain distinguishable. Search tools apply their existing filters before retention.
Follow `coverage.next_offset`; exhaustion describes the retained list, not
complete discovery of all code or strings. An unbound source keeps
`artifact: null` and the derived Evidence keeps `subject: null`.
The CLI uses the same projector. For an original complete Evidence JSON file,
write `{"source":{"kind":"evidence-file","path":"/absolute/source.json"},"view":{"kind":"native-inventory","limit":32}}`
to `/absolute/view-request.json`, then run
`rea inspect-analysis-view /absolute/view-request.json --json`. This also reads
pre-summary source records without changing their identity; no live provider is started.
For oversized native function Evidence, `details.reported_limits.continuation`
contains a ready-to-call `inspect_analysis_view` request for the retained
pseudocode's first page. Use its `name` and `arguments` directly, then follow
@@ -111,6 +195,8 @@ limit is the view contract's default, not a guarantee that arbitrary source or
metadata fits; reduce the limit or export when needed. Continuations are
offered for completed `analyze_function` results only after session recording is
acknowledged; the complete result and its retention reference remain intact.
Oversized native inventories likewise include a ready-to-call first
`native-inventory` page. Reduce its limit or select fields when a row is large.
A broad follow-up or `get_evidence_bundle` can also exceed the response budget; exporting
preserves the complete session without sending it through a single MCP frame.
@@ -132,6 +218,12 @@ is null. `total` counts all matching heads; each page preserves complete records
in stable unknown ID order. Filters apply before paging. Pages reflect current
session state, so keep the unknown ledger unchanged while traversing it.
Automatically retained workflow questions include their immutable result
Evidence ID. Distinct results retain independent questions and source links;
repeating the same result does not create another unknown. Workflow Evidence
keeps the original residual question text. Explicit `record_unknown` requests
keep caller-selected identity and reject duplicate creation.
For a portable exported bundle, the CLI shares this projection:
`rea inspect-evidence-bundle '{"path":"/tmp/evidence.json","detail":"summary","filters":{"operation":"analyze_function"}}' --format json`.
The CLI validates and materializes that local bundle under its existing memory
@@ -142,11 +234,31 @@ The destination changes only when a complete export is atomically published.
Clients that explicitly configure a larger receive buffer can set the REA
server's `REA_MCP_MAX_RESPONSE_BYTES` environment variable to the same byte
count. This setting must be a safe decimal integer at least 10485760; REA
reserves 1024 bytes for the envelope. Raising it restores complete inline
delivery for responses that fit that buffer and Node's single-string limit.
It does not change the client's buffer, analysis coverage, or retained content.
Ordinary responses keep their existing complete result contract.
count. This setting must be a safe decimal integer at least 10485760 (10 MiB);
REA reserves 1024 bytes for the envelope. The value is read when the REA
process starts, so a change requires a restart and a matching client receive
buffer. Raising it restores complete inline delivery for responses that fit
that buffer. It does not raise REA's reserved single-string limit, which is
1024 UTF-16 code units below Node's single-string ceiling, and it does not
raise that Node ceiling. It does not change analysis coverage or retained
content. Ordinary responses keep their existing complete result contract.
### Error recovery and deadline ownership
Initialization instructions and the static JavaScript tool description teach
recovery before a host can discard a tool response. Invalid input calls should be corrected from the connected schema
(refresh `tools/list` only if stale), not retried unchanged. REA's returned
`provider_timeout` describes its server/provider deadline; provider-authored
remediation names the applicable controls and preserves partial Evidence and
cleanup uncertainty.
A host timeout without a REA result is different: execution and cleanup remain
unknown. Increasing an advertised `analysis_timeout_ms` cannot fix a shorter
client deadline. Configure the client's tool timeout with execution, cleanup
and delivery headroom, or report that change is needed when not authorized.
Session status does not establish that all target-free work stopped. Detailed
host settings and bounded retry guidance live in the shipped skill's
[recovery reference](https://github.com/morluto/rea/blob/main/.agents/skills/reverse-engineer-anything/references/connection-and-recovery.md#distinguish-client-and-server-deadlines).
### Untrusted target content
@@ -210,6 +322,21 @@ inferred Evidence whenever any group is templated, and derived Evidence only whe
no group was templated.
See [derived API surfaces](web-network-captures.md#derived-api-surface).
`inspect_analysis_view` also accepts `environment-manifest` for retained HAR capture
Evidence and `capture_browser_scenario` Evidence, projecting the primary origin's request lines into named tools with path
templates, parameters, observed query names, value-free body shapes and record
pointers, plus excluded groups and three fixed unknowns. Templates, parameters and
names are inferences; the Evidence is inferred whenever any tool or excluded group
is templated, and derived otherwise.
See [environment manifests](web-network-captures.md#environment-manifest).
`inspect_analysis_view` also accepts `environment-state` for the same parents,
extracting the initial state the recorded reads observed: entity types with an
identity field, entities, documents for non-entity reads, and a render
plan per read tool that reproduces its recordings from the state or names why it
cannot. Types and identity are inferences, so the Evidence is always inferred.
See [environment state](web-network-captures.md#environment-state).
`inspect_analysis_view` projects a caller-selected view of already completed
`inspect_binary_layout`, `analyze_javascript_application`, or `analyze_function`
Evidence. Native views select procedure, pseudocode, assembly, basic blocks,
@@ -228,10 +355,41 @@ application and semantic coverage. The result carries a digest of the selected
facts. Actual serialized size determines MCP transport admission: reduce the
page size or export retained Evidence if the view is too large.
`compare_source_to_bundle` accepts the committed historical graph inline or as
`reference: {"kind":"file","path":"/absolute/reference.json"}`. The shared
reader checks resource bounds and the graph's root commitment on every read. File-backed
comparison Evidence records `parameters.reference_source`: the exact
`requested_path` and the reader's absolute selected `path`, preserving POSIX
`..`/symlink semantics. Normalized comparison facts and mapping identities agree
with inline input; Evidence IDs distinguish caller-selected file origins.
Omitting `view` preserves the complete comparison. For a compact initial reply,
select `view: {"kind":"summary"}` or a `source-to-bundle` page; the session retains
the complete comparison before delivery. Later calls use `inspect_analysis_view`
with the returned `parent_evidence_id`.
A `source-to-bundle` view selects `collection: "mappings"` or `"candidates"` with
exact `source_paths`, `mapping_ids`, `statuses`, `fields`, `offset` and `limit`.
Omitted filters select all; empty arrays select none. The default mapping fields
include status, confidence, source digest/language and candidate/mapped counts.
Candidate defaults include kind, score and confidence; request `signals` for exact
supporting values. Mapping identity and `source_index` always remain; candidates
also retain `current_node_id`, `candidate_index` and whether they were actually
mapped. Indices refer to the complete comparison's item array and that item's
candidate array. All classifications are computed before selection. The original
`source_coverage` remains separate from page `coverage`; exhausting a page never
turns unknown correspondence into absence or proves behavioral equivalence.
The CLI accepts the same reference-file alternative (relative paths resolve from
the working directory). Save its complete `--json` Evidence, then use
`inspect-analysis-view` with an `evidence-file` source and the same view. Neither
adapter executes the target or repeats analysis for retained queries.
Completed `inspect_artifact` and atomic `inventory_artifact` Evidence also
support summary and inventory views. A summary reports the manifest's expected
counts separately from available record counts, observed entry kinds, inventory
Evidence IDs and inspection coverage. An inventory view selects `nodes`,
Evidence IDs, the inventory producer's traversal `source_coverage` and
inspection coverage. Inspection coverage is `partial` when that traversal
coverage is unknown. An inventory view selects `nodes`,
`occurrences`, `edges`, or `integrity_contradictions`, with `offset` and `limit`
defaulting to 0 and 64. For occurrences, optional `logical_paths` matches exact
recorded strings: omission selects all available records; `[]` selects none.
@@ -355,6 +513,17 @@ checking that a client received the full catalog. An operation absent from all
groups is missing from the complete inventory; it is not an implicit
unavailable entry.
`get_call_graph` and `trace_call_path` report `forward` and `backward` modes.
Each requires `procedure_address` plus `procedure_callees` or `procedure_callers`,
respectively. The tool is available when either traversal mode is supported;
`default_mode_available` describes the default forward direction. Read each mode's
missing operations and remediation before selecting a direction. These facts
describe traversal prerequisites, not relationship completeness or a guarantee
for every selector. A trace whose start and goal resolve to the same address can
finish without reading relationships, even when neither traversal mode is
available. Discovery does not block that direct invocation or replace its typed
partial/error outcomes.
The `effects` and `annotations` arrays list the true members of their fixed
vocabularies. A known member omitted from either array is false. This applies
only to these closed flag sets; it does not make an omitted tool, provider, mode,
@@ -393,6 +562,17 @@ concrete version, selection source, and complete analysis profile through
choices return typed selection details. A selected provider is never replaced
automatically after a runtime failure.
`open_bundle_resources` selects a separate read-only app resource session
without resolving `CFBundleExecutable`, including when it is absent or
unresolvable. `binary_session` reports `session_kind: "bundle_resources"` and the
caller and canonical resource-root paths; it does not report a binary target or
deep-provider binding. `inspect_plist`, `decode_interface_builder`,
`inspect_asset_catalog`, and `inspect_keyed_archive` retain resource-root
provenance and use a null Evidence subject when executable identity is unknown.
Binary-only operations and binary analysis snapshots do not apply in this
session. `open_binary` can switch back to executable analysis, and
`close_binary` retires either session kind.
Each provider client receives `binary_session.analysis_run.run_id` before any
provider startup, including clients whose startup fails. `process_lineage` is
`not_observed` until a dynamic provider starts, then becomes `snapshots` with
@@ -418,6 +598,96 @@ inspection fails or is cancelled before a provider client exists. If no client
remains, no provider run or health observation is available; follow the cleanup
error's reported resources.
## Transports
stdio is the default transport and the only one that client registrations,
`rea mcp doctor` and the MCP registry entry describe. `rea mcp --http [--host H]
[--port N]` is an opt-in alternative that serves the same catalog over the
streamable HTTP transport at `/mcp`; it replaces stdio for that process rather
than running beside it. Host and port come from the flags, then `MCP_HOST` and
`MCP_PORT`, then `127.0.0.1` and an ephemeral port. The bound URL is announced
as one JSON log line on stderr (`"msg":"MCP transport listening"` with `url`)
at every `REA_LOG_LEVEL`, because an ephemeral port is otherwise unreachable;
stdout stays unused.
This endpoint uses plain HTTP without TLS or client authentication. Use it only
within a trusted local or isolated environment; an explicit non-loopback bind
makes the same tools and active analysis state reachable at that address. It
does not provide separate users or independent target sessions. Standard client
registrations continue to use a dedicated stdio process.
The HTTP server is stateful and serves one client at a time on one server
instance. `initialize` returns an `Mcp-Session-Id`; `notifications/initialized`
is acknowledged with `202`; responses arrive as JSON or SSE frames; `DELETE
/mcp` with the session id ends the session with `200`. Ending a session is not
a server shutdown: the process keeps listening, the instance keeps its providers
and the shared active target, and the next client opens a fresh session against
them. A client ending or replacing a session cancels its running tool calls and
prompt completions, stops request-body reads and fences further message dispatch,
then waits up to ten seconds for request dispatch, handlers and cleanup to finish before reusing the
server. A timeout returns `503`; the old calls remain owned, and later requests
retry the drain rather than starting another session against those resources.
Requests that finish parsing or SDK dispatch after their session closed are
refused, and their response streams are cancelled. Tool callbacks whose
validation finishes after cancellation never start.
Body forwarding stops when SDK request processing ends, including early header
and size refusals, rather than remaining active until the session closes.
HTTP input/route dispatch is limited to eight concurrent requests by default,
shared by MCP and plain routes. Excess requests receive `503` with a closing
connection before their bodies are converted, read or cloned. An embedder can
select `maxConcurrentDispatches`; the SDK's per-body size limit still applies.
MCP responses with fully read or bodyless requests do not hold admission slots,
so an idle MCP SSE stream does not prevent later calls. Plain routes retain their
slots through response delivery and response-source cancellation cleanup. An
unread upload retains its slot until input finishes or either side closes,
even with a long response. Sequential keep-alive is supported; a peer pipelining
behind an unfinished response is disconnected before queued requests dispatch.
Concurrent MCP requests use separate connections.
This bounds concurrent input work, not total provider or process memory.
Provider-backed prompt completions use the same request owner and drain, so a
cancelled completion cannot keep using providers after handover or shutdown.
HTTP factories enable `RequestTrackingMcpServer` tracking so completion is tracked
even when cancellation suppresses the SDK's reply; stdio retains the SDK's
original callback behavior. Full server shutdown stops the listener and waits
for MCP work, plain-route handlers and response-source cancellation to settle
before running provider shutdown hooks or closing providers. Response producers
must finish provider work before closing their stream and expose asynchronous
disconnect cleanup through the stream's `cancel()` result. Cancellation does not
delay delivery of a HEAD reply; a caller retaining a sibling of a teed response
must consume or cancel that sibling before shutdown can finish. Failed response
cleanup remains owned, blocks further admission and prevents provider teardown.
The server continues cleanup
automatically when they finish, including after a client handover timed out.
All routes return `503` until the server factory succeeds; startup failure closes
the listener and joins its pending replies before rejecting the factory.
The newest client replaces an open session: an `initialize` that arrives
while a session is open ends that session instead of being refused, because a
client that exits without `DELETE` must not wedge the listener; the replaced
client's open streams are closed and its later requests are refused. Only an
`initialize` that carries the streamable headers (`Content-Type:
application/json` and an `Accept` naming both `application/json` and
`text/event-stream`) and passes the Host and Origin checks can replace a
session; any other sessionless POST goes to the live transport, which refuses
it without disturbing the session. Requests that carry no valid session id are
refused with `400` or `404` as the SDK transport defines. A bind is loopback by
address class, not spelling, and is classified from the address the listener
actually bound: any `127.0.0.0/8` address, `::1`, or an IPv4-mapped loopback.
Configured names, including `localhost` and its aliases, do not establish that
the bound address is local; names are added only after classifying the actual IP.
On such a bind, requests whose `Host` header is outside the SDK loopback allowlist plus
the configured name and the bound address are refused with `403`, and a browser
`Origin` outside that allowlist is refused the same way (a missing `Origin`
passes); a non-loopback bind relaxes both checks and logs the relaxation. A reply sent before a request body was read (a refused `Host` or `Origin`, an unknown route, the startup `503`) closes the connection after the reply, so an unread upload cannot keep a socket open. Request targets are taken verbatim as origin-form paths (`//host/path` is a path, not another origin); an absolute-form target, a target containing a raw fragment delimiter (`#`), or one whose path URL parsing would rewrite (dot segments such as `/public/../mcp`), is refused with `400`, and a method Fetch does not support with `405`. Percent-encoded `%23` remains valid query data. Only a lone `initialize` can replace an open session; a batch that carries one is left to the transport's refusal. Scoped
IPv6 literals (`fe80::1%eth0`) are refused before binding, because no URL can
name them. Listener errors reach the runtime's connection-loss handler only
after a successful bind; a bind failure prints the listen-failure message alone. Request bodies are bounded by the SDK's
4 MiB limit, and the response budget keeps its stdio-derived floor. The
listener ends on SIGINT or SIGTERM only, not on stdin EOF, and exits `130` or
`143` after cleanup settles. A signal that arrives while startup is still
running is recorded and acted on as soon as the listener and its providers are
owned, so startup never ends without cleanup; a second signal during startup
exits immediately.
## Progress and cancellation
REA accepts ordinary `tools/call` progress tokens. The numeric `progress` counts
@@ -569,13 +839,13 @@ auto-analysis, bridge connection, and health readiness before returning analysis
These deadlines have different owners:
| Deadline | Owner and effect |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MCP initialize | The client bounds transport/REA connection startup, before any target query. |
| Hopper startup | REA allows 120,000 ms by default; `REA_HOPPER_STARTUP_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid values fail configuration validation. Startup failure is reported by the first provider query. |
| Ghidra startup | REA allows 330,000 ms by default; `REA_GHIDRA_STARTUP_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid supplied values fail configuration validation. Startup failure is reported by the first provider query. |
| Darwin swiftc helper | REA allows 120,000 ms by default for ownership-helper compilation; `REA_SWIFTC_COMPILE_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid values fail configuration validation. |
| Individual tool call | The client bounds its wait, including cold engine startup. The pinned client SDK 2.3.1 defaults to 60,000 ms and can cancel earlier than REA's startup deadline. |
| Deadline | Owner and effect |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MCP initialize | The client bounds transport/REA connection startup, before any target query. |
| Hopper startup | REA allows 120,000 ms by default; `REA_HOPPER_STARTUP_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid values fail configuration validation. Startup failure is reported by the first provider query. |
| Ghidra startup | REA allows 330,000 ms by default; `REA_GHIDRA_STARTUP_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid supplied values fail configuration validation. Startup failure is reported by the first provider query. |
| Darwin swiftc helper | REA allows 120,000 ms by default for ownership-helper compilation; `REA_SWIFTC_COMPILE_TIMEOUT_MS` accepts decimal integers from 1–2,147,483,647 ms. Invalid values fail configuration validation. Set it in the environment that starts REA and restart REA; the next ownership-helper compile uses the new value. |
| Individual tool call | The client bounds its wait, including cold engine startup. The pinned client SDK 2.3.1 defaults to 60,000 ms and can cancel earlier than REA's startup deadline. |
For [Codex and Kimi registrations](client-configuration.md), setup supplies
missing tool deadlines from the known provider allowance plus 120 seconds of
@@ -583,7 +853,8 @@ operation headroom: 450 seconds with the default Ghidra allowance, or 2820
seconds with `REA_GHIDRA_STARTUP_TIMEOUT_MS=2700000`. Positive caller-selected
deadlines remain unchanged. Doctor reports an informational recommendation
when a configured deadline is shorter than the known provider allowance. An
explicit JEB upstream request budget also contributes to that allowance.
explicit JEB upstream deadline (`REA_JEB_MCP_TIMEOUT_MS`, shared by catalog
discovery and each tools/call) also contributes to that allowance.
For an already connected client using the pinned SDK, request options are the
**second** argument of `callTool`:
@@ -652,6 +923,13 @@ the current client, so it is not a fresh-start recovery. On the same connection:
`provider_id: "ghidra"`, then retry the first query with an appropriate client
deadline. The connection and selected provider do not need to change.
If REA's provider startup allowance also needs raising, preserve Evidence and
close as above, then update `REA_GHIDRA_STARTUP_TIMEOUT_MS` in REA's launch
environment and restart the server. Reconnect the MCP client before reopening
the target. Configuration is read at process startup; close/reopen on the same
connection cannot apply a changed environment. See the
[CLI retry example](installation.md#ghidra).
This close/reopen flow was exercised on one real Linux stdio connection after a
controlled startup timeout, followed by a successful overview and function
analysis. A separate Windows x64 stdio run with Ghidra 12.1.4, JDK 21 and Node
@@ -751,6 +1029,12 @@ after SDK conversion and check advertised validation and actual calls.
Individual model APIs can impose additional nesting limits; complete producer
captures can exceed ten structural levels.
`search_bytes` advertises its pattern and mask as descriptive strings. Its
shared canonical validator scans byte pairs, whitespace, wildcards and aligned
masks without a repeating regular expression or temporary byte arrays. The
server rejects malformed or unconstrained patterns before provider dispatch;
the advertised strings alone do not express those rules.
Boolean literal constraints in input schemas are relaxed only in this
advertisement. For example, a boolean `const` is presented as `type: boolean`;
an affected `not` is omitted, conditional predicates and their branches are
@@ -769,14 +1053,15 @@ verify the compact advertisement through the same client boundary.
Some function-calling providers reject a request while any single tool's
`parameters` schema exceeds a literal serialized size cap; Moonshot clients
such as kimi-cli fail every request while the default catalog is attached
such as kimi-cli have reported failures with the full catalog attached
([#1484](https://github.com/morluto/rea/issues/1484)). Setting the server's
`REA_MCP_INPUT_SCHEMA_PROFILE` environment variable to `compact` renders every
advertised input schema within a 13,312-byte budget, measured to sit below
`REA_MCP_INPUT_SCHEMA_PROFILE` environment variable to `compact` (the default)
renders every advertised input schema within a 13,312-byte budget, measured to sit below
Moonshot's observed cap (community measurements: a 13.7 KB schema is accepted
while a ~15 KB one is rejected). The setting is read at startup; restart the
server to apply changes, as with `REA_MCP_MAX_RESPONSE_BYTES`. The default
value `full` keeps the complete advertisement unchanged. Compact presentation
server to apply changes, as with `REA_MCP_MAX_RESPONSE_BYTES`. Explicitly select
`full` to retain complete advertised input guidance and nested validation detail.
Existing explicit profile choices are preserved. Compact presentation
also reduces schemas whose expanded JSON tree exceeds ten levels, the limit
reported by strict-depth MCP clients in [#2813](https://github.com/morluto/rea/issues/2813).
WorkBuddy/CodeBuddy gateways have also rejected full REA catalogs with an
@@ -857,6 +1142,21 @@ includes all dimension limitations. Equal CFGs establish only equal observed
block sizes and successor relationships. Text from different provider
identities remains unknown.
The `references` dimension preserves each edge's direction, endpoint identity
and available kind facts. Within one artifact it compares exact raw endpoint
coordinates, including the address space; hexadecimal case and zero padding
do not change identity. Resolving an endpoint to a containing procedure does
not replace the raw coordinate. Unparseable coordinates stay unknown.
Across artifacts, reference endpoints use stable procedure names. Missing or
address-generated names remain unknown. A name observed at multiple procedure
entries retains its label constraint but cannot establish equal endpoints.
Pairing preserves duplicate counts and considers alternative compatible
pairings; array order never identifies an edge. Compatible records with
unknown endpoint identity or kind facts remain `unknown`. Independent known
facts that contradict every possible pairing still establish `changed`.
Source Evidence retains the original addresses, names and unavailable facts.
### Comparison input shapes
`compare_web_captures` accepts exactly one of two input shapes:
+7 -5
View File
@@ -108,11 +108,13 @@ list does not establish that the target has no procedures.
| Artifact occurrence | Occurrence IDs present in schema-valid retained artifact inventory pages. |
| Residual unknown | Current non-resolved unknown heads only. |
Suggestions are Unicode-normalized, case-insensitive prefix matches. The server
deduplicates them and sorts by code point for deterministic results. Procedure
completion derives candidates from the complete inventory, so a name is offered
only when it identifies one address in that inventory. A completion reply
carries at most 100 values, the MCP limit. `total` counts every match and
Prefix matching is Unicode-normalized and case-insensitive; suggestions retain
their original spelling. The server deduplicates them and sorts by code point
for deterministic results. Procedure completion derives candidates from the
complete inventory, so a name is offered only when it identifies one address in
that inventory. Every name at a shared address participates in this check,
including later rows that establish ambiguity. A completion reply carries at
most 100 values, the MCP limit. `total` counts every match and
`hasMore` is `true` when values were omitted. Completion has no paging
controls. A longer prefix reaches an omitted value only when it excludes other
matches; matching uses normalized, case-insensitive forms, so a value can stay
+150
View File
@@ -0,0 +1,150 @@
# Model file declarations
Use `inspect_model_artifact` (CLI: `inspect-model-artifact`) to inspect a local
GGUF v2/v3 or safetensors file. Detection uses content, including GGUF byte
order, rather than its extension. REA does not load a model, interpret weights,
run inference, import Python, open external-data references or use the network.
Unsupported GGUF versions remain refused. Their diagnostic preserves the four
version bytes and both UINT32 interpretations with byte order unknown, rather
than inferring big-endian from an unrecognized little-endian value. Little-endian
v2/v3 and big-endian v3 remain supported; big-endian v2 remains refused.
```bash
rea inspect-model-artifact /absolute/path/model.gguf --json
rea inspect-model-artifact /absolute/path/model.safetensors --hash full --json
```
The CLI defaults to complete Evidence. For compact delivery with portable access
to every retained observation:
```bash
rea inspect-model-artifact /absolute/path/model.gguf \
--detail summary --evidence_output /absolute/path/model-evidence.json --json
```
## Identity and reads
The default `hash: "header"` reads only the metadata and tensor directory. The
result records the exact selected path, file size, header length, header SHA-256,
bytes read and read scope. GGUF alignment padding is outside this prefix.
`artifact.sha256` and the Evidence subject are null: a header digest is not a
commitment to the weights. Different files can have identical headers and sizes.
`hash: "full"` additionally streams the remaining file bytes through SHA-256.
It returns a full-file digest and Evidence subject, while retaining the same
header digest. It uses bounded buffers and does not interpret tensor data, but
it does read the whole file. Cost therefore grows with file size. Both modes
check descriptor and selected-path identity and metadata before completion;
this detects observed replacement or modification, not adversarial modification
that defeats filesystem metadata checks.
## Facts and selected queries
GGUF reports version, byte order, alignment, typed metadata, and each tensor's
name, original type ID, dimensions, relative data offset, file offset and derived
byte length. Alignment accepts every positive UINT32 multiple of eight, including
non-powers of two. Metadata keys use ASCII lower-snake-case hierarchy components;
standard numeric components such as `general.base_model.0.name` are preserved.
Scalar metadata is complete. Arrays have declared element types,
counts and at most eight preview elements per array, with an explicit
`preview_complete` flag. This includes tokenizer vocabularies: omitted values
are not silently represented as a complete array. Strings are UTF-8; 64-bit
integer metadata and all shape dimensions use decimal strings without rounding.
Nonfinite floating metadata uses `NaN`, `+Infinity` or `-Infinity` with its
declared float type; negative zero is `"-0"`. Unknown tensor types retain their numeric IDs and null byte
lengths; affected totals and storage validation remain unknown.
Safetensors reports the header extent, exact string `__metadata__` values, dtype,
shape and declared data ranges. JSON duplicate keys, invalid UTF-8, out-of-file
ranges, overlaps, gaps, trailing unindexed data and known dtype/shape byte-length
contradictions are rejected with a typed `file_format_rejected` constraint (public code `target_unavailable`, category `unsupported_target`). Empty
tensors and scalar shapes are supported; packed sub-byte types require whole
byte storage. Unknown dtypes retain declared ranges and an explicit limitation
that shape-to-storage validation is unavailable. Each tensor records
`storage_validation: "consistent" | "unknown"`; `coverage.storage_sizes` remains
partial when that consistency cannot be checked. Tensor filters accept these
`storage_validation` states independently of dtype or name.
Parameter counts and per-type totals are **derived from declarations**, not
measurements of effective parameters or inference behavior. Shared or repeated
weights are not deduplicated. GGUF dimensions retain their original fastest-first
order; safetensors shapes retain JSON order. Safetensors tensor rows use name
order; GGUF rows use directory order. An index identifies a declaration within
its collection and header digest, not tensor contents or a cross-version match.
GGUF supports zero extents and scalar shapes, with at most four dimensions;
known quantized types still require complete blocks in the first dimension.
MCP defaults to a compact summary with counts, selected short headline metadata,
chat-template presence and derived totals. The full type histogram and all rows
remain in complete Evidence. Headline metadata uses short keys/types and scalar
values; long or compound values remain available through explicit metadata
queries. Use the returned `parent_evidence_id`:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": {
"kind": "model-artifact",
"collection": "tensors",
"names": ["token_embd.weight", "output.weight"],
"fields": ["name", "type", "shape", "file_offset", "byte_length"],
"offset": 0,
"limit": 32
}
}
```
To answer a known question in the initial inspection, pass the same selection
without `kind` as `inspect_model_artifact`'s optional `view`, for example
`{"path":"/absolute/path/model.gguf","view":{"collection":"tensors","names":["token_embd.weight"],"fields":["type","shape","file_offset"]}}`.
This returns one selected page with compact model context and retains the full
source Evidence, avoiding another tool call. `view` requires summary delivery;
complete detail and a selection are rejected as conflicting choices.
CLI uses `--view '{"collection":"tensors","names":["token_embd.weight"]}'`
with `--detail summary --evidence_output FILE`.
Call `inspect_analysis_view` with the historical query object above for further pages. `collection: "metadata"` accepts
exact `keys`, indices, fields and paging; use it for `tokenizer.chat_template`
or tokenizer array previews. `collection: "types"` pages derived storage and
parameter totals and accepts exact `types`. Tensor pages also accept `types`.
Filters intersect; omitted filters mean all recorded rows and empty arrays mean
none. Every row retains its source-scoped index. Names, keys and type labels
follow field selection; `fields: []` returns only indices. Omitted fields return
all recorded columns. Compact warnings use the shared bounded view budget and
link to complete parent Evidence when messages are omitted. Page offsets count filtered
matches, while row indices retain their original scope. Each page carries source
identity, header coverage, array omissions, unknowns and parent Evidence links.
Pages read historical retained facts without reopening the model. Complete
Evidence can also be supplied inline or as a single authenticated Evidence JSON
record through `source: {"kind": "evidence-file", "path": "/absolute/path/model-record.json"}`.
CLI Evidence bundles contain a `records` array; import the bundle with
`import_evidence_bundle` before using retained queries, or save one complete
record as a standalone Evidence file. A bundle is not a single Evidence record.
The session owns validated indexes until that Evidence is released; there is no
live-file result cache or automatic freshness claim.
Imported reports must retain positional indices and unique names, keys and
type identities; malformed reports return a typed input error before indexing.
## Bounds and unsupported inputs
The reader admits one active inspection per provider. It enforces a 100,000,000
byte header ceiling (safetensors counts its declared JSON bytes separately from
the fixed eight-byte length prefix; GGUF counts the complete header) and a separate 32 MiB
retained representation budget before retaining rows or expanding strings.
Numeric products use exact integer arithmetic. GGUF follows its four-dimensional
tensor layout and limits metadata array nesting to 32 frames. Resource refusals
are typed, rather than returned as complete empty inventories. Cancellation
joins descriptor finalization; failed cleanup remains owned for retry.
PyTorch pickle and ZIP model deserialization are unsupported; convert using a
trusted external workflow and supply GGUF or safetensors. ONNX, TFLite, Core ML,
model execution and conversion are outside this operation.
Format references: [GGUF specification](https://github.com/ggml-org/ggml/blob/da8e2a54b919557b816b1c2beb432ccb766f7ce0/docs/gguf.md),
[ggml tensor layouts](https://github.com/ggml-org/ggml/blob/da8e2a54b919557b816b1c2beb432ccb766f7ce0/src/ggml-common.h),
[safetensors format](https://github.com/huggingface/safetensors/tree/e246a2560645b7525f5775669ed816eb57c5bcc8#format).
+120
View File
@@ -0,0 +1,120 @@
# Match native functions across builds
`match_native_functions` pairs two existing `list_procedures` Evidence inventories. Select `list_procedures` `detail: "summary"` to retain
complete source rows without transferring the entire inventory. Its
`parent_evidence_id` is the reference matching consumes.
Targets may be opened sequentially; matching never opens a target, rereads its
file, executes it or starts a provider. Preserve each inventory before closing its
target, or import its Evidence bundle later. `close_binary` clears session
records. Export each bundle before closing; after collecting both sides and
closing the last target, import both bundles, then use their references. Keeping
only an Evidence ID across close is insufficient. Complete inline Evidence and
CLI `source_bundle` inputs are portable alternatives. Pass Evidence or exact
session references as `left` and `right`:
```json
{
"left": { "kind": "retained-evidence", "evidence_id": "ev_<left digest>" },
"right": { "kind": "retained-evidence", "evidence_id": "ev_<right digest>" }
}
```
Unique exact reported names are paired first. Optional `list_names` Evidence
identifies dynamic/default names to exclude. If origin is unavailable, the
existing automatic-name exclusion rule applies and each function retains that
limitation. Exact names establish name correspondence, not unchanged code or
original-source identity.
For unmatched candidates, optionally supply `left_observations` and
`right_observations`. `procedure_info` or existing `analyze_function` Evidence
gives exact inclusive body ranges; `read_bytes` supplies memory bytes. Observations
must belong to the side's exact target/provider/profile and document context.
Adjacent, consistent overlapping and partially returned reads compose by their
observed extent; conflicting intervals remain gaps. A byte match requires every
body byte, equal total size, equal ordered range lengths, a unique SHA-256
fingerprint and the same known architecture. Extents are never guessed from the
next entry, and relocations are not normalized. A larger mapped read can serve
several observed bodies; only needed ranges need to be captured.
This first slice reuses existing range observations. Stripped builds can require
many lightweight range queries when those facts are not retained yet. Matching
does not hide that acquisition cost or silently start those queries. Full
decompilation is unnecessary.
Repeated candidates stay `unresolved` groups without a Cartesian pair expansion.
`only_left`/`only_right` mean no exact counterpart in the supplied observations;
renaming, inlining, stripping, changed bytes or incomplete discovery can explain
them. They do not prove source addition/removal. `source_coverage` explicitly keeps
inventory completeness unknown and separately counts known byte fingerprints and
resolved correspondence. Provider limitations remain accessible.
Default `detail: "summary"` retains complete matching Evidence in MCP and returns
counts, both identities and coverage. Query its `parent_evidence_id`:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "ev_<matching digest>"
},
"view": {
"kind": "function-matches",
"collection": "functions",
"states": ["matched"],
"sides": ["left"],
"fields": ["name", "body_sha256"],
"offset": 0,
"limit": 20
}
}
```
`collection: "matches"` returns relation identities, states, basis and member
counts. Large member lists are omitted by default; select `left`/`right` columns
explicitly or page individual `functions`. Batch `match_ids`/`function_ids`, exact function `names`, state
and side filters intersect. Mandatory identities and provenance survive column
selection. Page coverage covers selected retained facts. Function identity binds
inventory Evidence and the owning inventory’s `source_index`, preserving same-address alternatives.
One validation, lazy member index and bounded recent filter are retained per
immutable parent; no live target state is cached.
When both functions already have unambiguous `analyze_function` dossiers, a matched
relation includes `compare_functions_input` with directly usable retained
references. Otherwise analyze just the selected canonical addresses in their
respective targets, then compare those dossiers. Matching never claims behavioral
equivalence. Optional informative CFG/call/string fingerprints from supplied
dossiers connect unresolved candidate groups only. They require observed CFG,
callees and strings, complete observed call coverage, no unresolved calls, and
the same analysis-profile identity. Empty leaf-function buckets are excluded.
`structural_candidate_sha256` identifies that derived candidate signature; its
dossier link preserves the full supporting facts. Group membership does not
assert that every member pair is a candidate or equivalent.
CLI uses the same service and JSON input:
```bash
rea match-native-functions request.json \
--source_bundle left-bundle.json --source_bundle right-bundle.json \
--evidence_output matching-bundle.json --json
```
`source_bundle` resolves exact references from authenticated local bundles.
Default summary requires `evidence_output`, retaining full matching Evidence and
its selected source closure, including transitive Evidence links across supplied
bundles. Missing dependencies fail with an integrity error; unrelated records
are omitted. Publication never overwrites. Set `detail: "complete"`
in the JSON for all groups inline. Import the bundle into MCP for views, or
extract its matching Evidence record to a JSON file for the existing CLI
`inspect-analysis-view` `evidence-file` source. Input bundles are unchanged.
Representation admission is bounded at 96 MiB before cloning selected observations
and expanding matching indexes and repeated per-function source links. Work yields to cancellation. No worker/provider
concurrency is introduced; this budget is not a bound on total process RSS.
The self-owned source fixture is [nativeFunctionMatching.c](https://github.com/morluto/rea/blob/main/tests/fixtures/nativeFunctionMatching.c).
On Linux x86-64, compile with `cc -O2 -g0 -fno-pie -no-pie -DVERSION=1` and
`-DVERSION=2`; copy the second binary and run `strip --strip-all` on that copy.
It includes unchanged/changed code, a byte-identical rename, a removed/added
observation, an inlined function, identical-code aliases and a renamed changed
function with an observed call/string signature. Analyze without executing the
fixture. Full-provider verification still needs caller-supplied Ghidra and Java.
+165 -24
View File
@@ -202,8 +202,38 @@ Function dossiers retain this same string evidence. Native call edges retain
Hopper's partial `CallReference` classification and exact endpoints; detailed
reference flags remain unavailable rather than being invented.
Regex searches use ECMAScript Unicode syntax in a cancellable worker with a
five-second matching deadline. Deadline or cancellation stops matching while
leaving the Hopper API available. Literal mode retains Unicode casefold matching.
five-second matching deadline and a worker old-generation heap. Deadline or
cancellation stops matching while leaving the Hopper API available. This
release has no runtime override for that deadline. The worker requests 128
MiB. A positive Node.js `--max-old-space-size` on the process that starts
REA, including `NODE_OPTIONS`, overrides that request and sets the effective
heap. `--max-old-space-size-percentage` takes precedence over that flag in
either order. REA does not turn the percentage into a MiB, so the effective
heap stays unestablished instead of the 128 MiB request or the absolute flag.
The reported `NODE_OPTIONS` value is the process initial environment when that
block can be read. A later edit to the environment is not the value Node
applied, and an unreadable initial value leaves the effective heap
unestablished. The launch Node options are the initial command line on Linux
when that buffer still has a program entry, not a later edit to
`process.execArgv`. A preload can clear that array after V8 has applied the
flags. Setting `process.title` or `--title` overwrites the command line, so a
buffer without a program entry leaves the effective heap unestablished.
`--env-file` or `--env-file-if-exists` can supply `NODE_OPTIONS`
when the initial environment has none. That file is not part of the initial
environment block, so the effective heap stays unestablished instead of the
128 MiB request. An initial `NODE_OPTIONS` is still used, because Node does
not let the file replace it. A positive `--max-heap-size`, including the
underscore form and launch `NODE_OPTIONS` on Node versions that allow it,
sets the total heap rather than the old generation and can be lower than the
128 MiB request. The effective old generation stays unestablished while that
value is in effect. A zero or empty value clears it.
`--experimental-config-file` or `--experimental-default-config-file` can set
`nodeOptions`, including a heap percentage, from a file that is not read
back. The effective heap stays unestablished when either flag is present,
including when an absolute `--max-old-space-size` is also on the command
line or in the recovered `NODE_OPTIONS`. Node accepts the config path as
`=` or the next argument.
Literal mode retains Unicode casefold matching.
## Bounded static traces
@@ -216,6 +246,36 @@ sites remain distinct. A static route does not establish runtime reachability.
Swift/closure dispatch requires resolved static references; unavailable ABI
forms remain unknown.
Incomplete reference kinds do not discard known typed calls or partial
provider call references. A `provider_call` with `observed` resolution retains
the provider-reported call site and endpoint without claiming generic direct,
indirect or Objective-C dispatch semantics. Its `call_reference` evidence
preserves the original endpoints, classification, raw provider type and
provenance, even when the target node is a containing procedure. Hopper's
`none`, `unknown`, `direct` and `objective_c` labels stay provider-scoped;
unknown numeric types remain available in the raw type field. Target-only
callee fallback uses `provider_call` with `inferred` resolution.
Callee fallback adds inferred targets while each retained route keeps its
original provider and call site. If enumeration fails, known routes remain alongside an unresolved
failure; cancellation still terminates the request. A node-limit omission keeps
the route's known relation while marking its target unresolved. Distinct call
sites to the same omitted target retain separate evidence.
Reports sharing a call site and containing target procedure retain all their
original endpoint evidence on the shared graph edge. Different reported
relations retain separate edges, independent of enumeration order.
Session discovery describes two automatic source routes for this trace:
`authored_ui_dispatch` needs Interface Builder decoding and dispatch metadata;
`native_seed_call_trace` needs native address resolution, dispatch metadata and
a call reader. Metadata can come from direct inspection or `list_names`;
the call reader can supply typed `procedure_references` or inferred
`procedure_callees`. An authored UI-to-handler edge remains useful without
call expansion, and native-seed tracing can proceed without UI decoding.
These routes add no request option or default mode, so discovery omits
`default_mode_available`. Availability describes source prerequisites;
the result reports the query's actual matches, coverage and failures.
`trace_native_values` / `rea trace-native-values <binary> <procedure> --provider
ghidra` composes high-p-code def-use graphs across statically resolved calls.
Logical CALL arguments bind to recovered parameter ordinals; recovered RETURN
@@ -268,13 +328,25 @@ markup, including UTF-8 and BOM-marked UTF-16 sources. Unidentified text and
OpenStep plists, including a data-only value such as `<deadbeef>`, report
`unknown` even when plutil decodes their values through an XML conversion.
Binary plist inspection reads the original bytes through an owned file descriptor,
so conversion cannot erase control characters, fractional dates, negative zero,
or the high word of a 128-bit integer. It accepts at most 64 MiB of input and
reserves an estimated 64 MiB decode budget before parsing; this estimate is not
a hard process-memory bound. A refused input reports non-retryable
`resource_constraint` with `reported_limits.maximum_input_bytes`,
`maximum_decoded_bytes` or, for nesting deeper than 128 levels,
`maximum_nesting_depth`. These are fixed allowances: worker limits and host
memory do not raise them, and the unchanged request fails the same way.
Binary-source provenance records the `file` classification without claiming a
`plutil` conversion.
A plist explicitly selected through the path input or as the active plist target
reports an unreadable or malformed selection as `invalid_request`. A missing or
unreadable default plist of another target reports `capability_unavailable`.
Permission failures remain `access_denied`; output and cleanup failures retain
their own error categories.
A plist decode refusal includes plutil's diagnostic from either output stream.
A conversion refusal includes plutil's diagnostic from either output stream.
`details.captured_output` retains bounded stdout/stderr excerpts, observed byte
totals and exit status. `truncated: true` means those excerpts are incomplete.
@@ -337,6 +409,12 @@ complete observation.
Object `kind` describes the decoded archive value: data, dates and numbers
remain `scalar` when their JSON value uses a `$plist_type` wrapper. An actual
dictionary with the same fields remains `dictionary`.
XML must be well-formed. Data literals use
[CoreFoundation's raw ASCII quartet rules](https://github.com/swiftlang/swift-corelibs-foundation/blob/384ff680be7c7445fee6ce0c55e9ae11a46e07c5/Sources/CoreFoundation/CFPropertyList.c#L1588):
non-alphabet ASCII characters are ignored and an incomplete final quartet
emits no bytes. Character references retain their source spelling for data
decoding. Non-ASCII content, child markup and self-closing `<data/>` are format
failures; explicit `<data></data>` represents empty data.
UID 0 cannot distinguish conditional nil from ordinary nil. Limits are
64 MiB of input, 200,000 objects/references and 128 nesting levels.
XML dictionary entries decoded as `__proto__` are omitted with an explicit
@@ -389,10 +467,32 @@ complete observation.
vtable descriptors. Records include exact virtual addresses/file offsets and
artifact evidence. Vtable indexes are metadata word offsets; witness indexes
start after the conformance header. Names unavailable in metadata remain null.
The `swift_class_vtable_descriptors` coverage counters count examined vtable
slots and successfully decoded slots, rather than type-section entries.
The `objc_class_method_ivar_metadata` counters count admitted class and
metaclass objects and successfully decoded objects.
Pointers are decoded through the image's fixups:
- `LC_DYLD_CHAINED_FIXUPS` rebases and binds, including the authenticated
arm64e formats;
- legacy `LC_DYLD_INFO` bind opcodes.
- legacy `LC_DYLD_INFO` rebase and bind opcodes.
A Swift conformance whose type or protocol reference is an external bind
keeps its name as `null` and carries the raw dyld identity in
`type_binding` or `protocol_binding`; that record and its facet coverage are
partial. Consumers of this output must handle nullable conformance names
and use the typed binding fields instead of substituting a symbol as a
display name. Indirect relative-pointer records also retain their binding
identity. A decoded rebase to virtual address zero remains an address; only
an unfixed zero in a nullable ABI field is treated as null. Incomplete or
conflicting fixup streams keep affected pointers unresolved; coverage reports
parsing and resource limits while retaining validated prefix facts.
Conformance records preserve the raw three-bit `type_reference_kind`. Kinds
0 and 1 identify direct and indirect nominal descriptors; kind 2 preserves
the inline Objective-C class name and its source location. Kind 3 preserves
an imported class binding or the local class-object address when available,
but class metadata/name recovery requiring the Objective-C runtime remains
partial. Unknown kinds retain the raw kind and reference location without
being treated as absent or assigned a guessed type name.
So an external superclass resolves from its `_OBJC_CLASS_$_` bind (for
example `NSObject`). The `pointer_fixups` coverage facet names the mechanism.
@@ -424,6 +524,27 @@ complete observation.
address is retained as `reported_address` in the symbol's evidence, whose
location also remains unknown. Nonempty provider address syntax is preserved.
Session discovery reports this workflow available when the bound provider
offers direct metadata inspection or a `list_names` symbol inventory. The
workflow tries direct metadata first and uses the symbol fallback only when
that operation is unavailable; runtime failures remain failures rather than
being replaced by symbol-only results.
`get_objc_classes` keeps names from the provider inventory. It coalesces rows
only when their exact selected-image pointer slots decode to the same class
import, including its binding stream, raw library ordinal, resolved library, weak status, and addend. A literal filter is
applied to the original names before that join; if the filter selects only an
alias, the output keeps that exact row. `identity_coverage` distinguishes a
complete selected-inventory scan from partial, unsupported, and unknown cases.
Recognized Mach-O formats outside the native metadata reader's support retain
the provider's class labels with unknown import identity; malformed headers and
read failures remain errors.
The join also requires matching whole-artifact digests and matching provider-
owned selected-image facts: container, byte range, full raw CPU type/subtype,
and FAT table digest when present. A missing or overridden loader selection
remains unknown; the result describes agreement on the selected artifact image,
not an atomic observation of a running process or whole-program class coverage.
## Native desktop observation
`observe_native_ui` captures one explicitly selected existing PID/window ID.
@@ -446,8 +567,10 @@ cleanup. A later abort does not replace an earlier helper or output failure.
Cleanup failures retain their runtime owner until a confirmed cleanup retry.
Scenarios accept caller-selected action lists and accessibility node counts.
Individual waits cannot exceed the operation's 180-second deadline, and the
complete scenario result has a 64 MiB output budget. Screenshots are scaled to
One wait step stays capped at 180000 ms. That cap has no runtime override.
The operation deadline is `native_ui_deadline_ms` (omitted means 180000 ms)
and does not raise the wait-step cap. The complete scenario result has a
64 MiB output budget. Screenshots are scaled to
at most 2,048 pixels and captured only for the selected window. REA compiles one
owned helper per scenario, removes its temporary compiler cache and stops its
helper on cancellation. It does not launch or own the selected application. UI
@@ -598,9 +721,11 @@ digests identify the original serialized bytes.
The archive reader observes XML number element types and binary number markers.
XML values and their number facts are interpreted together from the validated
DOM. Hexadecimal `<integer>` text, including an optional sign, retains its value;
DOM and its original scalar source spans. Hexadecimal `<integer>` text, including
an optional sign, retains its value;
`<real>` text and CDATA segments are combined without inferring text from nested
elements. The XML path does not serialize or reparse character references.
elements. Real character references expand outside CDATA; integer and date
literals use raw source text.
Integers beyond the exact range of a JSON number are reported with the original
decimal text as `{ "$plist_type": "integer", "decimal": "<exact digits>" }` when
that source value can be associated unambiguously. Integral real values remain
@@ -609,9 +734,9 @@ markers remain decoded with an explicit precision limitation. The limitation
also counts observed unsafe integer literals, including observations outside the
selected object page. Incomplete supplemental metadata produces an explicit
precision note without rejecting an archive accepted by the byte decoder.
Mixed XML number content (comments, CDATA, processing instructions or child
elements) and integer text the supplemental reader cannot classify disable exact
association and retain decoded numbers with that precision note. Nonnumeric
Malformed XML scalar content becomes an explicit unknown rather than a prefix
number, guessed timestamp, or tag-only boolean. These unknowns do not disable
exact association for unrelated observed numbers. Nonnumeric
`UID` and `CF$UID` dictionary values remain ordinary data and are projected
recursively; numeric reference markers retain their original representation.
@@ -632,11 +757,21 @@ decode budget reserves estimated room for number metadata and attribute
projection; these estimates are not a hard process-memory bound. Native
NIBArchive decoding is unchanged by this plist-specific representation.
Dates are reported as `{ "$plist_type": "date", "iso8601": "<timestamp>" }`. A
date the decoder cannot represent, such as an XML date with a year beyond 9999
or a negative year, is reported as `{ "$plist_type": "date", "iso8601": null }`
with a counted limitation; the rest of the plist or archive is still decoded.
`inspect_plist` and Interface Builder decoding use the same projection.
Dates are reported as `{ "$plist_type": "date", "iso8601": "<timestamp>" }`.
XML dates require a complete UTC spelling with fixed two-digit month, day and
time fields; short, negative and extended years are interpreted as UTC year
fields within JavaScript's date range. Unsupported calendar fields (including
leap seconds) and out-of-range dates remain explicit unknowns. REA does not
emulate CoreFoundation's normalization of overflowing calendar fields. Invalid
dates returned by other decoders retain `{ "$plist_type": "date", "iso8601": null }`
with a counted limitation. `inspect_plist` and Interface Builder decoding use
the same projection. Binary plist decoding refuses a reachable date whose marker
is not `0x33`; date and numeric payloads must end before the offset table.
Valid overlapping object records retain their independent source values. A valid `0x33` date is
reported with an ISO-8601 timestamp only when its float64 seconds are exactly
the canonical encoding of that millisecond instant. Any other finite binary
date uses `{ "$plist_type": "date", "iso8601": null }` and the counted
limitation; the archive bytes remain the source of the instant.
A negative-zero real is reported as `{ "$plist_type": "real", "value": "-0" }`
because a JSON number cannot carry the sign of zero. `inspect_plist` and
@@ -653,14 +788,20 @@ for those details. XML CFPropertyList literals (`nan`, `+infinity`, `-infinity`,
`infinity`, `inf`, `+inf`, `-inf`, case-insensitively) decode to the same known
values. Case and aliases normalize; original archive bytes retain source text.
XML numeric text whose identity the decoder cannot establish, including
unrecognized non-finite text and finite literals that overflow the numeric
representation, remains `{ "$plist_type": "real", "value": null }` with a
counted limitation. The XML decoder marks these values explicitly before shared
projection, so they cannot be confused with known binary IEEE values.
Incomplete numeric markup retains its existing compatibility behavior described
above. Known non-finite and unresolved numeric values have separate counts.
Native `inspect_plist` uses these same labels for plutil's XML conversion.
XML scalars whose identity cannot be established use
`{ "$plist_type": "unknown", "element": "integer" | "real" | "date" | "true" | "false", "literal": "<original content>", "reason": "invalid-literal" | "unsupported-markup" | "unrepresentable" }`.
A counted limitation accompanies these wrappers. Literal content retains its
original entity spelling, markup and line endings. Whole XML documents must
still pass strict well-formedness checks. Empty integer, real and date elements
are unknown scalars; boolean elements must be empty. Complete decimal/exponent
reals and signed decimal/hexadecimal integers accept their respective native
leading whitespace but reject trailing text. Arbitrary-precision integers
remain an intentional REA extension beyond CoreFoundation's integer range.
Finite real spellings that overflow the numeric representation remain unknown,
rather than becoming observed infinities. Known non-finite and unresolved scalar
values have separate counts. This replaces the former prefix-number and
incomplete-metadata fallback for malformed XML numeric content. Native
`inspect_plist` uses the same projection for plutil's XML conversion.
## Locate a byte signature
+5 -1
View File
@@ -67,7 +67,11 @@ Addresses count once per packet, including loopback and nested IP occurrences.
DNS addresses are associated only with one question in the same response packet;
additional records may be included, so this does not prove final resolution.
Ambiguous addresses remain in a separate inventory. Protocol distribution counts
exact `frame.protocols` stack strings. TLS SNI is recorded handshake metadata,
exact nonempty `frame.protocols` stack strings. Frames for which TShark reports
an empty stack, including zero-length packets, still contribute to the packet
count without adding a protocol row. An all-empty stack inventory can have
complete examined coverage; it does not establish the absence of network traffic.
TLS SNI is recorded handshake metadata,
not process identity or proof of the destination's authenticity.
All examined inventories are retained within the resource budget; no fixed
+83
View File
@@ -38,6 +38,10 @@ supervision on macOS. REA removes that directory when it exits. REA does not
install Xcode, Command Line Tools, or other software. Capability checks prepare
this helper before reporting macOS capture as available.
Stopping process sampling or cancelling an ownership query waits for its issued
inspection command to exit. Closing a macOS ownership reader rejects new queries
and waits for admitted helper commands before removing their executable directory.
## Capture a command
For a small first capture, save this as `scenario.json`:
@@ -241,6 +245,15 @@ follow also remain unknown. Partial enumeration of one root does not erase
known effects in another, and unavailable content hashes do not by themselves
make path absence unknown.
When a follow-up read fails after an entry's metadata was observed, the
snapshot keeps unaffected observations and records an `entry_unavailable`
enumeration omission with the root-aliased path and system error code.
Successfully observed identity replacements use `identity_changed` with a null
system code. Unstable symlink targets are omitted; already observed directory
metadata remains available. The affected root stays incomplete, so omitted
entries do not prove deletion. A path missing at its initial lookup remains an
observed absence. Cancellation and unexpected I/O failures still stop capture.
Terminal frame `data` is the comparison text after the selected normalization.
New captures also preserve `raw_data` when normalization changes a PTY chunk;
otherwise `data` is already the original text. Older captures may lack the
@@ -419,6 +432,17 @@ Every capture requires `truncation_details`, with separate accounting for:
imply incomplete path enumeration.
- `process`: sampling limit and whether sampling ended partially. Coverage
remains `sampled`, including when that limit was not exhausted.
`sampling_failures` counts failed read observations plus at most one
unfinished pass interrupted by sampler shutdown. `first_sampling_failure`
retains the first attributed read diagnostic, with shutdown context appended
when applicable; interruption alone has an explicit shutdown diagnostic.
Denied or failed procfs reads mark
sampling partial while preserving readable process rows and thread children;
a process with unreadable identity is not attributed. Expected process-exit
races are separate from failed observations. Shutdown counts only when it
interrupts a read or leaves traversal unfinished; a completed pass does not
become partial merely because the sampler stops. Completed rows
remain available and issued reads settle before final coverage is returned.
The aggregate `truncated` flag summarizes these observations. Comparisons retain
results for unaffected dimensions and mark affected dimensions unknown; an
@@ -435,12 +459,62 @@ Each filesystem checkpoint starts with a fresh `file_bytes` budget across all
selected roots; it is not a per-file allowance. File contents are read in
64 KiB chunks for hashing and are not embedded in capture Evidence.
Ownership inspections bind run-token reads to native start identities and retain
related generations through reparenting, group changes, omitted rows, and cleanup
retries. A host without native identity reads still token-checks process-table
rows that appear only in a launcher-exit refresh before reporting that group
clean or publishing an empty lineage. A matching token authorizes a signal only
for a group whose leader carries the same token. A matching token whose leader
is absent, or an unreadable token for a still-live new row, stays unresolved. A
readable foreign token is not signaled. An unreadable row that has exited by
the confirmation read does not hide a new row in that confirmation table, and a
group proven while revalidating another owned group is signaled in the same
cleanup. A matched row that changes parent or group on the confirmation read
is token-checked again. A PID whose token was already read is read again
on the next confirmation even when its parent and group return to the
pre-exit values. A PID whose first token was foreign is read again
on that table, because the PID alone does not identify the process. A PID
from the pre-exit table is read again when its parent or group changes, and
an unchanged pre-existing row that was never token-read stays unread. Lineage
publishes one row for each PID. Confirmation reads are bounded; a table that keeps producing unreadable
replacements stays unresolved. That refresh does not retain a ledger
for a later attempt that never observes the launcher. Lineage reads a row again
when its parent, group, or launcher-tree membership changes, and it reads a
token again on the next refresh even when those fields are unchanged. The
launcher is read on every lineage refresh; a missing, unowned, or
relation-changed launcher PID is not published as a verified lineage. A
descendant absent from the latest refresh is omitted. An
ancestor move cannot leave a foreign descendant inside a verified result. A
group that reappears after cleanup already processed it is revalidated once;
another appearance stays unresolved. The captured run keeps
one evidence owner through settlement and cleanup.
An absent or changed token leaves a previously related generation unresolved;
current token proof is still required before signaling. Swept cleanup verifies the
remaining family after its group signals. Coverage is bounded by the native
snapshots and generations inspected; sampled group IDs select candidates.
When the host withholds an unrelated process’s ownership token, REA leaves that
process untouched and records its PID and reason in `cleanup.unverified_processes`
and process residual unknowns. Successful cleanup verifies the owned group;
it does not attribute those unrelated processes. Related or otherwise unexplained
unreadable processes still prevent successful cleanup.
Failed cleanup retains its exact resources for the owning session to retry.
The CLI retries before projecting its error; MCP retries pending cleanup before
admitting another capture and during session cleanup. Once every attributed
owner confirms release, the live error status clears `cleanup_incomplete`.
The original failure, observations and `cleanup_report` retain the facts from
the earlier attempt, including any cleanup failure recorded then.
Snapshot file handles, directory handles, and the selected executable reader
follow the same ownership rule. A failed close preserves completed observations
and any primary read failure; it cannot turn a completed digest into a successful
capture with unresolved cleanup. Interrupted snapshots retain examined entries
with incomplete coverage in `partial_observation`, alongside the failure.
File-handle retry uses the exact retained owner. After a directory close rejects,
Node does not expose enough handle validity to authorize another native close;
REA retains that unresolved owner and blocks further captures in the session.
On macOS, changing a Node process's `process.title` can make its run token
unreadable. Node documents that [setting the title overwrites argv memory](https://nodejs.org/download/release/v24.18.0/docs/api/process.html#processtitle).
With the pinned toolchain, a live child retained a readable start identity
@@ -471,6 +545,15 @@ missing or relative SDK/compiler path fails with an actionable prerequisite
error before compilation. An incompatible installation reports the compiler's
bounded diagnostics; REA does not repair or replace the toolchain.
The compile deadline is `REA_SWIFTC_COMPILE_TIMEOUT_MS`. An omitted value is
120,000 ms, and accepted values are integers from 1 to 2,147,483,647. REA reads
the variable from the environment that starts the process and keeps that
deadline for every helper compile in that process. Restart REA to apply a
change; the next ownership-helper compile uses the new value. A timeout names
the effective milliseconds. Invalid values fail configuration validation at
startup. Embedded compiler diagnostics are cut at 512 bytes, and this release
has no runtime override for that excerpt.
For example, select paths from your existing Xcode or Command Line Tools
installation **before** entering an enforced write boundary:
+128
View File
@@ -0,0 +1,128 @@
# Python packaged applications
REA statically inventories PyInstaller executables with an appended CArchive.
`inspect_artifact` and `extract_artifact` share the same reader through CLI and
MCP. They read archive bytes without launching the application. Bytecode
source decompilation, encrypted PYZ recovery, zipapp and PEX analysis are outside
this capability.
## Facts and focused queries
The root occurrence's `format_metadata` records the CArchive layout (2.0 or
2.1), archive and cookie offsets, table extent, entry count, raw Python version,
normalized major/minor when known, library name and encryption marker. Member
metadata retains the original name, table index, type, compression flag,
relative offset and known directory record extent. Logical paths use archive
path rules; the source name retains its spelling, including backslashes.
`relative_offset` is relative to the CArchive start for CArchive rows, or to
the decoded PYZ image for PYZ rows. A CArchive directory record starts at
`archive_start + toc_offset + directory_record_offset`; its size is
`directory_record_size`. PYZ row directory extents remain unknown.
Namespace packages remain directories. Their `relative_offset` and
`compressed_size` preserve any payload declared by older producers, while
`declared_size` is zero because no bytecode is materialized for a namespace.
Every declared span must end before the PYZ table of contents.
PYZ `compression_flag` is derived from storage: nonempty payloads are compressed,
including legacy namespaces; an empty namespace has no compressed payload.
CArchive type `o` entries are runtime options. They are metadata occurrences,
with no content artifact or extractable file. Their query paths are
`__pyinstaller__/runtime-options/<table index>`; the option text is
`format_metadata.source_name`. Repeated declarations retain distinct occurrence
identities. These paths do not claim output filesystem names.
Type `d` entries are multipackage dependencies. They are also metadata, under
`__pyinstaller__/dependencies/<table index>`, and never materialize an empty file.
The reader preserves the raw reference and splits its first colon into
`dependency_archive` and `dependency_member`. `dependency_status` remains
`unresolved`, or `invalid-reference` with unknown parts for malformed references.
`external_dependency_count` summarizes these declarations. REA does not open
another executable or claim its contents are available. A real file with the
same logical path as metadata remains independently extractable.
Both declaration types require empty payloads and no compression. Their query
paths do not participate in filesystem collision checks, directory ancestry or
source-map target lookup; their parent identifies the declaring container.
Complete authenticated inventory page sets preserve producer identities in any
merge order, including metadata/file aliases. Malformed TOC diagnostics name the
table index; original names remain available in the supplied artifact.
Path failures use bounded escaped previews and report the original length;
accepted paths and retained source names are not shortened.
Request `detail: "summary"` for a compact inspection, then query retained
Evidence with `inspect_analysis_view`. An inventory view can select
`collection: "occurrences"`, `entry_kinds: ["metadata"]`, exact logical paths or
occurrence IDs, requested `fields`, and `offset`/`limit`. Filters intersect;
identities, parent Evidence and coverage survive projection. Full inventory
Evidence remains available for export. A compact reply reduces returned context;
it still performs the complete member inventory and hashing work.
Focused views add calls and tool-schema costs. A complete small inventory can
cost less overall; prefer compact delivery when the full member graph would
overwhelm the answer.
```bash
rea inspect-artifact /absolute/path/hello --detail summary --evidence_output /absolute/new/evidence.json --json
rea extract-artifact /absolute/path/hello --json
```
## Decoding and evidence limits
Inventory hashes members individually through bounded streams. Stored PYZ
images use descriptor ranges; outer-compressed images stream to private files,
which the reader owns through cleanup and any cleanup retry. Extraction binds
the selected carrier to its inventoried digest and checks source identity and
state before and after reading. It does not retain expanded module bodies.
Opaque outer-compressed images reuse that verified private image when opened,
instead of inflating the carrier again. Direct source spans describe stored
CArchive bytes; decompressed content has no direct span even when its encoded
and decoded sizes coincide. Original offsets and compression remain metadata.
Only the PYZ header and marshal directory are loaded for listing. PYZ tables
have a 16 MiB budget; CArchive tables have a 32 MiB budget. Parsed facts have a
32 MiB serialized budget. Projected entries share a 64 MiB retained budget,
including metadata, bookkeeping and conservative reservations for namespace
objects and possible case-collision annotations at each path component. These
reservations happen before normalization or trie allocation.
Outer-compressed PYZ images have a separate per-reader capacity of 128 private
files, bounding retained inodes and image identities. The complete image count
is admitted before any temporary file is created; excess images return a
capacity failure. This is a resource policy, not a PyInstaller format limit.
Only a zero-byte read establishes EOF; short successful descriptor reads fill
the bounded range. Compressed members must consume their complete declared
input span; trailing junk and concatenated streams are refused.
Plaintext expansion has an aggregate archive-derived budget. Exceeding a budget
returns a resource failure.
Supported final Python bytecode magic values cover Python 3.7 through 3.14.
Supported marshal directory values are lists, tuples, strings, integers and
bytes. An unsupported magic or directory stays an opaque member with a
limitation and `pyz_status: "opaque"`; its module contents remain unknown.
Any opaque PYZ makes producer traversal coverage unknown, including retained
summaries and exhausted queries. Per-archive reasons remain on the opaque
occurrences; the coverage observation summarizes their count without repeating
every limitation. An empty result does not establish module absence.
Observed `pyz_python_magic` bytes remain available even when their Python version
is unknown.
The directory declares compressed module lengths, so uncompressed declared
sizes and source spans inside decoded data remain unknown.
PYZ modules receive a derived 16-byte `.pyc` header from their own supported
magic. CArchive bytecode receives that header only when every sibling PYZ magic
and the cookie's Python version agree. Otherwise it retains its original bytes
and `bytecode_header: "unknown"`. `bytecode_magic` and graph derivation edges
identify synthesized headers; member digests cover the resulting derived files.
These headers do not establish successful execution or decompilation.
The nonempty CArchive Python module `pyimod00_crypto_key` (`m`/`M`) is recorded
as an encryption marker; a same-named data file or script is not. Affected
PYZ blobs are reported without decoding; extraction refuses encrypted entries.
The raw PYZ container remains readable and hashable, including when its module
table is opaque. Its marker stays in metadata and opaque child coverage stays
unknown; extracting the container does not decrypt its payloads.
The marker also applies to nonempty legacy namespace payloads. Empty namespaces
have no payload to encrypt and retain a null encryption source.
Detection searches the last 16 MiB for a cookie, allowing a trailing macOS code
signature within that bound. Member offsets are relative to the archive start:
cookie position plus cookie size minus package length. Native bootloader
analysis remains available through the native tools.
+4
View File
@@ -146,11 +146,13 @@ npx rea-agents@latest setup
| شيفرة EVM البايتية | محددات التوجيه، وإزاحات البايتات، والمعاملات المستنتجة، وقابلية تغيير الحالة | مدخل محلي يحمل بايتات خامًا أو تمثيلًا سداسيًا عشريًا على Linux x64؛ [دليل EVM دون تشغيل](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| أعطال Linux المسجّلة | سجلات note الخام، ومسجّلات المعالج/الإشارات لكل خيط مسجّل، وترشيحات اختيارية لخرائط الذاكرة | pwntools يوفّره المستدعي على Linux x64؛ GDB/pwndbg اختياريان؛ [الأعطال المسجّلة](../recorded-crashes.md) |
| تثبيتات سطح المكتب | عائلات وقت التشغيل، والملفات الداعمة، وعلامات المكونات، والخطوات التالية | فحص محدود للملفات والترويسات;[تطبيقات سطح المكتب](../desktop-applications.md) |
| JavaScript / Electron | الوحدات، وعمليات الاستيراد، وخرائط المصدر، والمسارات، وIPC، وعلاقات إضافات الشيفرة الأصلية | Node.js وnpm؛ [تحليل التطبيقات](../javascript-application-workflows.md) |
| المواقع | بنية الصفحة، والسكربتات، وملاحظات الشبكة، ولقطات الشاشة المطلوبة | متصفح من عائلة Chrome؛ [تحليل المتصفح](../browser-observation.md) |
| تسجيلات الشبكة المحفوظة | الطلبات، والاستجابات، ومحتويات الحمولة المتاحة، ومواضعها في المصدر | HAR؛ وmitmdump على Linux لتسجيلات mitmproxy بصيغتها الأصلية؛ [دليل تسجيلات الشبكة](../web-network-captures.md) |
| التقاط الحزم | نقاط النهاية وDNS وTLS SNI وتوزيع البروتوكولات وطلبات HTTP | tshark وcapinfos يوفّرهما المُستدعي؛ [دليل pcap](../pcap-analysis.md) |
| تجميعات .NET | البيانات الوصفية، وتعليمات CIL، واعتماديات الشيفرة الأصلية المعلنة، ومقارنات البناء | فحص ثابت؛ [دليل الشيفرة المُدارة](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| حزم Android APK | تصريحات ملف manifest، والأصناف، والدوال الناتجة عن فك الترجمة، والمراجع | JADX دون واجهة رسومية وJDK كامل على Linux/macOS/Windows x64؛ [دليل Android](../android-analysis.md) |
| أجهزة Android | الأجهزة والحزم والعمليات والسجلات والدامبات ولقطات الشاشة ونقل APK/الملفات | adb يوفّره المُستدعي (محاكي أو جهاز)؛ [دليل ADB](../adb-device-analysis.md) |
| مشاريع JEB | وحدات المشروع من المحرك وبصمات المصنّفات والكود الزائف للأنواع/الدوال | عميل JEB يبدأه المُستدعي ويقدّم MCP، ويُختار عبر REA_JEB_MCP_URL؛ [دليل JEB](../jeb-analysis.md) |
@@ -265,6 +267,8 @@ npx rea-agents@latest setup
- [التثبيت والإعداد](../installation.md): تسجيل الوكلاء، وتهيئة الموفّرين، والتحديثات، وإلغاء التثبيت.
- [الجاهزية واستكشاف الأخطاء](../installation.md#check-readiness-for-your-task): تشخيص وكيل أو محرك تحليل محدد.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI وEvidence](../cli.md): الأوامر، واختيار الموفّر، واللقطات، والاستيراد/التصدير، وحالات الخروج.
- [عقود MCP](../mcp-contracts.md) و[تعليمات الوكلاء](../mcp-prompts.md): نتائج الأدوات، والجلسات، والاستقصاءات الموجّهة.
- [كتالوج الأدوات](../mcp-contracts.md#generated-catalog): قائمة الأدوات والموفّرين وأوامر CLI المولّدة أثناء البناء.
+4
View File
@@ -146,11 +146,13 @@ REA benötigt Node.js 22.x (>=22.19), 24.x (>=24.11) oder 26+ sowie npm. Zusätz
| 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](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Aufgezeichnete Linux-Abstürze | Unverarbeitete Note-Einträge, Register/Signale aller aufgezeichneten Threads und optionale Zuordnungskandidaten | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; optional GDB/pwndbg; [aufgezeichnete Abstürze](../recorded-crashes.md) |
| Desktop-Installationen | Laufzeitkandidaten, Quelldateien, Komponenten und nächste Schritte | Begrenzte Verzeichnis- und Headerprüfung;[Desktop-Anwendungen](../desktop-applications.md) |
| JavaScript / Electron | Module, Imports, Source Maps, Routen, IPC und Beziehungen zu nativen Add-ons | Node.js und npm; [Anwendungsanalyse](../javascript-application-workflows.md) |
| Websites | Seitenstruktur, Skripte, Netzwerkbeobachtungen und angeforderte Screenshots | Ein Browser aus der Chrome-Familie; [Browseranalyse](../browser-observation.md) |
| Gespeicherte Netzwerkaufzeichnungen | Anfragen, Antworten, zugängliche Nutzdaten und Quellpositionen | HAR; mitmdump unter Linux für Aufzeichnungen im nativen mitmproxy-Format; [Leitfaden zu Netzwerkaufzeichnungen](../web-network-captures.md) |
| Paketerfassungen | Endpunkte, DNS, TLS SNI, Protokollverteilung und HTTP-Anfragen | Vom Aufrufer bereitgestellte tshark- und capinfos-Binaries; [pcap-Leitfaden](../pcap-analysis.md) |
| .NET-Assemblies | Metadaten, CIL-Anweisungen, deklarierte native Abhängigkeiten und Build-Vergleiche | Statische Untersuchung; [Leitfaden für verwalteten Code](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.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](../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](../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](../jeb-analysis.md) |
@@ -263,6 +265,8 @@ Beginne mit den [praxisnahen Anleitungen](https://rea.tools/de/guides/) auf der
- [Installation und Einrichtung](../installation.md): Agentenregistrierung, Provider-Konfiguration, Updates und Deinstallation.
- [Bereitschaft und Fehlerbehebung](../installation.md#check-readiness-for-your-task): Diagnose eines bestimmten Agenten oder einer Analyse-Engine.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI und Evidence](../cli.md): Befehle, Provider-Auswahl, Snapshots, Import/Export und Exit-Status.
- [MCP-Kontrakte](../mcp-contracts.md) und [Agenten-Prompts](../mcp-prompts.md): Werkzeugergebnisse, Sitzungen und geführte Untersuchungen.
- [Werkzeugkatalog](../mcp-contracts.md#generated-catalog): Beim Build erzeugtes Inventar von Werkzeugen, Providern und CLI-Befehlen.
+4
View File
@@ -153,10 +153,12 @@ npx rea-agents@latest setup
| Bytecode EVM | Selectors επιλογής συνάρτησης, μετατοπίσεις σε bytes, εκτιμώμενα ορίσματα και δυνατότητα μεταβολής της κατάστασης | Τοπική είσοδος σε ακατέργαστα bytes ή δεκαεξαδική μορφή σε Linux x64· [οδηγός EVM χωρίς εκτέλεση](../evm-bytecode.md) |
| Βάσεις δεδομένων SQLite | Πίνακες, στήλες, ευρετήρια, όψεις, triggers και επιλεγμένες γραμμές κανονικών πινάκων | Τοπικό στιγμιότυπο βάσης δεδομένων/WAL· Node.js 24.x >=24.15 ή 26+ με εγγενή όρια SQLite |
| Καταγεγραμμένες καταρρεύσεις στο Linux | Ακατέργαστες εγγραφές notes, καταχωρητές/σήματα κάθε καταγεγραμμένου νήματος και προαιρετικές πιθανές αντιστοιχίσεις μνήμης | pwntools που παρέχει ο χρήστης σε Linux x64· προαιρετικά GDB/pwndbg· [καταγεγραμμένες καταρρεύσεις](../recorded-crashes.md) |
| Εγκαταστάσεις επιφάνειας εργασίας | Υποψήφια περιβάλλοντα εκτέλεσης, αρχεία τεκμηρίωσης, στοιχεία και επόμενα βήματα | Περιορισμένη επιθεώρηση καταλόγων και κεφαλίδων;[Εφαρμογές επιφάνειας εργασίας](../desktop-applications.md) |
| JavaScript / Electron | Modules, εισαγωγές, source maps, διαδρομές, IPC και σχέσεις με πρόσθετα κώδικα μηχανής | Node.js και npm· [ανάλυση εφαρμογών](../javascript-application-workflows.md) |
| Ιστότοποι | Δομή σελίδων, scripts, παρατηρήσεις δικτύου και ζητούμενα στιγμιότυπα οθόνης | Πρόγραμμα περιήγησης της οικογένειας Chrome· [ανάλυση μέσω προγράμματος περιήγησης](../browser-observation.md) |
| Αποθηκευμένες καταγραφές δικτύου | Αιτήματα, αποκρίσεις, διαθέσιμα δεδομένα φορτίου και θέσεις στην πηγή | HAR ή SAZ του Fiddler Everywhere· mitmdump σε Linux για την εγγενή μορφή mitmproxy· [οδηγός καταγραφών](../web-network-captures.md) |
| Assemblies .NET | Μεταδεδομένα, εντολές CIL, δηλωμένες εξαρτήσεις από κώδικα μηχανής και συγκρίσεις builds | Καμία πρόσθετη απαίτηση (μόνο στατική ανάλυση)· [οδηγός διαχειριζόμενου κώδικα](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| APK Android | Δηλώσεις manifest, κλάσεις, απομεταγλωττισμένες μέθοδοι και αναφορές | JADX χωρίς γραφικό περιβάλλον και πλήρες JDK σε Linux/macOS/Windows x64· [οδηγός Android](../android-analysis.md) |
| Συσκευές Android | Συσκευές, πακέτα, διεργασίες, logs, dumps, στιγμιότυπα οθόνης και μεταφορές APK/αρχείων | adb που παρέχει ο χρήστης (εξομοιωτής ή φυσική συσκευή)· [οδηγός ADB](../adb-device-analysis.md) |
| Έργα JEB | Μονάδες έργου από τη μηχανή ανάλυσης, ψηφιακά αποτυπώματα αρχείων και ψευδοκώδικα τύπων/μεθόδων | Client JEB που έχει ξεκινήσει ο χρήστης και παρέχει MCP, επιλεγμένος μέσω REA_JEB_MCP_URL· [οδηγός JEB](../jeb-analysis.md) |
@@ -276,6 +278,8 @@ npx rea-agents@latest setup
- [Εγκατάσταση και ρύθμιση](../installation.md): καταχώριση agents, ρύθμιση παρόχων ανάλυσης, ενημερώσεις και απεγκατάσταση.
- [Έλεγχος ετοιμότητας και αντιμετώπιση προβλημάτων](../installation.md#check-readiness-for-your-task): διάγνωση ενός agent ή μιας μηχανής ανάλυσης.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI και Evidence](../cli.md): εντολές, επιλογή παρόχου, στιγμιότυπα, εισαγωγή/εξαγωγή και κωδικοί εξόδου.
- [Προδιαγραφές MCP](../mcp-contracts.md) και [prompts για agents](../mcp-prompts.md): αποτελέσματα εργαλείων, συνεδρίες και καθοδηγούμενες διερευνήσεις.
- [Κατάλογος εργαλείων](../mcp-contracts.md#generated-catalog): αυτόματα παραγόμενος κατάλογος εργαλείων, παρόχων και εντολών CLI.
+4
View File
@@ -146,11 +146,13 @@ REA requiere Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, además de npm. Las h
| 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](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Fallos de Linux registrados | Registros note sin procesar, registros/señales de cada hilo registrado y posibles correspondencias de memoria opcionales | pwntools proporcionado por quien llama, en Linux x64; GDB/pwndbg opcionales; [fallos registrados](../recorded-crashes.md) |
| Instalaciones de escritorio | Posibles entornos de ejecución, archivos de evidencia, componentes y siguientes pasos | Inspección acotada de directorios y cabeceras;[Aplicaciones de escritorio](../desktop-applications.md) |
| JavaScript / Electron | Módulos, importaciones, mapas de código fuente, rutas, IPC y relaciones con complementos nativos | Node.js y npm; [análisis de aplicaciones](../javascript-application-workflows.md) |
| Sitios web | Estructura de la página, scripts, observaciones de red y capturas de pantalla solicitadas | Un navegador de la familia Chrome; [análisis del navegador](../browser-observation.md) |
| Capturas de red guardadas | Solicitudes, respuestas, contenido accesible de las cargas útiles y ubicaciones de origen | HAR; mitmdump en Linux para capturas en formato nativo de mitmproxy; [guía de capturas](../web-network-captures.md) |
| Capturas de paquetes | Endpoints, DNS, TLS SNI, distribución de protocolos y solicitudes HTTP | tshark y capinfos suministrados por el autor de la llamada; [guía pcap](../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](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.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](../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](../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](../jeb-analysis.md) |
@@ -263,6 +265,8 @@ Empieza con las [guías prácticas](https://rea.tools/es/guides/) del sitio web.
- [Instalación y configuración](../installation.md): registro de agentes, configuración de proveedores, actualizaciones y desinstalación.
- [Preparación y resolución de problemas](../installation.md#check-readiness-for-your-task): diagnóstico de un agente o motor de análisis concreto.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI y Evidence](../cli.md): comandos, selección de proveedores, instantáneas, importación/exportación y estados de salida.
- [Contratos de MCP](../mcp-contracts.md) y [prompts para agentes](../mcp-prompts.md): resultados de herramientas, sesiones e investigaciones guiadas.
- [Catálogo de herramientas](../mcp-contracts.md#generated-catalog): inventario de herramientas, proveedores y comandos de CLI generado durante la compilación.
+4
View File
@@ -138,10 +138,12 @@ REA به Node.js 22.x (>=22.19)، 24.x (>=24.11) یا 26+، به‌همراه np
| بایت‌کد EVM | selectorهای dispatch، offsetهای بایتی، آرگومان‌های استنباط‌شده و قابلیت تغییر وضعیت | دادهٔ خام/hex محلی روی Linux x64؛ [راهنمای EVM آفلاین](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| کرش‌های ثبت‌شدهٔ لینوکس | یادداشت‌های خام، رجیسترها/سیگنال‌های تمام threadهای ثبت‌شده و گزینه‌های احتمالی نگاشت | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ GDB/pwndbg اختیاری؛ [کرش‌های ثبت‌شده](../recorded-crashes.md) |
| نصب‌های دسکتاپ | نامزدهای زمان اجرا، فایل‌های شاهد، نشانه‌های مؤلفه‌ها و مراحل بعدی | بررسی محدود پوشه‌ها و سرآیندها;[برنامه‌های دسکتاپ](../desktop-applications.md) |
| JavaScript / Electron | ماژول‌ها، importها، source mapها، مسیرها، IPC و ارتباط افزونه‌های بومی | Node.js و npm؛ [تحلیل برنامه](../javascript-application-workflows.md) |
| وب‌سایت‌ها | ساختار صفحه، اسکریپت‌ها، مشاهدات شبکه و اسکرین‌شات‌های درخواستی | مرورگر مبتنی بر Chrome؛ [تحلیل مرورگر](../browser-observation.md) |
| داده‌های ضبط‌شدهٔ شبکه | درخواست‌ها، پاسخ‌ها، payloadهای آشکارشده و مکان آن‌ها در منبع | HAR؛ ابزار mitmdump در لینوکس برای ضبط‌های بومی mitmproxy؛ [راهنمای ضبط شبکه](../web-network-captures.md) |
| اسمبلی‌های .NET | فراداده، دستورالعمل‌های CIL، وابستگی‌های بومی اعلام‌شده و مقایسهٔ buildها | بررسی ایستا؛ [راهنمای کد مدیریت‌شده](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| فایل‌های APK اندروید | تعاریف Manifest، کلاس‌ها، متدهای دیکامپایل‌شده و ارجاعات | JADX بدون رابط گرافیکی و JDK کامل در Linux/macOS/Windows x64؛ [راهنمای اندروید](../android-analysis.md) |
| دستگاه‌های اندروید | دستگاه‌ها، بسته‌ها، فرایندها، لاگ‌ها، دامپ‌ها، اسکرین‌شات‌ها و انتقال APK/فایل | adb تأمین‌شده توسط فراخوان‌کننده (شبیه‌ساز یا دستگاه)؛ [راهنمای ADB](../adb-device-analysis.md) |
| پروژه‌های JEB | واحدهای پروژه از موتور، هش‌های مصنوع و شبه‌کدِ نوع/متد | یک کلاینت JEB که توسط فراخوان‌کننده اجرا شده و MCP ارائه می‌دهد و با REA_JEB_MCP_URL انتخاب می‌شود؛ [راهنمای JEB](../jeb-analysis.md) |
@@ -248,6 +250,8 @@ npx rea-agents@latest setup
- [نصب و راه‌اندازی](../installation.md): ثبت ایجنت، پیکربندی ارائه‌دهنده، به‌روزرسانی و حذف نصب.
- [آمادگی و رفع اشکال](../installation.md#check-readiness-for-your-task): عیب‌یابی یک ایجنت یا موتور تحلیل.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI و شواهد](../cli.md): دستورات، انتخاب ارائه‌دهنده، snapshotها، ورود/خروج داده و وضعیت‌های خروج.
- [قراردادهای MCP](../mcp-contracts.md) و [پرامپت‌های ایجنت](../mcp-prompts.md): نتایج ابزارها، نشست‌ها و بررسی‌های هدایت‌شده.
- [فهرست ابزارها](../mcp-contracts.md#generated-catalog): فهرست تولیدشده هنگام build از ابزارها، ارائه‌دهندگان و دستورات CLI.
+4
View File
@@ -150,11 +150,13 @@ REA nécessite Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, ainsi que npm. Les
| 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](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Crashs Linux enregistrés | Notes brutes, registres et signaux de chaque thread enregistré, et correspondances de mappings facultatives | pwntools fourni par l'utilisateur sous Linux x64 ; GDB/pwndbg en option ; [crashs enregistrés](../recorded-crashes.md) |
| Installations de bureau | Environnements candidats, fichiers justificatifs, composants et étapes suivantes | Inspection bornée des répertoires et en-têtes;[Applications de bureau](../desktop-applications.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC et relations avec les modules natifs | Node.js et npm ; [analyse d'applications](../javascript-application-workflows.md) |
| Sites web | Structure des pages, scripts, observations réseau et captures d'écran demandées | Un navigateur de la famille Chrome ; [analyse du navigateur](../browser-observation.md) |
| Captures réseau enregistrées | Requêtes, réponses, payloads exposés et emplacements dans le code source | HAR ; mitmdump sous Linux pour les captures mitmproxy natives ; [guide des captures](../web-network-captures.md) |
| Captures de paquets | Points de terminaison, DNS, TLS SNI, distribution des protocoles et requêtes HTTP | tshark et capinfos fournis par l'appelant ; [guide pcap](../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é](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.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](../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](../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](../jeb-analysis.md) |
@@ -267,6 +269,8 @@ Commencez par les [guides pas à pas](https://rea.tools/fr/guides/) du site web.
- [Installation et configuration](../installation.md) : enregistrement des agents, configuration des fournisseurs, mises à jour et désinstallation.
- [Vérification et dépannage](../installation.md#check-readiness-for-your-task) : diagnostiquer un agent ou un moteur d'analyse donné.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI et Evidence](../cli.md) : commandes, choix du fournisseur, snapshots, import/export et codes de sortie.
- [Contrats MCP](../mcp-contracts.md) et [prompts pour agents](../mcp-prompts.md) : résultats des outils, sessions et investigations guidées.
- [Catalogue des outils](../mcp-contracts.md#generated-catalog) : inventaire des outils, fournisseurs et commandes CLI, généré lors du build.
+4
View File
@@ -153,11 +153,13 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal; [panduan EVM offline](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Crash Linux yang direkam | Catatan mentah, register/sinyal setiap thread yang direkam, dan kandidat pemetaan opsional | pwntools yang disediakan pemanggil; GDB/pwndbg opsional; [crash yang direkam](../recorded-crashes.md) |
| Instalasi desktop | Kandidat runtime, berkas pendukung, penanda komponen, dan langkah berikutnya | Pemeriksaan direktori dan header terbatas;[Aplikasi desktop](../desktop-applications.md) |
| JavaScript / Electron | Modul, impor, source map, rute, IPC, dan hubungan add-on native | Node.js dan npm; [analisis aplikasi](../javascript-application-workflows.md) |
| Situs web | Struktur halaman, skrip, pengamatan jaringan, dan tangkapan layar yang diminta | Peramban berbasis Chrome; [analisis peramban](../browser-observation.md) |
| Rekaman jaringan tersimpan | Permintaan, respons, payload yang terekspos, dan lokasi sumber | HAR; mitmdump di Linux untuk rekaman native mitmproxy; [panduan rekaman](../web-network-captures.md) |
| Capturan paket | Endpoint, DNS, TLS SNI, distribusi protokol, dan permintaan HTTP | tshark dan capinfos buatan pemanggil; [panduan pcap](../pcap-analysis.md) |
| Assembly .NET | Metadata, instruksi CIL, dependensi native yang dideklarasikan, dan perbandingan build | Tidak ada (hanya analisis statis); [panduan kode terkelola](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| APK Android | Deklarasi manifest, kelas, metode hasil dekompilasi, dan referensi | JADX mode headless dan JDK lengkap di Linux/macOS/Windows x64; [panduan 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](../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](../jeb-analysis.md) |
@@ -288,6 +290,8 @@ Untuk mengetahui opsi, prasyarat, dan kontrak hasil secara tepat:
- [Instalasi dan penyiapan](../installation.md): pendaftaran agen, konfigurasi penyedia, pembaruan, dan penghapusan instalasi.
- [Kesiapan dan pemecahan masalah](../installation.md#check-readiness-for-your-task): mendiagnosis satu agen atau mesin analisis.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI dan Bukti](../cli.md): perintah, pemilihan penyedia, snapshot, impor/ekspor, dan status keluar.
- [Kontrak MCP](../mcp-contracts.md) dan [prompt agen](../mcp-prompts.md): hasil alat, sesi, dan investigasi terpandu.
- [Katalog alat](../mcp-contracts.md#generated-catalog): inventaris alat, penyedia, dan perintah CLI yang dibuat secara otomatis.
+4
View File
@@ -150,11 +150,13 @@ REA richiede Node.js 22.x (>=22.19), 24.x (>=24.11) o 26+, oltre a npm. Strument
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale; [guida EVM offline](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Crash Linux registrati | Note grezze, registri/segnai di ogni thread registrato e candidati mapping opzionali | pwntools fornito dal chiamante; GDB/pwndbg opzionale; [crash registrati](../recorded-crashes.md) |
| Installazioni desktop | Runtime candidati, file di supporto, componenti e passi successivi | Ispezione limitata di directory e intestazioni;[Applicazioni desktop](../desktop-applications.md) |
| JavaScript / Electron | Moduli, import, source map, route, IPC e relazioni con add-on nativi | Node.js e npm; [analisi delle applicazioni](../javascript-application-workflows.md) |
| Siti web | Struttura della pagina, script, osservazioni di rete e screenshot richiesti | Un browser della famiglia Chrome; [analisi browser](../browser-observation.md) |
| Acquisizioni di rete salvate | Richieste, risposte, payload esposti e posizioni sorgente | HAR; mitmdump su Linux per acquisizioni mitmproxy native; [guida alle acquisizioni](../web-network-captures.md) |
| Captured di pacchetti | Endpoint, DNS, TLS SNI, distribuzione dei protocolli e richieste HTTP | tshark e capinfos forniti dal chiamante; [guida pcap](../pcap-analysis.md) |
| Assembly .NET | Metadati, istruzioni CIL, dipendenze native dichiarate e confronti di build | Nessuno (solo statico); [guida managed-code](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| APK Android | Dichiarazioni manifest, classi, metodi decompilati e riferimenti | JADX headless e un JDK completo su Linux/macOS/Windows x64; [guida 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](../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](../jeb-analysis.md) |
@@ -267,6 +269,8 @@ Inizia dalle [guide pratiche](https://rea.tools/it/guides/) del sito web. Per op
- [Installazione e configurazione](../installation.md): registrazione agente, configurazione provider, aggiornamenti e disinstallazione.
- [Pronto all'uso e risoluzione dei problemi](../installation.md#check-readiness-for-your-task): diagnostica un agente o un motore di analisi.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI ed Evidence](../cli.md): comandi, selezione provider, snapshot, import/export e stati di uscita.
- [Contratti MCP](../mcp-contracts.md) e [prompt agente](../mcp-prompts.md): risultati degli strumenti, sessioni e indagini guidate.
- [Catalogo strumenti](../mcp-contracts.md#generated-catalog): inventario generato di strumenti, provider e comandi CLI.
+4
View File
@@ -146,11 +146,13 @@ REA には Node.js 22.x(>=22.19)、24.x(>=24.11)、または 26+ と npm
| EVM バイトコード | ディスパッチセレクター、バイトオフセット、推定された引数と状態変更の可否 | Linux x64 上のローカルの生バイト/16 進数の入力ファイル;[オフライン EVM ガイド](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| 記録済みの Linux クラッシュ | 生の note レコード、記録された全スレッドのレジスター/シグナル、任意のマッピング候補 | Linux x64 で利用者が用意する pwntools;GDB/pwndbg は任意;[記録済みクラッシュ](../recorded-crashes.md) |
| デスクトップのインストール先 | ランタイム候補、根拠ファイル、コンポーネントの目印、次の調査手順 | 上限付きのディレクトリ・ヘッダー検査;[デスクトップアプリ](../desktop-applications.md) |
| JavaScript / Electron | モジュール、インポート、ソースマップ、ルート、IPC、ネイティブアドオンの関係 | Node.js と npm;[アプリケーション分析](../javascript-application-workflows.md) |
| ウェブサイト | ページ構造、スクリプト、ネットワークの観測結果、依頼されたスクリーンショット | Chrome 系ブラウザー;[ブラウザー分析](../browser-observation.md) |
| 保存済みのネットワークキャプチャ | リクエスト、レスポンス、取得可能なペイロード、ソース内の位置 | HAR;mitmproxy ネイティブ形式のキャプチャには Linux 上の mitmdump;[キャプチャガイド](../web-network-captures.md) |
| パケットキャプチャ | エンドポイント、DNS、TLS SNI、プロトコル分布、HTTPリクエスト | 呼び出し側が用意した tshark と capinfos;[pcapガイド](../pcap-analysis.md) |
| .NET アセンブリ | メタデータ、CIL 命令、宣言されたネイティブ依存関係、ビルドの比較 | 静的な検査;[マネージドコードのガイド](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| Android APK | マニフェストの宣言、クラス、逆コンパイルされたメソッド、参照 | Linux/macOS/Windows x64 上のヘッドレス JADX と完全な JDK;[Android ガイド](../android-analysis.md) |
| Android デバイス | デバイス、パッケージ、プロセス、ログ、ダンプ、スクリーンキャプチャ、APK/ファイル転送 | 呼び出し側が用意した adb(エミュレーターまたは実機);[ADB ガイド](../adb-device-analysis.md) |
| JEBプロジェクト | エンジンによるプロジェクトユニット、アーティファクトのダイジェスト、型/メソッドの擬似コード | 呼び出し側が起動し MCP を提供する JEB クライアント(REA_JEB_MCP_URL で選択);[JEB ガイド](../jeb-analysis.md) |
@@ -265,6 +267,8 @@ npx rea-agents@latest setup
- [インストールとセットアップ](../installation.md):エージェントの登録、プロバイダーの設定、更新、アンインストール。
- [準備状況の確認とトラブルシューティング](../installation.md#check-readiness-for-your-task):特定のエージェントや分析エンジンを診断。
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI と Evidence](../cli.md):コマンド、プロバイダーの選択、スナップショット、インポート/エクスポート、終了ステータス。
- [MCP 契約](../mcp-contracts.md)と[エージェント向けプロンプト](../mcp-prompts.md):ツールの結果、セッション、ガイド付き調査。
- [ツールカタログ](../mcp-contracts.md#generated-catalog):ビルド時に生成されるツール、プロバイダー、CLI コマンドの一覧。
+33 -25
View File
@@ -117,6 +117,10 @@ REA는 빠르게 바뀌며 새 릴리스에는 버그 수정이 자주 포함됩
rea update
```
`rea --update`는 이 검증된 업데이트 절차의 별칭이며 같은 전역 출력 플래그를 사용할 수 있습니다. 다른 명령 제어 옵션과 함께 사용할 때는 `rea update`를 사용하세요.
업데이트 명령은 stdout과 stderr를 합쳐 최대 4 MiB까지만 보관합니다. 한도를 넘긴 메타데이터 응답은 명령이 종료된 뒤 거부됩니다. 상세 출력을 사용하는 설치에서는 진단 정보를 한도 내에서만 보관하고 설치를 계속 진행합니다. 사람이 읽는 진행 출력은 터미널이 받아들이는 속도에 맞춰 전달되며, 이미 제출한 쓰기가 끝날 때까지 기다립니다.
Bun 전역 업데이트에는 Bun 1.2.17 이상이 필요합니다. 이전 버전의 Bun을 사용한다면 `rea update`를 실행하기 전에 Bun을 직접 업그레이드하세요.
에이전트 등록과 스킬을 갱신하려면 업데이트 과정에서 출력된 설정 명령을 실행하세요.
@@ -143,31 +147,33 @@ npx rea-agents@latest setup
REA에는 Node.js 22.x(>=22.19), 24.x(>=24.11) 또는 26+와 npm이 필요합니다. 추가 도구와 호스트 지원은 대상에 따라 다릅니다.
| 대상 | REA가 반환하는 내용 | 요구 사항 및 가이드 |
| --------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra 또는 IDA; [네이티브 분석](../native-investigation.md) |
| 오프라인 ELF 레이아웃 | 섹션, 세그먼트, 원본 심볼/재배치 정보, 정적 분석으로 얻은 보안 완화 기법 후보 | Linux x64에서 호출자가 제공하는 pwntools; [바이너리 진단](../binary-diagnostics.md) |
| Go 바이너리 | 내장된 컴파일러 버전, 모듈, `replace` 지시어, 빌드 설정 | REA 내장 ELF/PE/thin Mach-O 정적 검사; Go 설치 불필요 |
| Rust 바이너리 | cargo-auditable이 내장한 크레이트 이름, 버전, 소스, 의존성 관계 | REA 내장 ELF/PE/thin Mach-O 정적 검사; [Rust 바이너리](../rust-binaries.md) |
| WASM 아티팩트 | 유효성 검사, 섹션, import/export의 정확한 WAT 형식, 디코딩된 WAT | 호출자 제공 WABT 1.0.42; `inspect_wasm_artifact` |
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | Linux x64의 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](../evm-bytecode.md) |
| SQLite 데이터베이스 | 테이블, 열, 인덱스, 뷰, 트리거, 선택한 일반 테이블의 행 | 로컬 데이터베이스/WAL 스냅샷; Node.js 24.15 이상의 24.x 또는 26 이상(네이티브 SQLite 한도 적용) |
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | Linux x64에서 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; [기록된 크래시](../recorded-crashes.md) |
| JavaScript / Electron | 모듈, 임포트, 소스 맵, 라우트, IPC, 네이티브 애드온 관계 | Node.js와 npm; Linux: procps 호환 `ps`; [애플리케이션 분석](../javascript-application-workflows.md) |
| 웹사이트 | 페이지 구조, 스크립트, 네트워크 관찰 결과, 요청한 스크린샷 | Chrome 계열 브라우저; [브라우저 분석](../browser-observation.md) |
| 저장된 네트워크 캡처 | 요청, 응답, 접근 가능한 페이로드, 소스 위치 | HAR 또는 Fiddler Everywhere SAZ; mitmproxy 네이티브 캡처에는 Linux의 mitmdump; [캡처 가이드](../web-network-captures.md) |
| .NET 어셈블리 | 메타데이터, CIL 명령, 선언된 네이티브 의존성, 빌드 비교 | 별도 도구 불필요(정적 검사만); [관리 코드 가이드](../managed-code-analysis.md) |
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS/Windows x64의 헤드리스 JADX와 전체 JDK; [Android 가이드](../android-analysis.md) |
| Android 기기 | 기기, 패키지, 프로세스, 로그, 덤프, 화면 캡처, APK/파일 전송 | 호출자 제공 adb(에뮬레이터 또는 실제 기기); [ADB 가이드](../adb-device-analysis.md) |
| JEB 프로젝트 | 엔진 기반 프로젝트 유닛, 아티팩트 해시, 타입/메서드 의사코드 | 호출자가 시작하고 MCP를 제공하는 JEB 클라이언트(REA_JEB_MCP_URL로 선택); [JEB 가이드](../jeb-analysis.md) |
| Android 리소스 | 디코딩된 매니페스트, 문자열 테이블, 로캘, 버전 정보 | 호출자 제공 Apktool 런처; [리소스 가이드](../apktool-resource-analysis.md) |
| Flutter 앱 | Dart 스냅샷 해시, ABI별 라이브러리 해시, 엔진 빌드 출처 | 없음 (정적 APK 파싱); [Flutter 가이드](../flutter-analysis.md) |
| 펌웨어 | 영역, 추출 결과, 네이티브 분석으로 전달할 정보 | Linux의 Binwalk / Unblob; [펌웨어 가이드](../firmware-analysis.md) |
| 기록된 패킷 | 선택 필드, 반복 값, 필터 및 디코딩 규칙 | Linux: TShark 4.x + prlimit; [캡처 가이드](../packet-captures.md) |
| 패킷 요약 | 엔드포인트, DNS, TLS SNI, 프로토콜 분포, HTTP 요청 | 호출자 제공 tshark 및 capinfos(Linux에서 검증됨); [pcap 가이드](../pcap-analysis.md) |
| 기록된 논리 신호 | 디코더 주석, 샘플 범위, 진단 정보 | Linux: sigrok-cli 0.7.2 + prlimit; [신호 기록 가이드](../signal-recordings.md) |
| 패키지 및 리소스 | 파일 목록, 다이제스트, plist, Apple 번들 구조, 추출한 리소스 | [아티팩트 및 JavaScript 가이드](../javascript-artifact-reconstruction.md), [Apple 애플리케이션](../apple-application-analysis.md) |
| 프로세스 동작 | 터미널 출력, 상호작용, 종료 및 파일 시스템 관찰 결과, 실행 비교 | 네이티브 PTY를 지원하는 Linux/macOS; [프로세스 캡처](../process-capture.md) |
| 대상 | REA가 반환하는 내용 | 요구 사항 및 가이드 |
| ---------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra 또는 IDA; [네이티브 분석](../native-investigation.md) |
| 오프라인 ELF 레이아웃 | 섹션, 세그먼트, 원본 심볼/재배치 정보, 정적 분석으로 얻은 보안 완화 기법 후보 | Linux x64에서 호출자가 제공하는 pwntools; [바이너리 진단](../binary-diagnostics.md) |
| Go 바이너리 | 내장된 컴파일러 버전, 모듈, `replace` 지시어, 빌드 설정 | REA 내장 ELF/PE/thin Mach-O 정적 검사; Go 설치 불필요 |
| Rust 바이너리 | cargo-auditable이 내장한 크레이트 이름, 버전, 소스, 의존성 관계 | REA 내장 ELF/PE/thin Mach-O 정적 검사; [Rust 바이너리](../rust-binaries.md) |
| WASM 아티팩트 | 유효성 검사, 섹션, import/export의 정확한 WAT 형식, 디코딩된 WAT | 호출자 제공 WABT 1.0.42; `inspect_wasm_artifact` |
| EVM 바이트코드 | 디스패치 선택자, 바이트 오프셋, 추론한 인자와 상태 변경 가능 여부 | Linux x64의 로컬 원시 바이트/16진수 입력 파일; [오프라인 EVM 가이드](../evm-bytecode.md) |
| SQLite 데이터베이스 | 테이블, 열, 인덱스, 뷰, 트리거, 선택한 일반 테이블의 행 | 로컬 데이터베이스/WAL 스냅샷; Node.js 24.15 이상의 24.x 또는 26 이상(네이티브 SQLite 한도 적용) |
| 기록된 Linux 크래시 | 원시 note 레코드, 기록된 모든 스레드의 레지스터/시그널, 선택적 매핑 후보 | Linux x64에서 호출자가 제공하는 pwntools; GDB/pwndbg는 선택 사항; [기록된 크래시](../recorded-crashes.md) |
| 데스크톱 설치 디렉터리 | 런타임 후보, 근거 파일, 구성 요소 표시와 다음 조사 단계 | 범위가 제한된 디렉터리 및 헤더 검사;[데스크톱 애플리케이션](../desktop-applications.md) |
| JavaScript / Electron | 모듈, 임포트, 소스 맵, 라우트, IPC, 네이티브 애드온 관계 | Node.js와 npm; Linux: procps 호환 `ps`; [애플리케이션 분석](../javascript-application-workflows.md) |
| 웹사이트 | 페이지 구조, 스크립트, 네트워크 관찰 결과, 요청한 스크린샷 | Chrome 계열 브라우저; [브라우저 분석](../browser-observation.md) |
| 저장된 네트워크 캡처 | 요청, 응답, 접근 가능한 페이로드, 소스 위치 | HAR 또는 Fiddler Everywhere SAZ; mitmproxy 네이티브 캡처에는 Linux의 mitmdump; [캡처 가이드](../web-network-captures.md) |
| .NET 어셈블리 | 메타데이터, CIL 명령, 선언된 네이티브 의존성, 빌드 비교 | 별도 도구 불필요(정적 검사만); [관리 코드 가이드](../managed-code-analysis.md) |
| Android APK | 매니페스트 선언, 클래스, 디컴파일된 메서드, 참조 | Linux/macOS/Windows x64의 헤드리스 JADX와 전체 JDK; [Android 가이드](../android-analysis.md) |
| Android 기기 | 기기, 패키지, 프로세스, 로그, 덤프, 화면 캡처, APK/파일 전송 | 호출자 제공 adb(에뮬레이터 또는 실제 기기); [ADB 가이드](../adb-device-analysis.md) |
| JEB 프로젝트 | 엔진 기반 프로젝트 유닛, 아티팩트 해시, 타입/메서드 의사코드 | 호출자가 시작하고 MCP를 제공하는 JEB 클라이언트(REA_JEB_MCP_URL로 선택); [JEB 가이드](../jeb-analysis.md) |
| Android 리소스 | 디코딩된 매니페스트, 문자열 테이블, 로캘, 버전 정보 | 호출자 제공 Apktool 런처; [리소스 가이드](../apktool-resource-analysis.md) |
| Flutter 앱 | Dart 스냅샷 해시, ABI별 라이브러리 해시, 엔진 빌드 출처 | 없음 (정적 APK 파싱); [Flutter 가이드](../flutter-analysis.md) |
| 펌웨어 | 영역, 추출 결과, 네이티브 분석으로 전달할 정보 | Linux의 Binwalk / Unblob; [펌웨어 가이드](../firmware-analysis.md) |
| 기록된 패킷 | 선택 필드, 반복 값, 필터 및 디코딩 규칙 | Linux: TShark 4.x + prlimit; [캡처 가이드](../packet-captures.md) |
| 패킷 요약 | 엔드포인트, DNS, TLS SNI, 프로토콜 분포, HTTP 요청 | 호출자 제공 tshark 및 capinfos(Linux에서 검증됨); [pcap 가이드](../pcap-analysis.md) |
| 기록된 논리 신호 | 디코더 주석, 샘플 범위, 진단 정보 | Linux: sigrok-cli 0.7.2 + prlimit; [신호 기록 가이드](../signal-recordings.md) |
| 패키지 및 리소스 | 파일 목록, 다이제스트, plist, Apple 번들 구조, 추출한 리소스 | [아티팩트 및 JavaScript 가이드](../javascript-artifact-reconstruction.md), [Apple 애플리케이션](../apple-application-analysis.md) |
| 프로세스 동작 | 터미널 출력, 상호작용, 종료 및 파일 시스템 관찰 결과, 실행 비교 | 네이티브 PTY를 지원하는 Linux/macOS; [프로세스 캡처](../process-capture.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
정적 JavaScript 및 .NET 검사는 제공된 파일을 읽으며 애플리케이션을 실행하지 않습니다. 런타임 캡처는 사용자의 권한으로 선택한 대상을 실행하거나 대상과 상호작용합니다. 각 런타임 가이드에서 그 영향을 설명합니다.
@@ -274,6 +280,8 @@ npx rea-agents@latest setup
- [설치 및 설정](../installation.md): 에이전트 등록, 제공자 설정, 업데이트, 제거.
- [준비 상태 확인 및 문제 해결](../installation.md#check-readiness-for-your-task): 특정 에이전트 또는 분석 엔진 진단.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI 및 Evidence](../cli.md): 명령, 제공자 선택, 스냅샷, 가져오기/내보내기, 종료 상태.
- [MCP 계약](../mcp-contracts.md) 및 [에이전트 프롬프트](../mcp-prompts.md): 도구 결과, 세션, 안내에 따른 조사.
- [도구 카탈로그](../mcp-contracts.md#generated-catalog): 빌드 시 생성되는 도구, 제공자, CLI 명령 목록.
+4
View File
@@ -155,10 +155,12 @@ REA-യ്ക്ക് Node.js 22.x (>=22.19), 24.x (>=24.11), അല്ലെ
| EVM bytecode | Dispatch selectors, byte offsets, അനുമാനിച്ച arguments, mutability | Linux x64-ൽ local raw/hex carrier; [offline EVM guide](../evm-bytecode.md) |
| SQLite databases | Tables, columns, indexes, views, triggers, തിരഞ്ഞെടുത്ത സാധാരണ table rows | Local database/WAL snapshot; native SQLite പരിമിതികളോടെ Node.js 24.x >=24.15 അല്ലെങ്കിൽ 26+ |
| Recorded Linux crashes | Raw notes, രേഖപ്പെടുത്തിയ ഓരോ thread-ന്റെയും registers/signals, ഐച്ഛിക mapping candidates | Linux x64-ൽ caller നൽകുന്ന pwntools; ഐച്ഛിക GDB/pwndbg; [recorded crashes](../recorded-crashes.md) |
| ഡെസ്ക്ടോപ്പ് ഇൻസ്റ്റലേഷനുകൾ | റൺടൈം സാധ്യതകൾ, തെളിവ് ഫയലുകൾ, ഘടക സൂചനകൾ, തുടർ നടപടികൾ | പരിധിയുള്ള ഡയറക്ടറി, ഹെഡർ പരിശോധന;[ഡെസ്ക്ടോപ്പ് ആപ്ലിക്കേഷനുകൾ](../desktop-applications.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC, native add-on ബന്ധങ്ങൾ | Node.js, npm; Linux: procps-compatible `ps`; [application analysis](../javascript-application-workflows.md) |
| Websites | Page structure, scripts, network observations, ആവശ്യപ്പെട്ട screenshots | Chrome-family browser; [browser analysis](../browser-observation.md) |
| Saved network captures | Requests, responses, പുറത്തുകാണുന്ന payload-ുകൾ, source locations | HAR അല്ലെങ്കിൽ Fiddler Everywhere SAZ; native mitmproxy-നായി Linux-ൽ mitmdump; [capture guide](../web-network-captures.md) |
| .NET assemblies | Metadata, CIL instructions, പ്രഖ്യാപിച്ച native dependencies, build comparisons | ഒന്നും ആവശ്യമില്ല (static മാത്രം); [managed-code guide](../managed-code-analysis.md) |
| Python packaged apps | CArchive/PYZ entries, Python version, bytecode, resources and runtime options | Static PyInstaller parsing; [Python guide](../python-packaged-applications.md) |
| Android APKs | Manifest declarations, classes, decompiled methods, references | Linux/macOS/Windows x64-ൽ Headless JADX-ഉം full JDK-ഉം; [Android guide](../android-analysis.md) |
| Android devices | Devices, packages, processes, logs, dumps, screen captures, APK/file transfers | Caller നൽകുന്ന adb (emulator അല്ലെങ്കിൽ hardware); [ADB guide](../adb-device-analysis.md) |
| JEB projects | Engine-backed project units, artifact digests, type/method pseudo-code | MCP സേവനം നൽകുന്ന caller ആരംഭിച്ച JEB client; REA_JEB_MCP_URL ഉപയോഗിച്ച് തിരഞ്ഞെടുക്കുക; [JEB guide](../jeb-analysis.md) |
@@ -281,6 +283,8 @@ npx rea-agents@latest setup
- [Installation and setup](../installation.md): agent registration, provider configuration, updates, uninstall.
- [Readiness and troubleshooting](../installation.md#check-readiness-for-your-task): ഒരു agent-ന്റെയോ analysis engine-ന്റെയോ പ്രശ്നങ്ങൾ കണ്ടെത്തുക.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI and Evidence](../cli.md): commands, provider തിരഞ്ഞെടുക്കൽ, snapshots, import/export, exit statuses.
- [MCP contracts](../mcp-contracts.md), [agent prompts](../mcp-prompts.md): tool results, sessions, guided investigations.
- [Tool catalog](../mcp-contracts.md#generated-catalog): tools, providers, CLI commands എന്നിവയുടെ സ്വയമേവ സൃഷ്ടിച്ച പട്ടിക.
+4
View File
@@ -146,11 +146,13 @@ REA wymaga Node.js 22.x (>=22.19), 24.x (>=24.11) lub 26+ oraz npm. Dodatkowe na
| 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](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Zarejestrowane awarie systemu Linux | Surowe rekordy note, rejestry/sygnały każdego zarejestrowanego wątku i opcjonalni kandydaci na mapowania | pwntools dostarczone przez użytkownika w systemie Linux x64; opcjonalnie GDB/pwndbg; [zarejestrowane awarie](../recorded-crashes.md) |
| Instalacje desktopowe | Kandydaci środowisk uruchomieniowych, pliki źródłowe dowodów, komponenty i dalsze kroki | Ograniczona inspekcja katalogów i nagłówków;[Aplikacje desktopowe](../desktop-applications.md) |
| JavaScript / Electron | Moduły, importy, mapy źródeł, trasy, IPC i powiązania z natywnymi dodatkami | Node.js i npm; [analiza aplikacji](../javascript-application-workflows.md) |
| Strony internetowe | Struktura strony, skrypty, obserwacje sieciowe i zamówione zrzuty ekranu | Przeglądarka z rodziny Chrome; [analiza w przeglądarce](../browser-observation.md) |
| Zapisane przechwycenia ruchu sieciowego | Żądania, odpowiedzi, dostępne dane przesyłane i lokalizacje źródłowe | HAR; mitmdump w systemie Linux dla natywnych przechwyceń mitmproxy; [przewodnik przechwytywania](../web-network-captures.md) |
| Przechwytywanie pakietów | Punkty końcowe, DNS, TLS SNI, dystrybucja protokołów i żądania HTTP | Dostarczone przez wywołującego tshark i capinfos; [przewodnik pcap](../pcap-analysis.md) |
| Zestawy .NET | Metadane, instrukcje CIL, zadeklarowane zależności natywne i porównania kompilacji | Analiza statyczna; [przewodnik kodu zarządzanego](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.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](../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](../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](../jeb-analysis.md) |
@@ -263,6 +265,8 @@ Zacznij od [przewodników z przykładami](https://rea.tools/pl/guides/) na stron
- [Instalacja i konfiguracja](../installation.md): rejestracja agentów, konfiguracja dostawców analizy, aktualizacje i odinstalowanie.
- [Gotowość i rozwiązywanie problemów](../installation.md#check-readiness-for-your-task): diagnostyka jednego agenta lub silnika analizy.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI i Evidence](../cli.md): polecenia, wybór dostawcy, migawki, import/eksport i kody zakończenia.
- [Kontrakty MCP](../mcp-contracts.md) i [prompty dla agentów](../mcp-prompts.md): wyniki narzędzi, sesje i prowadzone analizy.
- [Katalog narzędzi](../mcp-contracts.md#generated-catalog): generowany podczas kompilacji wykaz narzędzi, dostawców i poleceń CLI.
+4
View File
@@ -146,11 +146,13 @@ O REA requer Node.js 22.x (>=22.19), 24.x (>=24.11) ou 26+, além do npm. As fer
| 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](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Falhas do Linux registradas | Registros note brutos, registradores/sinais de cada thread registrada e candidatos opcionais a mapeamentos | pwntools fornecido pelo chamador no Linux x64; GDB/pwndbg opcionais; [falhas registradas](../recorded-crashes.md) |
| Instalações desktop | Ambientes candidatos, arquivos de evidência, componentes e próximos passos | Inspeção limitada de diretórios e cabeçalhos;[Aplicações desktop](../desktop-applications.md) |
| JavaScript / Electron | Módulos, importações, source maps, rotas, IPC e relações com complementos nativos | Node.js e npm; [análise de aplicativos](../javascript-application-workflows.md) |
| Sites | Estrutura da página, scripts, observações de rede e capturas de tela solicitadas | Um navegador da família Chrome; [análise do navegador](../browser-observation.md) |
| Capturas de rede salvas | Requisições, respostas, payloads acessíveis e localizações de origem | HAR; mitmdump no Linux para capturas no formato nativo do mitmproxy; [guia de capturas](../web-network-captures.md) |
| Capturas de pacotes | Endpoints, DNS, TLS SNI, distribuição de protocolos e requisições HTTP | tshark e capinfos fornecidos pelo chamador; [guia pcap](../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](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.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](../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](../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](../jeb-analysis.md) |
@@ -263,6 +265,8 @@ Comece pelos [guias práticos](https://rea.tools/pt-BR/guides/) do site. Para op
- [Instalação e configuração](../installation.md): registro de agentes, configuração de provedores, atualizações e desinstalação.
- [Prontidão e solução de problemas](../installation.md#check-readiness-for-your-task): diagnóstico de um agente ou motor de análise específico.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI e Evidence](../cli.md): comandos, seleção de provedores, snapshots, importação/exportação e status de saída.
- [Contratos MCP](../mcp-contracts.md) e [prompts para agentes](../mcp-prompts.md): resultados das ferramentas, sessões e investigações guiadas.
- [Catálogo de ferramentas](../mcp-contracts.md#generated-catalog): inventário de ferramentas, provedores e comandos da CLI gerado durante o build.
+26 -22
View File
@@ -139,28 +139,30 @@ npx rea-agents@latest setup
REA требует Node.js 22.x (>=22.19), 24.x (>=24.11) или 26+, а также npm. Дополнительные инструменты и поддерживаемые системы зависят от цели:
| Цель | Что возвращает REA | Требования и руководство |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](../native-investigation.md) |
| Структура ELF без запуска | Секции, сегменты, исходные символы/релокации и возможные механизмы защиты по данным статического анализа | pwntools, предоставленный вызывающей стороной, в Linux x64; [диагностика бинарных файлов](../binary-diagnostics.md) |
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](../recorded-crashes.md) |
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](../javascript-application-workflows.md) |
| Сайты | Структура страницы, скрипты, наблюдения за сетью и запрошенные снимки экрана | Браузер семейства Chrome; [анализ браузера](../browser-observation.md) |
| Сохранённые сетевые захваты | Запросы, ответы, доступные полезные данные и позиции в источнике | HAR; mitmdump в Linux для захватов в собственном формате mitmproxy; [руководство по сетевым захватам](../web-network-captures.md) |
| Сборки .NET | Метаданные, инструкции CIL, объявленные нативные зависимости и сравнения сборок | Статическое исследование; [руководство по управляемому коду](../managed-code-analysis.md) |
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS/Windows x64; [руководство по Android](../android-analysis.md) |
| Устройства Android | Устройства, пакеты, процессы, журналы, дампы, снимки экрана и передача APK/файлов | adb, предоставленный вызывающей стороной (эмулятор или устройство); [руководство по ADB](../adb-device-analysis.md) |
| Проекты JEB | Единицы проекта от движка, дайджесты артефактов и псевдокод типов/методов | Запущенный вызывающей стороной клиент JEB с интерфейсом MCP, выбирается через REA_JEB_MCP_URL; [руководство по JEB](../jeb-analysis.md) |
| Ресурсы Android | Декодированный манифест, таблицы строк, языки и сведения о версии | Запуск Apktool, предоставленный вызывающей стороной; [руководство по ресурсам](../apktool-resource-analysis.md) |
| Приложения Flutter | Хеш снапшота Dart, дайджесты библиотек по ABI и происхождение сборки движка | Не требуется (статический разбор APK); [руководство по Flutter](../flutter-analysis.md) |
| Прошивки | Области, результаты извлечения и передача в нативный анализ | Binwalk / Unblob в Linux; [руководство по прошивкам](../firmware-analysis.md) |
| Записанные пакеты | Выбранные поля, повторяющиеся значения, фильтры и правила декодирования | Linux: TShark 4.x + prlimit; [руководство по захватам](../packet-captures.md) |
| Захват пакетов | Конечные точки, DNS, TLS SNI, распределение протоколов и HTTP-запросы | Предоставленные вызывающей стороной tshark и capinfos; [руководство по pcap](../pcap-analysis.md) |
| Записанные логические сигналы | Аннотации декодера, диапазоны отсчётов и диагностика | Linux: sigrok-cli 0.7.2 + prlimit; [руководство по сигналам](../signal-recordings.md) |
| Пакеты и ресурсы | Списки файлов, хеши, plist, структура пакетов Apple и извлечённые ресурсы | [Руководство по артефактам и JavaScript](../javascript-artifact-reconstruction.md), [приложения Apple](../apple-application-analysis.md) |
| Поведение процессов | Вывод терминала, взаимодействия, наблюдения за завершением и файловой системой, сравнения запусков | Linux/macOS с нативным PTY; [захват процессов](../process-capture.md) |
| Цель | Что возвращает REA | Требования и руководство |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](../native-investigation.md) |
| Структура ELF без запуска | Секции, сегменты, исходные символы/релокации и возможные механизмы защиты по данным статического анализа | pwntools, предоставленный вызывающей стороной, в Linux x64; [диагностика бинарных файлов](../binary-diagnostics.md) |
| Байт-код EVM | Селекторы диспетчеризации, смещения байтов, предполагаемые аргументы и изменяемость состояния | Локальные необработанные байты или шестнадцатеричное представление в Linux x64; [руководство по EVM без запуска](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Записанные сбои Linux | Необработанные записи note, регистры/сигналы каждого записанного потока и необязательные кандидаты сопоставления с памятью | pwntools, предоставленный вызывающей стороной, в Linux x64; необязательные GDB/pwndbg; [записанные сбои](../recorded-crashes.md) |
| Установленные настольные приложения | Возможные среды выполнения, файлы с доказательствами, компоненты и дальнейшие шаги | Ограниченная проверка каталогов и заголовков;[Настольные приложения](../desktop-applications.md) |
| JavaScript / Electron | Модули, импорты, карты исходного кода, маршруты, IPC и связи с нативными дополнениями | Node.js и npm; [анализ приложений](../javascript-application-workflows.md) |
| Сайты | Структура страницы, скрипты, наблюдения за сетью и запрошенные снимки экрана | Браузер семейства Chrome; [анализ браузера](../browser-observation.md) |
| Сохранённые сетевые захваты | Запросы, ответы, доступные полезные данные и позиции в источнике | HAR; mitmdump в Linux для захватов в собственном формате mitmproxy; [руководство по сетевым захватам](../web-network-captures.md) |
| Сборки .NET | Метаданные, инструкции CIL, объявленные нативные зависимости и сравнения сборок | Статическое исследование; [руководство по управляемому коду](../managed-code-analysis.md) |
| Android APK | Объявления манифеста, классы, декомпилированные методы и ссылки | JADX без графического интерфейса и полный JDK в Linux/macOS/Windows x64; [руководство по Android](../android-analysis.md) |
| Устройства Android | Устройства, пакеты, процессы, журналы, дампы, снимки экрана и передача APK/файлов | adb, предоставленный вызывающей стороной (эмулятор или устройство); [руководство по ADB](../adb-device-analysis.md) |
| Проекты JEB | Единицы проекта от движка, дайджесты артефактов и псевдокод типов/методов | Запущенный вызывающей стороной клиент JEB с интерфейсом MCP, выбирается через REA_JEB_MCP_URL; [руководство по JEB](../jeb-analysis.md) |
| Ресурсы Android | Декодированный манифест, таблицы строк, языки и сведения о версии | Запуск Apktool, предоставленный вызывающей стороной; [руководство по ресурсам](../apktool-resource-analysis.md) |
| Приложения Flutter | Хеш снапшота Dart, дайджесты библиотек по ABI и происхождение сборки движка | Не требуется (статический разбор APK); [руководство по Flutter](../flutter-analysis.md) |
| Прошивки | Области, результаты извлечения и передача в нативный анализ | Binwalk / Unblob в Linux; [руководство по прошивкам](../firmware-analysis.md) |
| Записанные пакеты | Выбранные поля, повторяющиеся значения, фильтры и правила декодирования | Linux: TShark 4.x + prlimit; [руководство по захватам](../packet-captures.md) |
| Захват пакетов | Конечные точки, DNS, TLS SNI, распределение протоколов и HTTP-запросы | Предоставленные вызывающей стороной tshark и capinfos; [руководство по pcap](../pcap-analysis.md) |
| Записанные логические сигналы | Аннотации декодера, диапазоны отсчётов и диагностика | Linux: sigrok-cli 0.7.2 + prlimit; [руководство по сигналам](../signal-recordings.md) |
| Пакеты и ресурсы | Списки файлов, хеши, plist, структура пакетов Apple и извлечённые ресурсы | [Руководство по артефактам и JavaScript](../javascript-artifact-reconstruction.md), [приложения Apple](../apple-application-analysis.md) |
| Поведение процессов | Вывод терминала, взаимодействия, наблюдения за завершением и файловой системой, сравнения запусков | Linux/macOS с нативным PTY; [захват процессов](../process-capture.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
Статическое исследование JavaScript и .NET читает предоставленные файлы, не запуская приложение. Захват во время выполнения запускает выбранную цель или взаимодействует с ней с правами вашего пользователя; соответствующие руководства описывают последствия.
@@ -263,6 +265,8 @@ npx rea-agents@latest setup
- [Установка и настройка](../installation.md): регистрация агентов, настройка провайдеров, обновление и удаление.
- [Готовность и устранение неполадок](../installation.md#check-readiness-for-your-task): диагностика конкретного агента или движка анализа.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI и Evidence](../cli.md): команды, выбор провайдера, снимки, импорт/экспорт и коды завершения.
- [Контракты MCP](../mcp-contracts.md) и [промпты агентов](../mcp-prompts.md): результаты инструментов, сеансы и исследования с подсказками.
- [Каталог инструментов](../mcp-contracts.md#generated-catalog): создаваемый при сборке перечень инструментов, провайдеров и команд CLI.
+4
View File
@@ -146,11 +146,13 @@ REA ต้องใช้ Node.js 22.x (>=22.19), 24.x (>=24.11) หรือ 26
| ไบต์โค้ด EVM | ตัวเลือกฟังก์ชันสำหรับการเรียก ออฟเซ็ตไบต์ อาร์กิวเมนต์และความสามารถในการเปลี่ยนสถานะที่อนุมานได้ | ไฟล์บนเครื่องที่มีไบต์ดิบหรือข้อมูลเลขฐานสิบหกบน Linux x64; [คู่มือ EVM แบบออฟไลน์](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| ข้อมูลการแครชของ Linux ที่บันทึกไว้ | ระเบียน note ดิบ รีจิสเตอร์/สัญญาณของทุกเธรดที่บันทึกไว้ และตัวเลือกการแมปเพิ่มเติม | pwntools ที่ผู้ใช้จัดเตรียมบน Linux x64; เลือกใช้ GDB/pwndbg เพิ่มเติมได้; [การแครชที่บันทึกไว้](../recorded-crashes.md) |
| ไดเรกทอรีติดตั้งแอปเดสก์ท็อป | รันไทม์ที่เป็นไปได้ ไฟล์หลักฐาน ตัวบ่งชี้ส่วนประกอบ และขั้นตอนถัดไป | ตรวจสอบไดเรกทอรีและส่วนหัวโดยจำกัดขอบเขต;[แอปเดสก์ท็อป](../desktop-applications.md) |
| JavaScript / Electron | โมดูล การนำเข้า ซอร์สแมป เส้นทาง IPC และความสัมพันธ์กับส่วนเสริมเนทีฟ | Node.js และ npm; [การวิเคราะห์แอปพลิเคชัน](../javascript-application-workflows.md) |
| เว็บไซต์ | โครงสร้างหน้า สคริปต์ ข้อมูลเครือข่ายที่สังเกตได้ และภาพหน้าจอที่ร้องขอ | เบราว์เซอร์ในตระกูล Chrome; [การวิเคราะห์ผ่านเบราว์เซอร์](../browser-observation.md) |
| ข้อมูลเครือข่ายที่บันทึกไว้ | คำขอ คำตอบ เพย์โหลดที่ปรากฏ และตำแหน่งต้นทาง | HAR; mitmdump บน Linux สำหรับข้อมูลที่บันทึกในรูปแบบเนทีฟของ mitmproxy; [คู่มือการบันทึกข้อมูล](../web-network-captures.md) |
| การจับแพ็กเก็ต | จุดเชื่อมต่อ, DNS, TLS SNI, การกระจายโปรโตคอล และคำขอ HTTP | tshark และ capinfos ที่ผู้เรียกจัดเตรียม; [คู่มือ pcap](../pcap-analysis.md) |
| แอสเซมบลี .NET | เมทาดาทา คำสั่ง CIL การพึ่งพาเนทีฟที่ประกาศไว้ และการเปรียบเทียบผลการบิลด์ | การตรวจสอบแบบสถิต; [คู่มือโค้ดแบบจัดการ](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| APK ของ Android | การประกาศใน manifest คลาส เมธอดที่ดีคอมไพล์ และการอ้างอิง | JADX แบบไม่มี GUI และ JDK แบบเต็มบน Linux/macOS/Windows x64; [คู่มือ Android](../android-analysis.md) |
| อุปกรณ์ Android | อุปกรณ์ แพ็กเกจ โพรเซส บันทึก ดัมพ์ ภาพหน้าจอ และการถ่ายโอน APK/ไฟล์ | adb ที่ผู้เรียกจัดเตรียม (โปรแกรมจำลองหรืออุปกรณ์จริง); [คู่มือ ADB](../adb-device-analysis.md) |
| โปรเจกต์ JEB | หน่วยโปรเจกต์จากเอนจิน, แฮชของอาร์ติแฟกต์ และซูโดโค้ดของไทป์/เมท็อด | ไคลเอนต์ JEB ที่ผู้เรียกเริ่มและให้บริการ MCP เลือกด้วย REA_JEB_MCP_URL; [คู่มือ JEB](../jeb-analysis.md) |
@@ -263,6 +265,8 @@ npx rea-agents@latest setup
- [การติดตั้งและตั้งค่า](../installation.md): การลงทะเบียนเอเจนต์ การตั้งค่าผู้ให้บริการ การอัปเดต และการถอนการติดตั้ง
- [ความพร้อมใช้งานและการแก้ไขปัญหา](../installation.md#check-readiness-for-your-task): ตรวจวินิจฉัยเอเจนต์หรือเอนจินวิเคราะห์หนึ่งตัว
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI และ Evidence](../cli.md): คำสั่ง การเลือกผู้ให้บริการ สแนปช็อต การนำเข้า/ส่งออก และรหัสการสิ้นสุด
- [สัญญา MCP](../mcp-contracts.md) และ[พรอมป์ต์สำหรับเอเจนต์](../mcp-prompts.md): ผลลัพธ์เครื่องมือ เซสชัน และการตรวจสอบตามคำแนะนำ
- [แค็ตตาล็อกเครื่องมือ](../mcp-contracts.md#generated-catalog): รายการเครื่องมือ ผู้ให้บริการ และคำสั่ง CLI ที่สร้างระหว่างการบิลด์
+4
View File
@@ -151,10 +151,12 @@ REA; Node.js 22.x (>=22.19), 24.x (>=24.11) veya 26+ ve npm gerektirir. Ek araç
| EVM bayt kodu | Yönlendirme seçicileri, bayt ofsetleri, çıkarımla belirlenen argümanlar ve durum değiştirilebilirliği | Linux x64 üzerinde yerel ham bayt/onaltılık girdi; [çevrimdışı EVM rehberi](../evm-bytecode.md) |
| SQLite veritabanları | Tablolar, sütunlar, index'ler, view'lar, trigger'lar ve seçilen sıradan tablo satırları | Yerel database/WAL snapshot'ı; native SQLite sınırlarıyla Node.js 24.x >=24.15 veya 26+ |
| Kaydedilmiş Linux çökmeleri | Ham note kayıtları, kaydedilen her iş parçacığının yazmaçları/sinyalleri ve isteğe bağlı eşleme adayları | Linux x64 üzerinde çağıranın sağladığı pwntools; isteğe bağlı GDB/pwndbg; [kaydedilmiş çökmeler](../recorded-crashes.md) |
| Masaüstü kurulumları | Çalışma zamanı adayları, kanıt dosyaları, bileşen işaretleri ve sonraki adımlar | Sınırlı dizin ve başlık incelemesi;[Masaüstü uygulamaları](../desktop-applications.md) |
| JavaScript / Electron | Modüller, içe aktarmalar, kaynak haritaları, rotalar, IPC ve yerel eklenti ilişkileri | Node.js ve npm; [uygulama analizi](../javascript-application-workflows.md) |
| Web siteleri | Sayfa yapısı, betikler, ağ gözlemleri ve istenen ekran görüntüleri | Chrome ailesinden bir tarayıcı; [tarayıcı analizi](../browser-observation.md) |
| 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](../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](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.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](../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](../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](../jeb-analysis.md) |
@@ -268,6 +270,8 @@ Web sitesindeki [uygulamalı rehberlerden](https://rea.tools/tr/guides/) başlay
- [Yükleme ve kurulum](../installation.md): ajan kaydı, sağlayıcı yapılandırması, güncellemeler ve kaldırma.
- [Hazırlık ve sorun giderme](../installation.md#check-readiness-for-your-task): belirli bir ajanı veya analiz motorunu tanılama.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI ve Evidence](../cli.md): komutlar, sağlayıcı seçimi, anlık görüntüler, içe/dışa aktarma ve çıkış durumları.
- [MCP sözleşmeleri](../mcp-contracts.md) ve [ajan istemleri](../mcp-prompts.md): araç sonuçları, oturumlar ve yönlendirmeli araştırmalar.
- [Araç kataloğu](../mcp-contracts.md#generated-catalog): derleme sırasında oluşturulan araç, sağlayıcı ve CLI komutu envanteri.
+4
View File
@@ -146,11 +146,13 @@ REA потребує Node.js 22.x (>=22.19), 24.x (>=24.11) або 26+, а та
| Байт-код EVM | Селектори диспетчеризації, зміщення байтів, виведені припущення про аргументи та змінюваність стану | Локальні необроблені байти або шістнадцяткове представлення у Linux x64; [посібник EVM без запуску](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Записані аварійні завершення в Linux | Необроблені записи note, регістри/сигнали кожного записаного потоку й необов'язкові кандидати зіставлення пам'яті | pwntools, наданий стороною, що викликає інструмент, у Linux x64; необов'язкові GDB/pwndbg; [записані аварійні завершення](../recorded-crashes.md) |
| Встановлені настільні програми | Можливі середовища виконання, файли доказів, компоненти та наступні кроки | Обмежена перевірка каталогів і заголовків;[Настільні програми](../desktop-applications.md) |
| JavaScript / Electron | Модулі, імпорти, карти вихідного коду, маршрути, IPC і зв'язки з нативними доповненнями | Node.js і npm; [аналіз застосунків](../javascript-application-workflows.md) |
| Сайти | Структура сторінки, скрипти, мережеві спостереження й запитані знімки екрана | Браузер сімейства Chrome; [аналіз браузера](../browser-observation.md) |
| Збережені мережеві захоплення | Запити, відповіді, доступні корисні дані та місця в джерелі | HAR; mitmdump у Linux для захоплень у власному форматі mitmproxy; [посібник мережевих захоплень](../web-network-captures.md) |
| Захоплення пакетів | Кінцеві точки, DNS, TLS SNI, розподіл протоколів та HTTP-запити | Надані викликаючою стороною tshark та capinfos; [підручник pcap](../pcap-analysis.md) |
| Збірки .NET | Метадані, інструкції CIL, оголошені нативні залежності й порівняння збірок | Статична перевірка; [посібник керованого коду](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| Android APK | Оголошення маніфесту, класи, декомпільовані методи й посилання | JADX без графічного інтерфейсу й повний JDK у Linux/macOS/Windows x64; [посібник Android](../android-analysis.md) |
| Пристрої Android | Пристрої, пакети, процеси, журнали, дампи, знімки екрана та передавання APK/файлів | adb, наданий викликаючою стороною (емулятор або пристрій); [підручник ADB](../adb-device-analysis.md) |
| Проєкти JEB | Єдиниці проєкту від рушія, дайджести артефактів і псевдокод типів/методів | Запущений викликаною стороною клієнт JEB з MCP, обирається через REA_JEB_MCP_URL; [посібник JEB](../jeb-analysis.md) |
@@ -263,6 +265,8 @@ npx rea-agents@latest setup
- [Встановлення й налаштування](../installation.md): реєстрація агентів, конфігурація провайдерів, оновлення та видалення.
- [Готовність та усунення неполадок](../installation.md#check-readiness-for-your-task): діагностика конкретного агента або рушія аналізу.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI та Evidence](../cli.md): команди, вибір провайдера, знімки, імпорт/експорт і статуси завершення.
- [Контракти MCP](../mcp-contracts.md) і [промпти агентів](../mcp-prompts.md): результати інструментів, сеанси й керовані дослідження.
- [Каталог інструментів](../mcp-contracts.md#generated-catalog): створюваний під час збірки перелік інструментів, провайдерів і команд CLI.
+26 -22
View File
@@ -139,28 +139,30 @@ Tác nhân gọi REA qua MCP để kiểm tra mục tiêu và lần theo mã li
REA yêu cầu Node.js 22.x (>=22.19), 24.x (>=24.11) hoặc 26+, cùng với npm. Công cụ bổ sung và nền tảng chạy REA được hỗ trợ tùy thuộc vào mục tiêu:
| Mục tiêu | REA trả về gì | Yêu cầu và hướng dẫn |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Tệp nhị phân mã máy | Mã giả, hợp ngữ, chuỗi, ký hiệu, lời gọi và tham chiếu | Hopper, Ghidra hoặc IDA; [phân tích mã máy](../native-investigation.md) |
| Bố cục ELF ngoại tuyến | Các section, segment, ký hiệu/thông tin tái định vị gốc và các biện pháp giảm thiểu có thể có từ phân tích tĩnh | pwntools do bên gọi cung cấp trên Linux x64; [chẩn đoán tệp nhị phân](../binary-diagnostics.md) |
| Bytecode EVM | Bộ chọn điều phối, độ lệch byte, tham số suy luận và khả năng thay đổi trạng thái | Đầu vào cục bộ chứa byte thô hoặc dạng thập lục phân trên Linux x64; [hướng dẫn EVM ngoại tuyến](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Sự cố Linux đã ghi lại | Bản ghi note thô, thanh ghi/tín hiệu của mọi luồng được ghi lại và các ứng viên ánh xạ tùy chọn | pwntools do bên gọi cung cấp trên Linux x64; GDB/pwndbg tùy chọn; [sự cố đã ghi lại](../recorded-crashes.md) |
| JavaScript / Electron | Mô-đun, các khai báo import, source map, tuyến, IPC và quan hệ với tiện ích mở rộng mã máy | Node.js và npm; [phân tích ứng dụng](../javascript-application-workflows.md) |
| Trang web | Cấu trúc trang, script, quan sát mạng và ảnh chụp màn hình được yêu cầu | Trình duyệt thuộc họ Chrome; [phân tích trình duyệt](../browser-observation.md) |
| Bản ghi lưu lượng mạng đã lưu | Yêu cầu, phản hồi, payload có thể truy cập và vị trí nguồn | HAR; mitmdump trên Linux cho bản ghi định dạng gốc của mitmproxy; [hướng dẫn bản ghi mạng](../web-network-captures.md) |
| Bắt gói tin | Điểm cuối, DNS, TLS SNI, phân bố giao thức và yêu cầu HTTP | tshark và capinfos do nơi gọi cung cấp; [hướng dẫn pcap](../pcap-analysis.md) |
| Assembly .NET | Siêu dữ liệu, lệnh CIL, các phụ thuộc mã máy được khai báo và so sánh bản dựng | Kiểm tra tĩnh; [hướng dẫn mã được quản lý](../managed-code-analysis.md) |
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS/Windows x64; [hướng dẫn Android](../android-analysis.md) |
| Thiết bị Android | Thiết bị, gói, tiến trình, nhật ký, dump, ảnh chụp màn hình và truyền APK/tệp | adb do nơi gọi cung cấp (trình giả lập hoặc thiết bị); [hướng dẫn ADB](../adb-device-analysis.md) |
| Dự án JEB | Đơn vị dự án từ engine, hash của artifact và mã giả của kiểu/phương thức | Một ứng dụng JEB do nơi gọi khởi động, phục vụ MCP, chọn bằng REA_JEB_MCP_URL; [hướng dẫn JEB](../jeb-analysis.md) |
| Tài nguyên Android | Manifest đã giải mã, bảng chuỗi, ngôn ngữ và thông tin phiên bản | Trình khởi chạy Apktool do nơi gọi cung cấp; [hướng dẫn tài nguyên](../apktool-resource-analysis.md) |
| Ứng dụng Flutter | Băm snapshot Dart, hash thư viện theo ABI và nguồn gốc build engine | Không cần (phân tích APK tĩnh); [hướng dẫn Flutter](../flutter-analysis.md) |
| Phần sụn | Các vùng, kết quả trích xuất và dữ liệu chuyển sang phân tích mã máy | Binwalk / Unblob trên Linux; [hướng dẫn phần sụn](../firmware-analysis.md) |
| Gói tin đã ghi | Trường được chọn, giá trị lặp, bộ lọc và quy tắc giải mã | Linux: TShark 4.x + prlimit; [hướng dẫn bản ghi gói tin](../packet-captures.md) |
| Tín hiệu logic đã ghi | Chú thích bộ giải mã, phạm vi mẫu và chẩn đoán | Linux: sigrok-cli 0.7.2 + prlimit; [hướng dẫn tín hiệu](../signal-recordings.md) |
| Gói và tài nguyên | Danh sách tệp, giá trị băm, plist, cấu trúc bundle Apple và tài nguyên được trích xuất | [Hướng dẫn hiện vật phần mềm và JavaScript](../javascript-artifact-reconstruction.md), [ứng dụng 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](../process-capture.md) |
| Mục tiêu | REA trả về gì | Yêu cầu và hướng dẫn |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Tệp nhị phân mã máy | Mã giả, hợp ngữ, chuỗi, ký hiệu, lời gọi và tham chiếu | Hopper, Ghidra hoặc IDA; [phân tích mã máy](../native-investigation.md) |
| Bố cục ELF ngoại tuyến | Các section, segment, ký hiệu/thông tin tái định vị gốc và các biện pháp giảm thiểu có thể có từ phân tích tĩnh | pwntools do bên gọi cung cấp trên Linux x64; [chẩn đoán tệp nhị phân](../binary-diagnostics.md) |
| Bytecode EVM | Bộ chọn điều phối, độ lệch byte, tham số suy luận và khả năng thay đổi trạng thái | Đầu vào cục bộ chứa byte thô hoặc dạng thập lục phân trên Linux x64; [hướng dẫn EVM ngoại tuyến](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| Sự cố Linux đã ghi lại | Bản ghi note thô, thanh ghi/tín hiệu của mọi luồng được ghi lại và các ứng viên ánh xạ tùy chọn | pwntools do bên gọi cung cấp trên Linux x64; GDB/pwndbg tùy chọn; [sự cố đã ghi lại](../recorded-crashes.md) |
| Thư mục cài đặt ứng dụng máy tính | Các runtime có khả năng được dùng, tệp bằng chứng, dấu hiệu thành phần và bước tiếp theo | Kiểm tra thư mục và phần đầu tệp có giới hạn;[Ứng dụng máy tính](../desktop-applications.md) |
| JavaScript / Electron | Mô-đun, các khai báo import, source map, tuyến, IPC và quan hệ với tiện ích mở rộng mã máy | Node.js và npm; [phân tích ứng dụng](../javascript-application-workflows.md) |
| Trang web | Cấu trúc trang, script, quan sát mạng và ảnh chụp màn hình được yêu cầu | Trình duyệt thuộc họ Chrome; [phân tích trình duyệt](../browser-observation.md) |
| Bản ghi lưu lượng mạng đã lưu | Yêu cầu, phản hồi, payload có thể truy cập và vị trí nguồn | HAR; mitmdump trên Linux cho bản ghi định dạng gốc của mitmproxy; [hướng dẫn bản ghi mạng](../web-network-captures.md) |
| Bắt gói tin | Điểm cuối, DNS, TLS SNI, phân bố giao thức và yêu cầu HTTP | tshark và capinfos do nơi gọi cung cấp; [hướng dẫn pcap](../pcap-analysis.md) |
| Assembly .NET | Siêu dữ liệu, lệnh CIL, các phụ thuộc mã máy được khai báo và so sánh bản dựng | Kiểm tra tĩnh; [hướng dẫn mã được quản lý](../managed-code-analysis.md) |
| APK Android | Khai báo manifest, lớp, phương thức được dịch ngược và tham chiếu | JADX không giao diện đồ họa và JDK đầy đủ trên Linux/macOS/Windows x64; [hướng dẫn Android](../android-analysis.md) |
| Thiết bị Android | Thiết bị, gói, tiến trình, nhật ký, dump, ảnh chụp màn hình và truyền APK/tệp | adb do nơi gọi cung cấp (trình giả lập hoặc thiết bị); [hướng dẫn ADB](../adb-device-analysis.md) |
| Dự án JEB | Đơn vị dự án từ engine, hash của artifact và mã giả của kiểu/phương thức | Một ứng dụng JEB do nơi gọi khởi động, phục vụ MCP, chọn bằng REA_JEB_MCP_URL; [hướng dẫn JEB](../jeb-analysis.md) |
| Tài nguyên Android | Manifest đã giải mã, bảng chuỗi, ngôn ngữ và thông tin phiên bản | Trình khởi chạy Apktool do nơi gọi cung cấp; [hướng dẫn tài nguyên](../apktool-resource-analysis.md) |
| Ứng dụng Flutter | Băm snapshot Dart, hash thư viện theo ABI và nguồn gốc build engine | Không cần (phân tích APK tĩnh); [hướng dẫn Flutter](../flutter-analysis.md) |
| Phần sụn | Các vùng, kết quả trích xuất và dữ liệu chuyển sang phân tích mã máy | Binwalk / Unblob trên Linux; [hướng dẫn phần sụn](../firmware-analysis.md) |
| Gói tin đã ghi | Trường được chọn, giá trị lặp, bộ lọc và quy tắc giải mã | Linux: TShark 4.x + prlimit; [hướng dẫn bản ghi gói tin](../packet-captures.md) |
| Tín hiệu logic đã ghi | Chú thích bộ giải mã, phạm vi mẫu và chẩn đoán | Linux: sigrok-cli 0.7.2 + prlimit; [hướng dẫn tín hiệu](../signal-recordings.md) |
| Gói và tài nguyên | Danh sách tệp, giá trị băm, plist, cấu trúc bundle Apple và tài nguyên được trích xuất | [Hướng dẫn hiện vật phần mềm và JavaScript](../javascript-artifact-reconstruction.md), [ứng dụng 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](../process-capture.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
Kiểm tra tĩnh JavaScript và .NET đọc các tệp được cung cấp mà không chạy ứng dụng. Ghi lại khi chạy sẽ khởi chạy hoặc tương tác với mục tiêu đã chọn bằng quyền người dùng của bạn; từng hướng dẫn mô tả tác động của nó.
@@ -263,6 +265,8 @@ Bắt đầu với [hướng dẫn thực hành](https://rea.tools/vi/guides/) t
- [Cài đặt và thiết lập](../installation.md): đăng ký tác nhân, cấu hình trình phân tích, cập nhật và gỡ cài đặt.
- [Kiểm tra mức sẵn sàng và khắc phục sự cố](../installation.md#check-readiness-for-your-task): chẩn đoán một tác nhân hoặc bộ máy phân tích cụ thể.
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI và Evidence](../cli.md): lệnh, lựa chọn trình phân tích, ảnh chụp trạng thái, nhập/xuất và trạng thái thoát.
- [Hợp đồng MCP](../mcp-contracts.md) và [prompt cho tác nhân](../mcp-prompts.md): kết quả công cụ, phiên làm việc và điều tra có hướng dẫn.
- [Danh mục công cụ](../mcp-contracts.md#generated-catalog): danh sách công cụ, trình phân tích và lệnh CLI được tạo khi dựng dự án.
+4
View File
@@ -150,11 +150,13 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
| EVM 位元組碼 | 分派選擇器、位元組偏移、推斷的參數和狀態可變性 | Linux x64 上的本地原始位元組/十六進位輸入載體;[離線 EVM 指南](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| 已記錄的 Linux 崩潰 | 原始 note 記錄、每個已記錄執行緒的暫存器/訊號及可選的對映候選項 | Linux x64 上由呼叫方提供的 pwntools;可選的 GDB/pwndbg;[已記錄崩潰](../recorded-crashes.md) |
| 桌面安裝目錄 | 執行階段候選、支持檔案、元件標記與後續操作 | 有界的目錄與檔頭檢查;[桌面應用](../desktop-applications.md) |
| JavaScript / Electron | 模組、匯入、source map、路由、IPC 和原生附加元件關係 | Node.js 和 npm;[應用分析](../javascript-application-workflows.md) |
| 網站 | 頁面結構、腳本、網路觀察結果和按請求獲取的螢幕擷取畫面 | Chrome 系瀏覽器;[瀏覽器分析](../browser-observation.md) |
| 已保存的網路擷取 | 請求、回應、可訪問的酬載和來源位置 | HAR;原生 mitmproxy 擷取需要 Linux 上的 mitmdump;[擷取指南](../web-network-captures.md) |
| 封包擷取 | 端點、DNS、TLS SNI、通訊協定分佈和 HTTP 請求 | 呼叫端提供的 tshark 和 capinfos;[pcap 指南](../pcap-analysis.md) |
| .NET 程式集 | 中繼資料、CIL 指令、聲明的原生依賴和建置對比 | 靜態檢查;[托管程式碼指南](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| Android APK | 清單聲明、類別、反編譯的方法和引用 | Linux/macOS/Windows x64 上的無界面 JADX 和完整 JDK;[Android 指南](../android-analysis.md) |
| Android 裝置 | 裝置、套件、程序、日誌、傾印、螢幕擷取以及 APK/檔案傳輸 | 呼叫端提供的 adb(模擬器或實體裝置);[ADB 指南](../adb-device-analysis.md) |
| JEB 專案 | 引擎支援的專案單元、成品摘要和型別/方法的虛擬碼 | 由呼叫端啟動、提供 MCP 的 JEB 用戶端,透過 REA_JEB_MCP_URL 選擇;[JEB 指南](../jeb-analysis.md) |
@@ -269,6 +271,8 @@ npx rea-agents@latest setup
- [安裝與設定](../installation.md):AI 代理註冊、提供者組態、更新和卸載。
- [就緒檢查與故障排查](../installation.md#check-readiness-for-your-task):診斷特定 AI 代理或分析引擎。
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI 與 Evidence](../cli.md):命令、提供者選擇、快照、匯入/匯出和退出狀態。
- [MCP 契約](../mcp-contracts.md)和[AI 代理提示詞](../mcp-prompts.md):工具結果、會話和引導式調查。
- [工具目錄](../mcp-contracts.md#generated-catalog):建置時生成的工具、提供者和 CLI 命令清單。
+4
View File
@@ -150,11 +150,13 @@ REA 需要 Node.js 22.x(>=22.19)、24.x(>=24.11)或 26+,以及 npm。
| EVM 字节码 | 分派选择器、字节偏移、推断的参数和状态可变性 | Linux x64 上的本地原始字节/十六进制输入载体;[离线 EVM 指南](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| 已记录的 Linux 崩溃 | 原始 note 记录、每个已记录线程的寄存器/信号及可选的映射候选项 | Linux x64 上由调用方提供的 pwntools;可选的 GDB/pwndbg;[已记录崩溃](../recorded-crashes.md) |
| 桌面安装目录 | 运行时候选、支持文件、组件标记和后续操作 | 有界的目录与文件头检查;[桌面应用](../desktop-applications.md) |
| JavaScript / Electron | 模块、导入、source map、路由、IPC 和原生扩展关系 | Node.js 和 npm;[应用分析](../javascript-application-workflows.md) |
| 网站 | 页面结构、脚本、网络观察结果和按请求获取的截图 | Chrome 系浏览器;[浏览器分析](../browser-observation.md) |
| 已保存的网络捕获 | 请求、响应、可访问的载荷和来源位置 | HAR;原生 mitmproxy 捕获需要 Linux 上的 mitmdump;[捕获指南](../web-network-captures.md) |
| 数据包捕获 | 端点、DNS、TLS SNI、协议分布和 HTTP 请求 | 调用方提供的 tshark 和 capinfos;[pcap 指南](../pcap-analysis.md) |
| .NET 程序集 | 元数据、CIL 指令、声明的原生依赖和构建对比 | 静态检查;[托管代码指南](../managed-code-analysis.md) |
| PyInstaller | CArchive, PYZ, Python bytecode | Static inspection; [Python packaged applications](../python-packaged-applications.md) |
| Android APK | 清单声明、类、反编译的方法和引用 | Linux/macOS/Windows x64 上的无界面 JADX 和完整 JDK;[Android 指南](../android-analysis.md) |
| Android 设备 | 设备、软件包、进程、日志、转储、屏幕截图以及 APK/文件传输 | 调用方提供的 adb(模拟器或实体设备);[ADB 指南](../adb-device-analysis.md) |
| JEB 项目 | 引擎支持的项目单元、工件摘要和类型/方法的伪代码 | 由调用方启动、提供 MCP 的 JEB 客户端,通过 REA_JEB_MCP_URL 选择;[JEB 指南](../jeb-analysis.md) |
@@ -269,6 +271,8 @@ npx rea-agents@latest setup
- [安装与设置](../installation.md):智能体注册、提供方配置、更新和卸载。
- [就绪检查与故障排查](../installation.md#check-readiness-for-your-task):诊断特定智能体或分析引擎。
- [CUDA / HIP](../gpu-code-objects.md)
- [GGUF / safetensors](../model-artifacts.md)
- [CLI 与 Evidence](../cli.md):命令、提供方选择、快照、导入/导出和退出状态。
- [MCP 契约](../mcp-contracts.md)和[智能体提示词](../mcp-prompts.md):工具结果、会话和引导式调查。
- [工具目录](../mcp-contracts.md#generated-catalog):构建时生成的工具、提供方和 CLI 命令清单。
@@ -320,6 +320,13 @@ close a `packaged-process` obligation. A static-only source cannot close a
runtime or process claim. Marking a claim `blocked` or `out-of-scope` records the
disposition but does not silently count it as verified.
The `summary` counts obligations. `by_status`, `by_application_layer`, and
`by_source_state` place each obligation in exactly one bucket.
`by_evidence_authority` groups obligations by the Evidence `authority` of their
`authority_references`: an obligation counts once under each distinct authority
it cites, so those counts can exceed `total`. A reference's own `state` and the
obligation's `source_state` do not affect its authority bucket.
The tool returns every obligation inline. Its `ledger_id` and `closure_digest`
identify the complete result, including summaries, reports, ownership and
dependency graphs, Evidence links, and limitations.
+22 -1
View File
@@ -105,6 +105,27 @@ GDB/Python/pwndbg/strace. Fixture generation explicitly launches its owned test
program; subsequent inspection only reads the resulting core. Real acceptance
checks recorded threads, high registers, missing/malformed notes, opaque owners,
CLI/MCP parity, optional debugger context and historical PID collision with an
owned live sentinel. The syscall trace also rejects access to the still-present
owned live sentinel. An observed Node thread group must launch the exact ownership
`ps` inventory before it can read that live process's `stat` or `status` for native
identity/UID facts. Only traced `CLONE_THREAD` members share this allowance;
exec-replaced threads, ordinary children, debugger and decoder processes cannot
use it. The purpose of stat/status reads within the same Node thread group
cannot be distinguished by strace. A second recording uses a valid
historical PID above the host's assignable PID range and rejects resolved lookups,
including Node `stat`/`status` reads, to detect historical-PID-driven access separately
from live inventory. Descriptor paths come from strace's `-yy` decoding; exact
PID-directory opens and relative accesses through those handles are rejected.
Failed FD-relative pathname attempts are checked across syscall variants.
Legacy relative pathname calls without dirfd/cwd evidence and symlink aliases
remain unverified; the verification report declares these gaps rather than
establishing their absence.
One syscall/selector contract supplies trace selection, target interpretation
and the report's explicit coverage catalog. Unlisted PID-directed syscalls remain
unverified. The catalog includes PID-directed resource
limits, scheduling, priority, process metadata, signals and pidfd controls.
Self, group and UID selectors retain their syscall-defined meanings; unresolved
targets cannot qualify. Coverage is reported once for all CLI/MCP traces and
does not establish containment of every possible kernel interaction.
The syscall trace also rejects access to the still-present
source executable. The CI workflow defines Ubuntu 24.04 and Debian 13 (GDB 16)
container lanes. Original inputs and host configuration remain unchanged.
Loaded 100 of 2389 files, more files were not shown because too many files have changed in this diff. Show more