Compare commits

...
Author SHA1 Message Date
dependabot[bot] 8ee75da849 chore(deps): bump actions/download-artifact from 4.3.0 to 8.0.2
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.3.0 to 8.0.2.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/d3f86a106a0bac45b974a628896c90dbdf5c8093...9000827ccba6bdab643e8b6fd33ac0654aef8333)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-10-30 09:42:21 +00:00
morluto 6bb831df60 chore(security): configure dependency and ownership reviews 2026-10-30 17:35:34 +08:00
Kaoru0822andClaude Opus 5.5 37342ecde0 feat(native): open extension, framework, XPC and plug-in bundle directories (#8117)
* feat(native): open extension, framework, XPC and plug-in bundle directories

open_binary and the CLI inspection commands admitted only .app
directories and pointed every other Apple bundle at the JavaScript
analyzer. Resolve .appex, .framework, .xpc, .systemextension, .bundle
and .plugin directories through their Info.plist CFBundleExecutable, in
the Contents or flat root layout, plus the versioned framework layout
under Versions/Current. Exactly one layout may declare the bundle and
every resolved path must stay inside it.

Unresolvable bundles fail closed with typed constraints, probed paths
and the Info.plist that was read. Other Apple bundle types are refused as
unsupported instead of being offered the JavaScript route. Resource-root
discovery shares the same layout rule, so inspect_plist reads a
versioned framework's Info.plist. The recognized bundle vocabulary now
has one owner in the domain.

Refs #4310

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(native): refuse kernel extensions and state bundle error fields

Name the Apple bundle types binary routes recognize but do not open
(.dext, .kext, .qlgenerator, .mdimporter) explicitly, so a kernel
extension is refused as unsupported instead of receiving the JavaScript
route. Document which bundle refusals carry probed_paths and info_plist,
and make success tests throw the typed admission error before asserting.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(native): open flattened frameworks through Resources/Info.plist

Electron and Gecko apps ship frameworks without Versions/: the program
file sits at the framework root beside Resources/Info.plist, the layout
#8101 taught bundle anatomy. Read that layout for a framework without
Versions/, and keep the versioned layout for one with it, so a versioned
framework's root Resources link is never read as a second declaration.
The resource root reports it as flattened-framework.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 02:27:52 -07:00
Kaoru0822andClaude Opus 5.5 a47dcca010 perf(javascript): keep one member-effect record per stored fact (#8103)
Member-mutation indexing appended a binding write or escape record for
every traversal state that reached it. States that differ only in
coverage fields the record never stores (origin, owner initializer,
getter widening) produced identical records, and each later receiver
query rescanned all of them. Record each stored fact once, alongside the
existing required-module effect deduplication. Propagation is unchanged.

Effect ordering also re-walked the same top-level statement ancestry for
every candidate record. Cache it with the other initializer positions,
and test the selected path before the costlier receiver comparison.

On the #7774 reproducer the semantic IR and the complete
analyze-javascript-application Evidence are byte-identical, while the
CLI run drops from 146 s to 40 s.

Refs #7774

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 02:26:01 -07:00
Kaoru0822andClaude Opus 5.5 6b68fb642a fix(ci): remove unused exports that fail deep static checks (#8095)
* fix(ci): remove unused exports that fail deep static checks

Knip on main reports three analysis-view hub re-exports, two type
re-exports, an unused artifact-format guard and an alias constant. Drop
the dead re-exports and guard, and give the debugger control-reply budget
its own literal: it is a separate budget from the caller command-output
default, as its comment already states.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(config): read the Rizin control budget from its own constant

The Rizin control-reply admission limit still took its value from the
caller command-output default, while GDB used DEBUGGER_CONTROL_REPLY_BYTES.
Read the dedicated constant in both so the control budget has one owner.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 02:25:43 -07:00
Kaoru0822andClaude Opus 5.5 81378efb71 fix(electron): keep literal IPC sends ambiguous beside unresolved handlers (#8120)
* fix(electron): keep literal IPC sends ambiguous beside unresolved handlers

A main handler on an unresolved channel can receive any literal renderer
send of a compatible mode, but pairing ignored it unless it had a scoped
receiver. The send was then reported unpaired, or paired with another
handler. Treat an unresolved-channel handler as a competitor that never
pairs.

The wrapper pass seeds only calls with a literal first argument, so it now
records which invocations of a dynamic site it traced. The syntax finding
gains `invocation_channels: "literal"` only when every invocation is a
traced direct call of an unexported local function supplying a literal
channel. Such a site is already represented by its per-invocation findings
and does not compete.

Fixes #8118

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(electron): keep guarded wrapper registrations competing in IPC pairing

A guarded wrapper registration keeps its predicate on a call path and has
no IPC finding. It still counted toward `invocation_channels: "literal"`,
so pairing lost it: a send on that channel was reported unpaired, or
paired uniquely with a direct handler. The enumerated site now carries
these channels as `guarded_invocation_channels`, and each one competes for
its own channel without pairing.

Index each binding's direct call sites by appending in place. Spreading
the earlier calls on every reference was quadratic in a file's call count.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 02:21:23 -07:00
ShuaixinHuang 72039ecca9 fix(environment): retain conflicting scenario MIME uncertainty (#8082)
* fix(environment): retain conflicting scenario MIME uncertainty

* test(mcp): assert structured absolute-path diagnostics

* test(mcp): assert typed selector and stdio diagnostics
2026-10-30 17:19:46 +08:00
ShuaixinHuang d77104daab fix(fit): preserve leading U+FEFF in property strings (#8083) 2026-10-30 17:19:38 +08:00
Kaoru0822andClaude Opus 5.5 cce33142ed fix(apple): charge the XML plist decoder's DOM before decoding (#8115)
* fix(apple): charge the XML plist decoder's DOM before decoding

The XML preflight charged 4 bytes per character and 256 bytes per start
or end tag. The decoder builds an @xmldom/xmldom DOM that measured
1,000-1,160 bytes per element and up to 240 bytes per text, comment or
CDATA node, which were not charged at all. A 1.75 MB plist of 230,000
<true/> lines was admitted under the 64 MiB decode budget and peaked at
249 MiB of heap; shipped Apple plists peaked at 80-104 MiB.

Charge each element and each text, comment, CDATA or DOCTYPE node at a
measured upper bound, keeping the character and number-projection terms.
The binary estimator already bounds its decoder and is unchanged.

Fixes #8113

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(apple): charge every XML element, attribute and reference

The XML preflight recognized only element names starting with an ASCII
letter, so names such as é, _, a CJK or astral character escaped the
element charge: 100,000 <é/> elements (0.5 MB) built an 84 MiB DOM before
the plist decoder rejected the tag. Attributes and entity or character
references were also uncharged; 20 attributes per element measured about
210 bytes each, and each reference about 26 bytes beyond its characters.

Classify markup by the character after "<" instead of a name pattern, so
anything other than an end tag, comment, CDATA, PI or declaration counts as
an element (saxes rejects malformed markup before the DOM is built). Charge
each unquoted "=" in a start tag as an attribute node and every "&" as a
reference.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(apple): charge XML references only where the parser expands them

The previous commit charged every "&" in the document as a reference,
including literal ampersands inside CDATA sections and comments. A valid
plist with one CDATA string of 1,000,000 ampersands was refused although
it is a single node the decoder holds as one string.

Count "&" during the existing token walk, only in text runs and in the
attribute values of start tags, so comments, CDATA, PIs and declarations
add no reference charge and the scan stays a single pass.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 01:29:16 -07:00
Kaoru0822andClaude Opus 5.5 c5f50e80d8 fix(captures): admit browser-serialized HAR request URLs (#8112)
* fix(captures): admit browser-serialized HAR request URLs

[email protected] checks request.url with ajv-formats' strict RFC 3986
`uri` format. Browsers record and send URLs as WHATWG serializes them,
which keeps characters such as `|` and `{` unescaped in the query, so one
Google Fonts or GraphQL GET entry made inspect-web-network-capture and
environment-build reject the whole HAR.

HAR 1.2 defines request.url only as the absolute request URL. Own that
correction in the HAR validator: every URL the RFC 3986 check accepts
stays accepted, and a URL that WHATWG URL serialization reproduces
unchanged is accepted too. Spellings WHATWG would rewrite (a backslash
authority, a tab, a space) and relative references still fail.

Fixes #8110

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(captures): state that RFC 3986 request URLs stay admitted

The HAR request URL rule is "passes RFC 3986, or WHATWG serialization
reproduces it unchanged". A spelling WHATWG would rewrite therefore fails
only when it also fails the RFC 3986 check; an uppercase host still
passes. Say so in the docs and the validator comment, and pin the
accepted uppercase-host case in the CLI test.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 01:03:35 -07:00
Kaoru0822andClaude Opus 5.5 9d68aac76d fix(javascript): stop reporting self-defaulted receivers as module loads (#8109)
The CommonJS loader search treated any repeated state on its own ancestor
chain as an unknown loader. A self-default such as
`session.messages = session.messages || []` forms that cycle, because a
member read inside the assigned value was attributed to the later call's
read site and selected the same write again. Each `push` on the value was
then reported as an unresolved `require` load, and graph coverage became
partial.

Record a member read inside a flowed value as a depth-1 captured selection
at its own position, as member mutations already do for flowed origins.
Treat a revisited state as adding no source; the cycle's other entries are
still expanded once each. Remove the superseded ancestor tracking.

Fixes #8102

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 01:01:21 -07:00
Kaoru0822andClaude Opus 5.5 24398a89e4 fix(source-maps): resolve empty sourceRoot sources against the map URL (#8107)
webpack 5 and tsc write "sourceRoot": "" for map-relative sources. Since
5f702dd6c the shared join added "/" for any non-null root, so these
sources resolved from the URL root: rxjs's ../../../src/internal/Observable.ts
under /npm/[email protected]/dist/cjs/internal/ became /src/internal/Observable.ts,
and xterm's webpack://xterm/./src/... became https://host/webpack://xterm/....

Treat an empty root like a null root in sourceMapReference, the single join
used by trace-web-source-location, analyze-javascript-application and the
web source-map fetcher. Chrome, Firefox and trace-mapping skip an empty root,
and tc39/ecma426#183 wrote the current steps to match them. Non-empty roots,
including "/" and repeated slashes (#6726), keep their existing behavior.

Fixes #8106

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 01:00:41 -07:00
Kaoru0822andClaude Opus 5.5 0ce76e70f4 fix(desktop): charge retained rows at their measured representation (#8105)
* fix(desktop): charge retained rows at their measured representation

The desktop scan reserved 1024 + 24 bytes per path character for every
row, omission and the root against its 32 MiB representation budget. Real
rows cost 800-940 heap and 490-640 JSON bytes, so the charge overstated
them 6-13 times and large macOS bundles stopped at 3,700-7,200 entries,
far below max_entries.

Charge each path at the larger of its UTF-16 heap size and its escaped
JSON size, plus the existing fixed row and omission overheads, in one
helper. The bound still covers the retained heap and the serialized
report, including control-character paths that expand six times in JSON.

Fixes #8104

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(desktop): charge every retained copy of a path

The tighter row charge counted each path once, but rows repeat it in
convention-fact values and the next probes those facts offer, and host
failure issues name the absolute path. Control-character paths under a
convention such as Content/Paks or resources/app.asar therefore serialized
47-80 MiB of reports within the 32 MiB budget.

Reserve each copy through the same text helper where it is stored: path
convention facts with their row, the probes any fact offers (at most two,
pinned by a projection test) with that fact, retained read ranges before
their read, and probe failure issues before they are recorded.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 01:00:28 -07:00
Kaoru0822andClaude Opus 5.5 6d19649c0b fix(apple): read flattened framework Info.plist from Resources (#8101)
A macOS framework without Versions/ keeps its binary, _CodeSignature/ and
Resources/Info.plist directly in the .framework, as Electron and Gecko apps
ship it. Bundle anatomy looked for a shallow bundle's plist only at its root
and reported info_plist_path: null under complete coverage.

Resolve a shallow bundle's root Info.plist first, then Resources/Info.plist,
the same layout a framework version directory uses. Keep the iOS platform
rule tied to a root-level Info.plist so a Resources/-only application root
is not classified as iOS.

Fixes #8100

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 01:00:06 -07:00
Kaoru0822andClaude Opus 5.5 bfa082f777 fix(analysis-view): keep inferred confidence on views of inferred Evidence (#8099)
createAnalysisViewEvidence chose view confidence from the view result kind
only, so every summary, page or item view of an inferred parent
(compare_source_to_bundle, inspect_evm_interface, partially resolved
inspect_il2cpp_metadata) was sealed as derived while keeping the parent's
authority. A projection never makes its facts more certain: an inferred
parent now yields inferred views through CLI and MCP alike. Observed and
derived parents keep their existing view confidence and identities.

Fixes #8098

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 00:59:53 -07:00
morlutoandCursor Agent 317bf3fe23 fix: report provider admission failures as typed codes (#8066)
* fix: report provider admission failures as typed codes

* fix(evm): keep limiter path on admission diagnostics

* fix: assert WABT and CBOR admission codes

* fix: keep admission details on returned failures

* fix(evm): detect repeated CBOR keys in the decoder

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 06:48:01 +08:00
morlutoandCursor Agent 3b647132c6 fix(kuna): report document failures as typed codes (#8064)
* fix(kuna): report document failures as typed codes

Kuna JSON, graphs, xrefs, spans, and command checks threw Error and
published the sentence. Those refusals are now KunaDocumentError codes
with the field or path that failed. Output errors keep the code as
reason and the same facts in diagnostics.

* fix(kuna): keep incoming-reference address fields

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 06:07:53 +08:00
morlutoandCursor Agent 249b90c5e3 refactor(javascript): break the semantic analysis import cycle (#8063)
* refactor(javascript): break the semantic analysis import cycle

Split shared semantic facts out of the analysis hub so projectors of
effects, evaluation, and identity no longer import one another in a cycle.

* refactor(javascript): share the import specifier reader

Read static imports in one module used by the boundary checker and both
cycle guards, so those rules cannot drift apart.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 06:07:49 +08:00
940d71a45a refactor(analysis-view): break the analysis view hub cycle (#8061)
* refactor(analysis-view): break the analysis view hub cycle

Move request fragments, the request union, and the result union out of
analysisView.ts so projectors no longer import the module that imports them.
The dispatcher re-exports the public schemas and seals projector results.

Co-authored-by: morluto <[email protected]>

* fix(analysis-view): check inferred projector results

Require each projector result to match the unsigned result union before
sealing it, and parse the cycle guard's imports with Babel so comments
and side-effect imports are not misread.

* fix(analysis-view): close IL2CPP and Android symbol view inputs

Admit those projectors through AdmittedView and check test selections
against their request schemas, so misspelled fields fail at the call site.

---------

Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-30 05:41:58 +08:00
morlutoandCursor Agent 4a8d8f72b3 feat(debugger): share GDB and Rizin session caps as REA_ settings (#8056)
* feat(debugger): share GDB and Rizin session caps as REA_ settings

Move the duplicated deadline guidance into the owned debugger helper and
replace the shared session, queue, output, and 120s command caps with
launch settings that name their value, source, and range.

* test(gdb): assert the command-output setting on truncated exit evidence

The retained-output limitation now names REA_DEBUGGER_MAX_COMMAND_OUTPUT_BYTES
instead of the old fixed-cap sentence.

* test(gdb): assert command-output limit fields on truncated exit

A truncated GDB exit now carries the command-output setting, value, and
source on the cleanup error. The coverage test reads those fields.

* fix(debugger): keep control replies and evidence hashes inside their budgets

Point the session-cap mutation target at DEFAULT_DEBUGGER_MAX_SESSIONS.
Give startup and cleanup replies a fixed 16 MiB budget so a small caller
output cap cannot truncate them. Lower the command-output maximum so
escaped Evidence JSON stays under Node's string ceiling, and keep GDB
startup timeout diagnostics when the error is rebuilt.

* test(debugger): throw typed Result errors before success checks

Success cases no longer assert ok and return. They throw the typed
error first, then check session, deadline, and close fields.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 05:41:54 +08:00
morlutoandCursor Agent 395b598383 refactor(admission): own inspector, web, and CLI state per host (#8058)
* refactor(admission): own inspector, web, and CLI state per host

Replace the process-global inspector, web-bundle, guidance, and JavaScript
counters with objects a host passes in, so independent instances do not
share admission or cleanup.

* fix(admission): keep worker and file cleanup on the host

Web-bundle and JavaScript workers retry only their host registry, and
each Inspector admission authorizes and closes its own file scope.
Browser providers can share one web-bundle admission.

* test(inspector): gate one admission's file cleanup

The isolation test delayed the first ArtifactResourceScope.retryCleanup
call, so a second call on a shared ElectronFileScope still finished.
Hold first.files.retryCleanup until the other admission's close
finishes, then release and join before restoring the method.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 05:23:33 +08:00
morlutoandCursor Agent b663c79552 fix(domain): replace bare parser errors with typed codes (#8057)
* fix(domain): replace bare parser errors with typed codes

OpenStep syntax, canonical JSON digests, managed-graph source checks,
frame fingerprints, and reference-flow invariants threw Error and
published the sentence. Each refusal now carries a code. Tests assert
that code, including OpenStep position, instead of the previous prose.

* test(domain): pin OpenStep refusal codes and positions

The syntax cases accepted any code and any offset. Each container
refusal now expects its code and source position, including the deep
suffix that changes (x from unterminated_array to expected_separator.
Scalar failures stay identical to the pinned decoder.

* test(filesystem): assert OpenStep keyed-archive codes

The deep-suffix keyed archive cases compared ArtifactReaderFailure
message text with the pinned decoder sentence. They now require
reason format and the OpenStep code and source position on the cause.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 05:23:10 +08:00
a4c183b750 refactor(adb): move device and client operations out of the provider switch (#8062)
* refactor(adb): move device and client operations out of the provider switch

Keep AdbProvider as the session owner. Device listing, device inspection,
and client identity now run in AdbDeviceOperations, and shared listing
execution construction lives next to the client identity result.

Co-authored-by: morluto <[email protected]>

* refactor(adb): use the shared client and provider identity types

Drop the ClientIdentity and ProviderIdentity aliases so method signatures
name AdbClientResult and AdbProviderIdentity directly.

Co-authored-by: morluto <[email protected]>

---------

Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-30 05:02:41 +08:00
morlutoandCursor Agent fa1aa64ce4 fix(errors): store resource-constraint recovery as one shape (#8055)
* fix(errors): store resource-constraint recovery as one shape

AnalysisResourceConstraintError kept remediationAction, fixedAllowance,
and retryable as independent optionals, so a refusal could claim both a
fixed allowance and a separate remediation. The constructor now stores
the existing ResourceConstraintRecovery union, and the three accessors
read that object.

* test(errors): cover competing resource-constraint recovery fields

A runtime options object can still carry both a fixed allowance and a
remediation action. The constructor keeps the allowance and drops the
other field; the regression now supplies both.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 04:50:02 +08:00
morlutoandCursor Agent b894be6361 fix(native)!: report NativeAOT failures as reason codes (#8053)
* fix(native)!: report NativeAOT failures as reason codes

PeImage admission failures and parser recoveries used to publish
Error.message as NativeAotReport.reason. The report is now a union on
status, and reason is a typed code with the fields that code needs.
Complete reports keep reason null and a located header. Partial and
not_applicable reports carry a code. Caller budget mistakes throw
AnalysisInputError or AnalysisResourceConstraintError with a diagnostics
code instead of a bare Error.

* fix(native): keep out-of-domain hydration pointers partial

An inline pointer outside the unsigned 64-bit domain made
writeBigUInt64LE throw RangeError, and the hydration catch rethrew it
instead of recording a partial report. Those targets are now an
admission detail. The load-image summary schema still accepts the
optional Ghidra extension's string reason.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 04:49:57 +08:00
morlutoandCursor Agent 5f9187cd27 refactor(artifacts): describe formats in one registry (#8054)
* refactor(artifacts): describe formats in one registry

Reader construction, classification retention, container role, and
extraction now read one descriptor per domain format id. unknown has
no reader, and zip package families share one capability row.

* fix(artifacts): keep reader presence in format descriptor types

Descriptor helpers no longer widen every format to an optional reader,
so ArtifactReaderFormat stays the union of formats that construct one.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 04:27:17 +08:00
morlutoandCursor Agent 1c14f66356 refactor(contracts): register CLI and MCP tools by family id (#8051)
* refactor(contracts): register CLI and MCP tools by family id

Walk the published tool-family list once for each adapter so a new
family id must supply both a CLI registrar and an MCP registrar.

* fix(cli): keep family registration off the contract tables

Walk family ids from the startup-safe list, and register the web script
commands with the application family that owns their MCP contracts.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 04:25:48 +08:00
HawkForgeandClaude Opus 5.5 1da304b282 fix(adb): verify pushes to long device paths (#8047)
* fix(adb): verify pushes to long device paths

sha256sum echoes the device path, so a correct digest line for a path
near 1 KiB exceeded the fixed 1 KiB capture budget. The resulting
resource failure was then reported as device_digest_source "unavailable",
the same outcome as a device without sha256sum. Size the budget to the
path, and return a capture-budget failure as a resource constraint
instead of an unverified success.

Fixes #3369

* Keep adbDeviceAnalysis.ts as on main

* test(adb): keep only the long-path digest test

Main already covers an oversized checksum answer as a resource
constraint with the completed push retained.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-30 02:48:51 +08:00
ShuaixinHuang da5ec6b62c fix(macho): preserve literal segment name BOMs (#8040) 2026-10-30 02:47:33 +08:00
morlutoandCursor Agent c0c3902207 fix(native): preserve Mach-O target selection in macOS tools (#7831)
* fix(native): preserve Mach-O target selection in macOS tools

* fix(native): retain exact Mach-O slice signature coverage

* fix(native): admit x86_64 LIB64 signature selectors

* test(native): match signature checks to actual slices

* fix(native): recognize vtool refusals on private Mach-O aliases

Match vtool's container refusal to the operand the command received so a
parenthesized universal path keeps completed facts and the refusal
limitation. Expect codesign -a only when the target format is universal.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 00:03:23 +08:00
morlutoandCursor Agent 845080aef6 fix(session): align resource-only status and snapshot recovery (#7896)
* fix(session): align resource-only status and snapshot recovery

* fix(session): report independent workflows during resource sessions

* test(mcp): honor SQLite runtime availability

* test: compare resource snapshot guidance with its formatter

Assert projected error codes and the owning remediation action for
resource-session snapshot refusals, and type MCP error text as a closed
content item.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-30 00:03:19 +08:00
morluto bf115be2cd fix(evidence)!: report storage publication limits (#7887)
* fix(evidence): report storage publication limits

* test(evidence): cover staged storage failure cleanup
2026-10-29 23:03:09 +08:00
morluto 539a494d25 docs(setup): restore target and Hopper launch settings (#7902) 2026-10-29 23:03:02 +08:00
morlutoandCursor Agent ec4a0a01c4 fix(hopper): reconcile observed caller relationships (#7953)
* fix(hopper): reconcile observed caller relationships

* fix(hopper): retain completed caller scans on failure

Attach the native reply and collected forward facts when reconciliation
fails or is cancelled, and check scan stop codes separately from their
wording. Live observations keep REA evidence ids rather than provider
supplied ones, and the real Hopper verifier uses advertised MCP schemas.

* fix(hopper): answer caller-scan methods in the package fixture

The packaged Hopper stand-in echoed unknown bridge methods, so
analyze_function rejected rea_caller_scan_target as an invalid scan
target and the native package baseline returned unreadable_output.

* fix(hopper): share caller identities in failed scan observations

Failure partials repeated each caller identity under every destination.
The page budget counted compact replies, then schema parsing copied the
expanded form. Identities are stored once and destinations cite addresses.

* refactor(config): own the Hopper caller-scan budget default

The environment schema hard-coded the 2000 ms scan default. The domain
limit owner now names that millisecond budget and the schema reuses it.

* test(mcp): assert bundle path issues by field

compare_bundles reports each relative path as an invalid_format issue
instead of one joined diagnostic sentence.

* test(flutter): assert ABI selector refusals as structured issues

inspect_dart_aot reports the ABI label as an issue on path abi. The
message is the selector contract, without an abi: prefix.

* fix(session): retain caller observations that cannot be replayed

A missing document selector blocks snapshot replay. Backward call-graph
and trace reads still keep the native result and forward observations,
and the workflow Evidence links those records.

* fix(session): keep decompile bodies out of the in-memory ledger

Caller and callee walks still stay in Evidence without a document.
procedure_pseudo_code does not, so decompile_all leaves each body in the
file-backed export instead of retaining the whole export in memory.

* fix(hopper): own caller-scan recovery and the page byte allowance

Scan facts stay in the domain. Environment recovery, including the time
budget bounds and the fixed allowances with no runtime override, is
appended from configuration. Setup forwards the budget, and the bridge
uses one byte allowance for instructions, native callers, and pages.

* fix(hopper): retain compact caller references within the scan budget

Recovered call sites stay in the address form the scan already counted.
Expanded identity copies are measured before allocation and refused when
they exceed the retention budget. Instruction lists are not part of the
retained reply.

* fix(session): omit instruction payloads from retained caller evidence

Documentless caller and callee reads stay in the ledger for the session.
Their evidence keeps call sites and drops instruction lists the scan
already consumed.

* fix(hopper): keep the owning caller address on each compact call site

A page reference marked source_procedure "caller" belongs to that page
item's caller. Saved sites record that address, and an owner missing from
the callee inventory is stored once instead of copied onto every site.

* fix(session): leave Hopper reply shaping to the Hopper adapter

Documentless caller evidence stores the adapter's raw result unchanged.
The session no longer reads native_result.instructions.

* test(hopper): throw typed scan failures before reading results

Successful caller-scan results now throw the typed error instead of
returning after an ok check. Expected failures assert structured tags,
stop codes, and reported limits.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 22:54:58 +08:00
8188497f13 feat(artifacts): inspect and extract Bun standalone module graphs (#6998)
* feat(artifacts): inventory and extract Bun standalone executable module graphs

Adds a Bun standalone artifact reader for Mach-O, PE, ELF and appended
trailers, supporting the 36-byte and 52-byte module record layouts. It
preserves module names, entry-point details and raw metadata, and
exposes contents, sourcemaps, bytecode and module-info as separate
entries for safe extraction without executing the binary. Parsing
rejects malformed or ambiguous graphs and enforces module-count,
retained-byte and expansion limits. Adds synthetic parser tests, CLI and
MCP coverage, agent skill guidance, and a verification script for
Bun-produced executables.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe

* fix(artifacts): bound Bun section probes and reject truncated sections

Split Bun recognition into a bounded probe that reads only section
headers, length prefixes, and the Offsets/trailer suffix, and a single
payload load used by the reader. Inventory classification and extraction
admission no longer allocate the whole graph.

Match ELF `.bun` section names by comparing only the name bytes and
terminator, so many headers sharing one long name cost constant work each.
Reject sections whose declared extent ends past EOF instead of reading a
silently shortened window.

Launch Bun, Docker, and REA in the standalone verifier through the shared
owned verifier commands, and release the runtime root only after those
command families have settled.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe

* style(artifacts): format Bun reader integration

* fix(contracts): describe static Bun inventory facts

* fix(artifacts): bound Bun metadata reads and combined path growth

---------

Co-authored-by: Matt Van Horn <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: gensokyo-dev <[email protected]>
2026-10-29 22:31:50 +08:00
gensokyo-dev cac6e0613e fix(ci): enforce architecture guards before dependency setup (#8027)
* fix(ci): enforce architecture guards before dependency setup

* test(ci): bind cache policy to preceding Node setup
2026-10-29 21:29:15 +08:00
a108a1b817 fix(cli): report incomplete debugger cleanup as typed outcomes (#8021)
* fix(cli): report incomplete debugger cleanup as typed outcomes

debug-with-gdb and debug-with-rizin hand-rolled final cleanup in
try/finally blocks: a failed or interrupted final close only logged
and assigned the process exit status, so callers still received
complete successful Evidence with no typed error or partial
observation.

Both commands now route through the shared close owner used by the
other one-shot CLI commands (deliverCliAnalysisEvidence /
finishAnalysisCommand) via a small closeDebuggerCommandSession
helper. A rejected closeAll projects as ProviderCleanupError, which
the owner turns into cleanup_incomplete retaining the completed
Evidence as partial observation; a signal observed after finalization
projects as cancelled with the same retained observation. The
per-session close failure still only logs, preserving the rule that
the retained owner's closeAll decides completion.

Fixes #7378. Fixes #7429.

* test(cli): reject unmodeled GDB requests in cleanup regressions

* test(cli): match modeled GDB requests exactly

* Update tests/boundary/cli/gdbStartupCleanupCli.test.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: morluto <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-10-29 20:52:03 +08:00
gensokyo-dev b3d31ed106 fix: preserve nullable source-map facts and streamline model tests (#8018)
* test: repair MCP validation assertions and reuse model sessions

* test(ci): audit constrained guidance bundle fingerprints

* fix(browser): distinguish empty and absent source-map declarations

* refactor(browser): encode script metadata groups once

* test: assert structured path errors without freezing prose
2026-10-29 20:35:25 +08:00
morlutoandCursor Agent 34577eb1cc fix(filesystem): preserve undecodable symlink targets (#7935)
* fix(firmware): preserve symlink target bytes

* fix(apple): preserve undecodable dylib link targets

* style(tests): fix CI formatting

* test(firmware): select the named contract directly

* test(firmware): record raw bytes for a decodable symlink target

* test(mcp): assert bundle path issues by field

compare_bundles reports each relative path as an invalid_format issue
instead of one joined diagnostic sentence.

* test(firmware): stat raw links without following them

access follows a symlink, so a published dangling raw-link still looked
absent. lstat and readlink inspect the link itself.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 20:07:30 +08:00
morlutoandCursor Agent e124bdfc54 fix(cli): preserve literal Markdown rendering (#7938)
* fix(cli): preserve literal Markdown rendering

* fix(cli): retain literal Markdown attributes

* fix(cli): preserve literal punctuation in markdown

* test(cli): update escaped empty object expectations

* style(cli): format the literal empty-object Markdown expectation

* test(mcp): assert bundle path issues by field

compare_bundles reports each relative path as an invalid_format issue
instead of one joined diagnostic sentence.

* test(flutter): assert ABI selector refusals as structured issues

inspect_dart_aot reports the ABI label as an issue on path abi. The
message is the selector contract, without an abi: prefix.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 20:07:17 +08:00
记得吃中饭andgensokyo-dev 22cab8215a feat(artifacts): inspect and extract .NET single-file bundles (#3787)
* feat(artifacts): inventory and extract .NET single-file bundles

* fix(artifacts): retain bundle source I/O failure reasons

* docs(artifacts): record Linux bundle regression verification

* fix(artifacts): preserve bundle source failures and cancellation

* docs(artifacts): record synchronized bundle verification

* fix(artifacts): bind bundle extraction to inventoried host

* docs(artifacts): record bundle verification outcome

* fix(artifacts): bound bundle paths and suggest extraction

* fix(artifacts): preserve nested executable container boundaries

* test(artifacts): verify projected .NET members and simplify extraction admission

* fix(artifacts): explain fixed bundle limits at their producing boundary

---------

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-29 20:06:58 +08:00
morlutoandCursor Agent 5c05eb88e5 fix(javascript)!: preserve operator influence in semantic traces (#7939)
* fix(javascript)!: preserve operator influence in semantic traces

* test(javascript): align semantic influence regressions

* style(javascript): format semantic IR

* test(javascript): follow literal argument seed influence

* fix(javascript): keep one literal node per operator operand

Reuse an existing literal for operator influence, and treat TypeScript
assertion wrappers as transparent when deciding whether a call result is used.

* test(mcp): assert bundle path issues by field

compare_bundles reports each relative path as an invalid_format issue
instead of one joined diagnostic sentence.

* fix(javascript): index operator literals by range and initializer

Repeated string operands rescanned every retained literal and every
initializer flow. Lookup now uses those indexes, and a 1200-declaration
file still projects one literal per operand.

* fix(javascript): keep literal and call facts on their own occurrences

Operator literals match their own source range, so a nested function does
not inherit the enclosing declaration's literal. A direct argument still
reaches the call, while the assigned result follows modeled returns.
for-loop initializers and updates are discarded call results.

* test(javascript): expect conditional operand literals beside binding values

A conditional binding keeps one candidate literal per union value and one
operator literal per operand token. Those are different facts, so the
aggregate payload check counts four nodes and compares literal seeds in
query order.

* perf(javascript): index call return flows by call site

projectCalls filtered every call return for each assigned result. Group
those flows once while projecting returns-to-call edges.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 20:06:55 +08:00
morlutoandCursor Agent 6fa48f201f docs(apk): clarify rotated signer agreement (#7936)
* docs(apk): clarify rotated signer agreement

* test(mcp): assert bundle path issues by field

compare_bundles reports each relative path as an invalid_format issue
instead of one joined diagnostic sentence.

* fix(javascript): ignore worker frames for a different source job

A failure frame for another job was dequeued as an output error, so a
later caller abort lost the race and was not reported as cancellation.

* test(flutter): assert ABI selector refusals as structured issues

inspect_dart_aot reports the ABI label as an issue on path abi. The
message is the selector contract, without an abi: prefix.

* fix(javascript): check each worker frame condition once

A ready frame is rejected on its own. A non-ready frame for another job
keeps waiting. The following id comparison repeated that skip, so it
never ran.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 20:00:02 +08:00
morlutoandCursor Agent 1ef5918179 fix(browser): preserve source-map declaration uncertainty (#7945)
* fix(browser): preserve source-map declaration uncertainty

* style(tests): fix CI formatting

* fix(browser): retain known source map differences

* fix(web): bind map comparisons to script metadata

* fix(browser): match source maps with partial script metadata

Keep each script's observed hash and declaration constraints instead of
dropping a metadata field for the whole URL group.

* test(flutter): assert ABI selector refusals as structured issues

MCP input validation reports the ABI path and the schema message separately.
The old concatenated "abi: ..." sentence is no longer the delivered error.

* fix(web): prove large source-map changes without factorial search

Groups larger than eight scripts were reported as unexplained, so nine
x.map declarations plus one omission compared as unknown against ten
y.map declarations. Declaration counts reject impossible placements, and
augmenting paths assign the rest without retrying identical scripts.

* test(mcp): assert bundle path issues by field

compare_bundles reports each relative path as an invalid_format issue
instead of one joined diagnostic sentence.

* fix(web): match repeated source-map scripts by count

Identical declarations share one group, and a shared omission pool is
counted once. A 2000-script self-compare no longer builds a dense
assignment graph.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 18:50:26 +08:00
51ad84516e feat(environment): serve sorted creates, listed references and toggles (#7600)
* feat(environment): serve the writes callers make without recorded form fields

- A create member a recording sent empty ("", null, false, [] or {}) is no
  longer required; a call that leaves it out is applied as sending that value
  (body.blank).
- List views render envelope members that list the listed entities' ids
  (Paperless's `all`), so creates in such collections are confirmed.
- Updates move their entity in collections kept sorted by a field they write,
  and a failed whole-collection read after an update can teach that order.
- A later create that stores an unruled field otherwise is withheld at the
  create, and an item read may fill values a create's answer had not loaded.
- An unsent field respelled between null, [] and {} is unchanged.
- The skill asks for one create with every field and one with only what a
  person must give.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): show how to read signed-in pages before recording

Agents guessed capture keys (artifacts, dom, final) to see pages behind
sign-in, which inspect_web_page cannot reach.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): accept every empty spelling recorded creates sent

A create that fills only what a person must give sends `null` where the
full create sent a string, and `null` or `false` for the same flag. The
merged plan now accepts each recorded empty value, and a call that leaves
the member out is applied as the earliest call sent it.

Also adds the spec folder for this change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): keep the vary-fields step neutral on UI or API writes

Agents read "the form" as a cue to write through the UI, where some
applications' request bodies are not exposed; a body-unusable UI write
now re-records once with request steps.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record verification for blank members and sorted writes

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): address review of blank members and sorted writes

- Bulk updates move their entities in turn against the others' earlier
  values and install the final order once, as replay does.
- A member's recorded empty values stay accepted once a later call teaches
  its default; a left-out member with a default keeps the default.
- Write answers spell empty lists and maps as their recorded answers did.
- A rename can teach a sort when the creates chose one by a field the
  update did not write, such as ids that ascend with titles.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve the writes that later reads explain

- An item read whose object is marked deleted (deleted, isDeleted or
  is_deleted true) agrees with an absent entity, as EspoCRM answers a
  deleted record; such an object never seeds or adopts an entity.
- maxSize, max_results and maxResults are page sizes, for whole-collection
  list lines and the list query's limit role.
- An item view also shows the fields only reads after its type's first write
  show, when no initial entity holds them (Vikunja's task subscription),
  without requiring them; write answers leave such a field out for entities
  without it, and it no longer withholds the write as incomplete-entities.
- The skill asks updates to change the fields a person would change, and
  expects a deleted object to read back as 404 or marked deleted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer sent empty members as sent, and keep a placed create's order

- A write answer spells an empty list or map the call did not send as its
  recorded answer did; one the call sent is answered as sent, so a create
  sending `[]` is not answered `null` because the first recorded create was.
- A read listing the whole collection that placed a create leaves the create
  only the sorted inserts whose order that read follows, so a later rename
  cannot teach a sort an earlier read ruled out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer bulk updates without fields only later reads show

A bulk update's answer renders each entity with the same allowance a single
update's answer has: a field only reads after the type's first write showed,
which no initial entity holds, is left out for an entity without it, so a
bulk update of a seeded task is no longer refused for lacking it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): correct how the EspoCRM contact update task passes

The agent trajectories show gpt-oss passes it by creating a replacement contact
and deleting the original, since the served update refuses emailAddress; the
update itself is refused in both builds.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer a read of a served-deleted entity marked deleted

An application that soft-deletes still answers a deleted record by id, marked
deleted. Serving now keeps an entity a served delete removed from a type whose
recorded item reads show that, until a reset or load and within the size
data/add loads, and answers a read of it with its last fields and the flag
true, instead of refusing the read.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers, check bulk answers with sent members, narrow inserts only on collection-order reads

- A create whose item read loaded values its answer had not records them
  (`observation.read.unloaded`), and a served create's answer keeps them as
  the recorded answer showed them, a zero-time owner included, while the state
  holds the read's.
- Replay checks a bulk update's recorded answers with each target's sent
  members, as serving answers them, so echoed `null` and `[]` no longer make
  the plan body-unusable.
- A whole-collection read whose query sorts it shows the query's order, so it
  no longer narrows a create's sorted insert candidates.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the census with main's unknown-clock rule merged

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve query numbers, counted values and made objects

- A query parameter accepts a number or boolean, which serving sends as its
  JSON text, as agents send page sizes and flags.
- A sequence may start at the value its first create took above every value
  its type held (Vikunja's per-project task index), and a later create's
  composed, template or started-sequence rule is adopted when it also spells
  the first create's value.
- A made-object rule explains an object the application makes with each
  created entity: members the request stamped, members holding the entity's
  own id, and counts one past the held objects' values.
- A create's answer names the id of the one object a one-element array member
  holds, so bulk creates link to their type.
- The skill reads each listed object by id before writing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): let a linked create take path values it stores

A create linked to its type's own collection, whose path has no parameters,
accepts any path values when its plan stores each one in a field, as a Vikunja
task stores its project; replay and serving apply it alike.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn a sort from a rename only when moving its entities reaches it

Serving moves only the entities a write changes in a collection kept sorted,
so replay now tries a sort after a rename only when the entities no write the
read exercised changed already follow it. Seeded folders listed out of title
order no longer teach a title sort that serving would answer with another
order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers a sent value did not echo, and learn no sort from query-sorted reads

- A served create keeps a value its recorded answer had not loaded unless the
  call sent that member and the plan stores it as sent, so a create sending
  `active: false` is answered `false` as recorded while the state holds the
  read's `true`.
- A rename no longer teaches a sort from a whole-collection read its query
  sorts, whose ties need not follow the collection's own order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): verify query values, counted values and made objects

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn the soft-delete flag in the state view and serve by it

Extraction now records the member later item reads set true on a record the
application soft-deleted, and the item view carries it as `deleted_flag`.
Serving reads that fact instead of scanning recorded bodies itself, so one
owner decides what a soft delete looks like.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the call-values checks at #7274 93821024

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn the soft-delete flag from item reads with a query too

A client may read a deleted record back only with a query, such as a
cache-busting parameter. Every successful read of the item tool now shows the
flag; only plain later reads still add fields.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the call-values checks at #7274 45832406

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn sorts only from orders a list read confirmed

- A sort retry after a failed whole-collection read requires the entities no
  write changed since a list last showed them to follow it already, rather than
  excusing every entity the update's tool ever wrote: an earlier rename a list
  confirmed in place stays where it was.
- An update takes its creates' sort only from a create a list read showed
  placed; replay still tries a sort a create guessed from the initial order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): drop entities read back as deleted and answer soft deletes as deleted

- A held entity a later read shows marked deleted is dropped, not adopted with
  the marked object's fields.
- Bulk-update replay renders answers with the optional and later-only fields
  serving uses, so a bulk update of created and seeded entities replays.
- A served delete of a soft-deleting type answers with the entity marked
  deleted, single and bulk.
- A deleted flag only query reads showed is a field of the item view, so a
  served tombstone keeps it where live records omit it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): check made objects as recorded and keep their ids and clocks honest

- A made object's clock counts as a write clock, so a capture with no clock
  anchor withholds the create instead of stamping 1970.
- Members holding the entity's identity follow the id written, generated or
  sent, through the type's id field.
- A later create's made object is checked as recorded, before its own members
  are rewritten, so one naming another entity withholds the plan.
- A later create's template is adopted only when it spells that create's value
  too, not just when the first create's text holds its source value.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): move updated entities only by placed sorts and keep query-sorted reads from confirming order

Replay moved an updated entity by a sort a create only guessed, while the
update plan exported only placed sorts, so a read could confirm an update
by a move serving would not make. Both now use the placed sort. A passing
list read clears its entities from the moved set only when the state
decides the order of every entity it lists, so a read whose query sorts
it no longer hides an earlier move from a later sort check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): count six withheld plans that explain more, not seven

The bulk task create counted among them is served on this branch.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): try a learned sort by moving each pending write in turn, as serving does

#retrySort sorted the whole collection, which a list could match while
serving, moving each renamed entity in turn against the others' values
before their own writes, gave another order. The state now records the
values each write replaced, and the retry replays the writes since a
list in collection order last showed their entities.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer a served delete with the deleted flag its recorded answer showed

An application may answer a delete with the record as it was and mark it
deleted only on later reads. Delete answers, single and bulk, now take
the flag's value from the recorded answer; reads of a served-deleted
entity still show it marked deleted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): set aside two hunks next to lines main's saved-values change rewrites

Main's #7267 changes the lines beside the blank-member docs and the
empty-spelling check in explainUpdate. Setting them aside lets that merge
apply cleanly; the commit after it puts them back on top of main's text.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): restore the set-aside hunks on main and bump the skill to 51

Puts the blank-member docs and the empty-spelling check back beside main's
slug and composed text and heldSlugRule. Main is at skill 50 with
different text, so this branch's skill changes take 51.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): bump the skill to 52 above #7260's 51

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): put back the call-values hunks main's merge took its side for, and bump the skill to 53

The merge of main kept main's side where it overlapped this branch, so it
could commit without a conflict. This restores this branch's side next to
main's: made-object agreement beside the & slug spellings, sequence starts
in the earlier evidence (now built by earlierOf), the combined value
imports, and recording step 2 beside main's UI-first step 3. Main is at
skill 50 and #7274 at 52, so this branch takes 53.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep sorts a list showed in place ruled out, and created answers' nested members as recorded

A whole list in collection order that showed a renamed entity where a
sort by the renamed field would have moved it now rules that sort out, so
a later rename of the same entity cannot teach it. A create's answer
leaves out members its item read added inside an object the answer
showed, as the recorded answer did; the state still stores them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve writes whose calls send different members

Recordings now vary what a type's two creates and updates send, and REA
withheld writes where a later call left out what the first sent. An update
plan's required members narrow to those every call sent; a member one create
sent and another left for the application to number is a sequence that
takes the value a call sends; a PUT's left-out member the application
cleared becomes that member's default; and an update's clock is held as
the read after it spells it. The skill spaces creates (skill 54).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep a later create's made object only with clocks its request stamped

followsMadeObjects only checked that a made object's clocks parsed, so a
later create whose object showed an older clock still passed, while serving
stamps the write's clock. Its clocks must now be in the rule's format and
within the stamp window of that create's request.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): accept sent values either way, check defaults against every call, and store update clocks as reads spell them

A sequence that takes sent values now accepts one a later create sent
after the first left the member to be numbered. A default an update learned
must agree with every update that left its member out, else the plan is
withheld. An update plan whose read-back spells a stamped clock at a coarser
precision keeps that read as observation.read, and serving stores the
update's clocks in its spelling while answers keep the response's.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): check recorded member and sequence values

* fix(environment): compare soft-deleted read fields

* fix(environment): reject contradictory learned sequences

* fix(environment): preserve initially deleted item observations

* fix(environment): index stored deleted entities separately

* fix(environment): replay lists that include deleted records

* feat(environment): serve sorted creates, listed references and toggles

A create a whole listing placed last is placed again by the sort a later
listing shows. A field holding the entities a sent list of ids names is a
reference with `many`, and a create that sent the member empty agrees with
one that named entities. A scenario request whose body Playwright did not
expose and that names no Content-Type sent no body. An item action calls
show flipping a boolean both ways learns a `toggle` rule. Skill 55 asks
recordings to run an action twice on one object.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): count a sequence number a create sends, as replay does

Serving now records a number a call sends for a `sequence` with `sent` in the
same count history it generates from, so after that entity is deleted the next
generated number still follows it, as replay's takeSequences does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the final gate run in the verification

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): make no count of a made-object member earlier creates held alike

A count only a later create shows starts at the exemplar's value, which is
right only while the exemplar is the one create accepted: creates accepted
after it showed the member unchanged, which a count would have moved. The
merge now refuses such a count, as the top-level sequence check does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): restate the verification after merging #7539

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): check PUT defaults against reads, and respell update clocks by serving's rule

A default a PUT learns must also agree with what the read after an earlier or
the current call showed for the member its answer left out, so a call whose
read showed the member kept withholds a later clearing default.

Replay and serving now choose an update clock's stored spelling by one rule,
readSpellsCoarser: the read after it at a coarser precision in the same zone
and separator. A read in another zone or separator is no longer adopted by
replay, which serving could not store, and a create's plain clocks stay as
answered, as serving makes them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep sorts earlier listings ruled out, and empty added references

A sort a whole listing that placed a create did not follow stays ruled out for
that create, though the entity that showed it is later deleted. A create that
sends a reference's member empty after a later create added the reference
agrees with it, as with a reference the first create showed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): restate the verification after the review round

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): leave out a reference the observed create left out

A create the plan observes that left out a reference's member stored no such
field, so a served call leaving the member out stores none either, though a
later recorded create sent it empty; a call sending it empty still stores that.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): restate the verification after #7539 merged main

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep the largest sequence value in replay, and store update clocks by the kept read

Replay now keeps the largest value a sequence took, as serving's commitWrite
does, so a lower sent value no longer lowers the next number.

Serving stores every update's clocks in the spelling of the read the plan
keeps as observation.read; replay now does the same through
readSpelledClocks, instead of adopting each update's own read, so a later
update whose read spells its clock otherwise contradicts the plan. The plain
clock branch of restampedFields, which no caller used any more, is gone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): restate the verification after merging #7539 3b800a10

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep learned sorts, references, and toggles faithful

Do not adopt a sort an earlier update already ruled out. Learn a list
reference only when every element shows the same nonempty fields. Promote
a toggle only when every call started from a boolean.

* test(environment): compare list-reference fields with matching values

The mixed-field case uses the held tag's color, so rejection comes from
the field set rather than a value the recording never stored.

* test(mcp): assert bundle path issues by field

The compare_bundles rejection reports each relative path as an
invalid_format issue instead of one joined diagnostic sentence.

* test(mcp): assert field issues for bundle paths and Dart ABI

Relative bundle paths and rejected ABI selectors are reported as
input issues on those fields, not as one joined diagnostic sentence.

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 18:46:18 +08:00
01e00dae72 fix(process): corroborate exiting Linux ownership candidates (#7958)
* fix(process): corroborate Linux exits after procfs environ read races

A token read failing with ENOENT/ESRCH may race with process exit while
native identity observation still sees a live PID. Recheck native lifetime
and accept absence only when corroborated; keep unverifiable or reused
PIDs fail closed.

Refs #7790

* fix(process): recheck Linux exit after final token retry

A process can exit after the final retry of a failed procfs environment
read. Re-observe native identity before producing final cleanup failures,
and keep PID replacement and uncertain identity fail-closed.

Add five integration-facing sweep regression cases for absence, live,
unavailable, replaced and zombie-replaced candidates.

Refs #7790

* fix(process): bound native exit settlement for token-open races

After a terminal ENOENT/ESRCH run-token read, allow a tightly bounded
native-only settlement window to corroborate pending Linux process exit.
Retain an explicit failure for live/unavailable or changed PID identities,
without inferring exit from the token error itself.

Cover delayed absence, delayed replacement and bounded live retries.

Refs #7790

* fix(process): share native token exit settlement

* fix(process): signal only groups with validated members

* fix(process): retain lineage through exit settlement

* fix(process): type mixed identity observations in exit checks

Map inference collapsed a readable/absent union onto the absent
overload after main tightened ProcessIdentityObservation.

* fix(process): refresh groups whose members exit during revalidation

A same-group child forked after the revalidation snapshot is not an
empty group, so cleanup reads the table again before skipping the signal.

* test(process): arm group-refresh exit from the revalidation snapshot

The regression follows the table read after planning observed the
launcher token, and requires a later refresh to see the forked child.

* test(mcp): assert bundle path issues by field

The compare_bundles rejection reports each relative path as an
invalid_format issue instead of one joined diagnostic sentence.

* test(mcp): assert field issues for bundle paths and Dart ABI

Relative bundle paths and rejected ABI selectors are reported as
input issues on those fields, not as one joined diagnostic sentence.

---------

Co-authored-by: Harshit Sharma <[email protected]>
Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 18:40:12 +08:00
860fdd8fbe feat(macho): report per-slice encryption status in inspect_macho (#5359)
* refactor(macho): extract non-throwing container and slice load-command readers

Split readMachoImage into readMachoContainer, which classifies a file as
thin, FAT or not Mach-O and keeps FAT range issues per slice, and
readSliceLoadCommands, which reads one slice header and frames its load
commands, returning every command framed before a failure.

readMachoImage keeps its strict policy on top of them: commands framed
before a framing defect still decode first, an unsupported FAT slice
still yields to a later malformed one, and the first FAT range issue is
still reported. A characterization test pins that precedence for inputs
with several defects; it passes against both the previous and the new
implementation.

Part of #4306.

* feat(macho): report per-slice encryption status in inspect_macho

inspect_macho now reports the LC_ENCRYPTION_INFO(_64) state of every
slice in a new `encryption` collection, read in process from load
commands without reading code bytes.

- Each slice is encrypted, not-encrypted, absent, malformed or unknown.
  Absent requires a completed load-command walk; malformed and unknown
  carry a reason and keep commands read before the failure.
- The named range is end-exclusive in slice and input-file coordinates
  and maps to file-backed segment fragments, VM addresses and the
  overlapping nonempty sections.
- A ciphertext range adds a limitation naming its input-file bytes.
- The in-process read and the native tools are bracketed by one regular
  file descriptor and stat identity checks; a change reports
  artifact_changed. A missing or inaccessible target keeps the tool
  facts and reports encryption as non-exhaustive, never absent.
- Retained Evidence recorded before this field is parsed by the owning
  schema and reports encryption as unknown in the macho view and in
  managed/native verification.

Fixes #4306

* fix(macho): keep slice facts and failures under large tables and close errors

- Frame load commands through a visitor instead of retaining every
  command, restoring the pre-refactor memory profile (2M eight-byte
  commands: peak heap 370 MiB -> 0.9 MiB).
- Confirm a large FAT container from a valid slice's Mach-O header so a
  sibling's range fault stays per slice instead of hiding healthy slices.
- Name only sections whose bytes the range and their segment both cover.
- Throw inspection failures inside the owned descriptor callback so a
  close failure keeps them as its primary error.

* fix(macho): map encrypted ranges only within segment VM extents

mapRange gave every file-backed segment fragment VM addresses, even for a
segment with no VM size, whose file bytes dyld never maps, and past vmsize
when a segment declared more file bytes than memory.

Read vmsize with the segment. A segment with no VM size keeps its fragment
with null VM addresses. A file size beyond the VM size, or a VM range past
the address space, makes the mapping unknown with a reason while the slice
keeps its encryption status.

The docs also claimed the encryption read never reads code bytes. Like
every Mach-O container read, a 0xcafebabe input of at most 16 MiB is read
whole to rule out a JVM class file; say so.

* fix(macho): read encryption through the admitted descriptor facts

Main's withArtifactRegularFile now hands callers the admitted handle and
its initial stats. Use those facts instead of re-stating the handle, and
pass the legacy Evidence payload straight to createEvidence.

* fix(macho): retain a finished report when the target close fails

The file owner keeps the completed callback value when the descriptor close
fails or cancellation arrives during close. inspect_macho now validates that
value and retains the report as the error's partial observation, as
inspect_signature does, instead of returning only the cleanup or
cancellation error.

* test(native): supply readEncryption in merged dyld refusal cases

main's new dyld refusal cases build NativeMachoInspectionContext without
the encryption reader this branch requires.

* test(views): bind the Mach-O encryption page to its facet

main's facet-ownership case builds inspect_macho Evidence without the
encryption coverage this branch requires; the fixture now carries one
slice row and the loop checks the encryption page like the other facets.

* fix(macho): bound encryption commands and range mapping across slices

A slice retains at most two encryption load commands, since a second one
already makes it malformed; the reason keeps the full count. Range mapping
in every slice shares one budget of segment and section records, charged
from each segment command's capacity before it is decoded. A slice past
the budget keeps its encryption status and reports an unknown mapping.

* style(macho): format encryption reader and binding test

* fix(macho): stop retaining segments past the mapping budget

Segment commands are collected during framing only while their mapping
records still fit in the budget shared by all slices, and the budget is
charged only when the slice maps its range.

* docs(macho): clarify retained mapping allowance

* fix(ci): own the Mach-O encryption test in Apple scope

---------

Co-authored-by: t <t@t>
Co-authored-by: gensokyo-dev <[email protected]>
2026-10-29 18:19:39 +08:00
morlutoandCursor Agent d3ecf68000 docs(website): clarify platform setup requirements (#7925)
* fix(website): clarify platform setup requirements

* style(website): format platform guidance

* docs(website): clarify Ghidra Linux host support

* style(website): format the Linux platform guidance paragraph

* docs(website): refresh gettext locations after guidance formatting

The wrapped get-started paragraph shifted source lines. Message ids and translations are unchanged.

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 16:55:17 +08:00
c88e1b0b43 feat(guidance): search installed workflow sections (#6996)
* feat(guidance): search bundled REA workflow guidance

* fix(guidance): address review findings

* test(guidance): fix boundary and dispatcher coverage

* test(setup): use supported doctor fixture runtime

* fix(guidance): resolve CI conformance, coverage, and review findings

* fix(guidance): own complete requests through shutdown

* test(guidance): bound lifecycle gates and join failed work

---------

Co-authored-by: Deepak-Kambala <[email protected]>
Co-authored-by: gensokyo-dev <[email protected]>
2026-10-29 16:47:10 +08:00
131fbe0754 feat(environment): serve writes whose calls send different members (#7539)
* feat(environment): serve the writes callers make without recorded form fields

- A create member a recording sent empty ("", null, false, [] or {}) is no
  longer required; a call that leaves it out is applied as sending that value
  (body.blank).
- List views render envelope members that list the listed entities' ids
  (Paperless's `all`), so creates in such collections are confirmed.
- Updates move their entity in collections kept sorted by a field they write,
  and a failed whole-collection read after an update can teach that order.
- A later create that stores an unruled field otherwise is withheld at the
  create, and an item read may fill values a create's answer had not loaded.
- An unsent field respelled between null, [] and {} is unchanged.
- The skill asks for one create with every field and one with only what a
  person must give.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): show how to read signed-in pages before recording

Agents guessed capture keys (artifacts, dom, final) to see pages behind
sign-in, which inspect_web_page cannot reach.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): accept every empty spelling recorded creates sent

A create that fills only what a person must give sends `null` where the
full create sent a string, and `null` or `false` for the same flag. The
merged plan now accepts each recorded empty value, and a call that leaves
the member out is applied as the earliest call sent it.

Also adds the spec folder for this change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): keep the vary-fields step neutral on UI or API writes

Agents read "the form" as a cue to write through the UI, where some
applications' request bodies are not exposed; a body-unusable UI write
now re-records once with request steps.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record verification for blank members and sorted writes

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): address review of blank members and sorted writes

- Bulk updates move their entities in turn against the others' earlier
  values and install the final order once, as replay does.
- A member's recorded empty values stay accepted once a later call teaches
  its default; a left-out member with a default keeps the default.
- Write answers spell empty lists and maps as their recorded answers did.
- A rename can teach a sort when the creates chose one by a field the
  update did not write, such as ids that ascend with titles.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve the writes that later reads explain

- An item read whose object is marked deleted (deleted, isDeleted or
  is_deleted true) agrees with an absent entity, as EspoCRM answers a
  deleted record; such an object never seeds or adopts an entity.
- maxSize, max_results and maxResults are page sizes, for whole-collection
  list lines and the list query's limit role.
- An item view also shows the fields only reads after its type's first write
  show, when no initial entity holds them (Vikunja's task subscription),
  without requiring them; write answers leave such a field out for entities
  without it, and it no longer withholds the write as incomplete-entities.
- The skill asks updates to change the fields a person would change, and
  expects a deleted object to read back as 404 or marked deleted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer sent empty members as sent, and keep a placed create's order

- A write answer spells an empty list or map the call did not send as its
  recorded answer did; one the call sent is answered as sent, so a create
  sending `[]` is not answered `null` because the first recorded create was.
- A read listing the whole collection that placed a create leaves the create
  only the sorted inserts whose order that read follows, so a later rename
  cannot teach a sort an earlier read ruled out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer bulk updates without fields only later reads show

A bulk update's answer renders each entity with the same allowance a single
update's answer has: a field only reads after the type's first write showed,
which no initial entity holds, is left out for an entity without it, so a
bulk update of a seeded task is no longer refused for lacking it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): correct how the EspoCRM contact update task passes

The agent trajectories show gpt-oss passes it by creating a replacement contact
and deleting the original, since the served update refuses emailAddress; the
update itself is refused in both builds.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer a read of a served-deleted entity marked deleted

An application that soft-deletes still answers a deleted record by id, marked
deleted. Serving now keeps an entity a served delete removed from a type whose
recorded item reads show that, until a reset or load and within the size
data/add loads, and answers a read of it with its last fields and the flag
true, instead of refusing the read.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers, check bulk answers with sent members, narrow inserts only on collection-order reads

- A create whose item read loaded values its answer had not records them
  (`observation.read.unloaded`), and a served create's answer keeps them as
  the recorded answer showed them, a zero-time owner included, while the state
  holds the read's.
- Replay checks a bulk update's recorded answers with each target's sent
  members, as serving answers them, so echoed `null` and `[]` no longer make
  the plan body-unusable.
- A whole-collection read whose query sorts it shows the query's order, so it
  no longer narrows a create's sorted insert candidates.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the census with main's unknown-clock rule merged

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve query numbers, counted values and made objects

- A query parameter accepts a number or boolean, which serving sends as its
  JSON text, as agents send page sizes and flags.
- A sequence may start at the value its first create took above every value
  its type held (Vikunja's per-project task index), and a later create's
  composed, template or started-sequence rule is adopted when it also spells
  the first create's value.
- A made-object rule explains an object the application makes with each
  created entity: members the request stamped, members holding the entity's
  own id, and counts one past the held objects' values.
- A create's answer names the id of the one object a one-element array member
  holds, so bulk creates link to their type.
- The skill reads each listed object by id before writing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): let a linked create take path values it stores

A create linked to its type's own collection, whose path has no parameters,
accepts any path values when its plan stores each one in a field, as a Vikunja
task stores its project; replay and serving apply it alike.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn a sort from a rename only when moving its entities reaches it

Serving moves only the entities a write changes in a collection kept sorted,
so replay now tries a sort after a rename only when the entities no write the
read exercised changed already follow it. Seeded folders listed out of title
order no longer teach a title sort that serving would answer with another
order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers a sent value did not echo, and learn no sort from query-sorted reads

- A served create keeps a value its recorded answer had not loaded unless the
  call sent that member and the plan stores it as sent, so a create sending
  `active: false` is answered `false` as recorded while the state holds the
  read's `true`.
- A rename no longer teaches a sort from a whole-collection read its query
  sorts, whose ties need not follow the collection's own order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): verify query values, counted values and made objects

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn the soft-delete flag in the state view and serve by it

Extraction now records the member later item reads set true on a record the
application soft-deleted, and the item view carries it as `deleted_flag`.
Serving reads that fact instead of scanning recorded bodies itself, so one
owner decides what a soft delete looks like.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the call-values checks at #7274 93821024

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn the soft-delete flag from item reads with a query too

A client may read a deleted record back only with a query, such as a
cache-busting parameter. Every successful read of the item tool now shows the
flag; only plain later reads still add fields.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the call-values checks at #7274 45832406

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn sorts only from orders a list read confirmed

- A sort retry after a failed whole-collection read requires the entities no
  write changed since a list last showed them to follow it already, rather than
  excusing every entity the update's tool ever wrote: an earlier rename a list
  confirmed in place stays where it was.
- An update takes its creates' sort only from a create a list read showed
  placed; replay still tries a sort a create guessed from the initial order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): drop entities read back as deleted and answer soft deletes as deleted

- A held entity a later read shows marked deleted is dropped, not adopted with
  the marked object's fields.
- Bulk-update replay renders answers with the optional and later-only fields
  serving uses, so a bulk update of created and seeded entities replays.
- A served delete of a soft-deleting type answers with the entity marked
  deleted, single and bulk.
- A deleted flag only query reads showed is a field of the item view, so a
  served tombstone keeps it where live records omit it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): check made objects as recorded and keep their ids and clocks honest

- A made object's clock counts as a write clock, so a capture with no clock
  anchor withholds the create instead of stamping 1970.
- Members holding the entity's identity follow the id written, generated or
  sent, through the type's id field.
- A later create's made object is checked as recorded, before its own members
  are rewritten, so one naming another entity withholds the plan.
- A later create's template is adopted only when it spells that create's value
  too, not just when the first create's text holds its source value.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): move updated entities only by placed sorts and keep query-sorted reads from confirming order

Replay moved an updated entity by a sort a create only guessed, while the
update plan exported only placed sorts, so a read could confirm an update
by a move serving would not make. Both now use the placed sort. A passing
list read clears its entities from the moved set only when the state
decides the order of every entity it lists, so a read whose query sorts
it no longer hides an earlier move from a later sort check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): count six withheld plans that explain more, not seven

The bulk task create counted among them is served on this branch.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): try a learned sort by moving each pending write in turn, as serving does

#retrySort sorted the whole collection, which a list could match while
serving, moving each renamed entity in turn against the others' values
before their own writes, gave another order. The state now records the
values each write replaced, and the retry replays the writes since a
list in collection order last showed their entities.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer a served delete with the deleted flag its recorded answer showed

An application may answer a delete with the record as it was and mark it
deleted only on later reads. Delete answers, single and bulk, now take
the flag's value from the recorded answer; reads of a served-deleted
entity still show it marked deleted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): set aside two hunks next to lines main's saved-values change rewrites

Main's #7267 changes the lines beside the blank-member docs and the
empty-spelling check in explainUpdate. Setting them aside lets that merge
apply cleanly; the commit after it puts them back on top of main's text.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): restore the set-aside hunks on main and bump the skill to 51

Puts the blank-member docs and the empty-spelling check back beside main's
slug and composed text and heldSlugRule. Main is at skill 50 with
different text, so this branch's skill changes take 51.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): bump the skill to 52 above #7260's 51

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): put back the call-values hunks main's merge took its side for, and bump the skill to 53

The merge of main kept main's side where it overlapped this branch, so it
could commit without a conflict. This restores this branch's side next to
main's: made-object agreement beside the & slug spellings, sequence starts
in the earlier evidence (now built by earlierOf), the combined value
imports, and recording step 2 beside main's UI-first step 3. Main is at
skill 50 and #7274 at 52, so this branch takes 53.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep sorts a list showed in place ruled out, and created answers' nested members as recorded

A whole list in collection order that showed a renamed entity where a
sort by the renamed field would have moved it now rules that sort out, so
a later rename of the same entity cannot teach it. A create's answer
leaves out members its item read added inside an object the answer
showed, as the recorded answer did; the state still stores them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve writes whose calls send different members

Recordings now vary what a type's two creates and updates send, and REA
withheld writes where a later call left out what the first sent. An update
plan's required members narrow to those every call sent; a member one create
sent and another left for the application to number is a sequence that
takes the value a call sends; a PUT's left-out member the application
cleared becomes that member's default; and an update's clock is held as
the read after it spells it. The skill spaces creates (skill 54).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep a later create's made object only with clocks its request stamped

followsMadeObjects only checked that a made object's clocks parsed, so a
later create whose object showed an older clock still passed, while serving
stamps the write's clock. Its clocks must now be in the rule's format and
within the stamp window of that create's request.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): accept sent values either way, check defaults against every call, and store update clocks as reads spell them

A sequence that takes sent values now accepts one a later create sent
after the first left the member to be numbered. A default an update learned
must agree with every update that left its member out, else the plan is
withheld. An update plan whose read-back spells a stamped clock at a coarser
precision keeps that read as observation.read, and serving stores the
update's clocks in its spelling while answers keep the response's.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): check recorded member and sequence values

* fix(environment): compare soft-deleted read fields

* fix(environment): reject contradictory learned sequences

* fix(environment): preserve initially deleted item observations

* fix(environment): index stored deleted entities separately

* fix(environment): replay lists that include deleted records

* fix(environment): count a sequence number a create sends, as replay does

Serving now records a number a call sends for a `sequence` with `sent` in the
same count history it generates from, so after that entity is deleted the next
generated number still follows it, as replay's takeSequences does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): make no count of a made-object member earlier creates held alike

A count only a later create shows starts at the exemplar's value, which is
right only while the exemplar is the one create accepted: creates accepted
after it showed the member unchanged, which a count would have moved. The
merge now refuses such a count, as the top-level sequence check does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): check PUT defaults against reads, and respell update clocks by serving's rule

A default a PUT learns must also agree with what the read after an earlier or
the current call showed for the member its answer left out, so a call whose
read showed the member kept withholds a later clearing default.

Replay and serving now choose an update clock's stored spelling by one rule,
readSpellsCoarser: the read after it at a coarser precision in the same zone
and separator. A read in another zone or separator is no longer adopted by
replay, which serving could not store, and a create's plain clocks stay as
answered, as serving makes them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep the largest sequence value in replay, and store update clocks by the kept read

Replay now keeps the largest value a sequence took, as serving's commitWrite
does, so a lower sent value no longer lowers the next number.

Serving stores every update's clocks in the spelling of the read the plan
keeps as observation.read; replay now does the same through
readSpelledClocks, instead of adopting each update's own read, so a later
update whose read spells its clock otherwise contradicts the plan. The plain
clock branch of restampedFields, which no caller used any more, is gone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep a left-out default from numbering, a read's sub-millisecond digits, and references named by member

A member a call left out and the application stored a fixed value for is no
longer turned into a numbered sequence by a later call that left it out.
Serving shortens an update's clock to the read's precision from the answer's
own digits, keeping microseconds. A PUT that names a reference field's entity
by its member supplies that field, for the default check and in serving.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): count a reference a later PUT names toward the default an earlier one cleared

The default check now reads the reference rules the current call shows as
well as the plan's, so a PUT naming the owner by ownerId after one that
cleared it is served, as in the other order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): number a left-out member past every sent value, and never fill it with a sent blank

A later create the application numbered at or below a value an earlier create
sent no longer turns the echo into a numbered sequence, since serving counts
past every sent value. A member a numbered sequence covers is not filled with
an empty value another call sent when a call leaves it out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): count sent values in the sequence's scope before numbering a left-out member

The largest value earlier creates sent is kept by type and by collection, and
a collection-scoped sequence adopted later checks only its own collection, so
a number sent in another collection no longer withholds a create numbered
within its own.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-29 16:14:05 +08:00
morlutoandCursor Agent 3503578f91 fix(session): preserve cancellation during mutation retirement (#7959)
* fix(session): preserve cancellation during mutation retirement

* fix(session): retain exact cleanup owners through retry

---------

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 16:05:43 +08:00
morlutoandCursor Agent bd3792566d docs(skill): clarify scenario pause deadlines (#7961)
Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 16:05:03 +08:00
f7cd4e5256 fix(adb): validate screen capture PNG headers (#7962)
* fix(adb): validate screen capture PNG headers

* fix(adb): state screen header validation limits

* style(adb): format screen capture assertion

Match the current formatter after integrating main.

Co-authored-by: morluto <[email protected]>

---------

Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-29 16:04:49 +08:00
morlutoandCursor Agent 2b85a4a2ba fix(native): preserve bookmark address uncertainty (#7966)
fix(analysis): preserve bookmark address uncertainty

Co-authored-by: Cursor Agent <[email protected]>
2026-10-29 15:54:33 +08:00
gensokyo-dev e3d8d20236 fix(native): preserve dispatch metadata format refusals (#8013)
* fix(native): preserve dispatch metadata format refusals

* test(native): normalize CLI format refusal envelopes

* test(native): assert admitted metadata target paths
2026-10-29 15:48:42 +08:00
17ceb77ca5 fix(mcp): preserve input validation issue attribution (#7981)
* fix(mcp): preserve input validation issue attribution

* fix(mcp): charge nested issue projection before allocation

* style(mcp): format server declarations

* fix(mcp): avoid duplicate fallback diagnostics

* test(mcp): assert structured validation issues

* test(mcp): align browser input issue assertions

* fix(mcp): retain SDK diagnostic parts once

* style(mcp): format diagnostic projection

---------

Co-authored-by: Cursor Agent <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-29 15:39:10 +08:00
STDquantum f25d1e3e9f fix(cli): preserve Amp MCP registration settings (#7995)
* fix(cli): preserve Amp registration environment and report failures (#7538, #7536)

* fix(cli): normalize equals-form mcp add agents before Incur parses them (#7538)

* fix(cli): remove the Amp settings backup after a verified registration (#7538)

* fix(cli): secure Amp registration backups

* test(cli): cover Amp registration backup permissions

* fix(cli): retain Amp registration recovery backups

* fix(cli): create private Amp recovery copies

* test(cli): fix Amp backup assertion typing

* fix(cli): preserve typed Amp backup failures

* fix(cli): handle Amp backup cleanup failures
2026-10-29 15:23:42 +08:00
Dragolone 124e97eac5 fix(native): explain categories whose class reference names no class (#8006)
An Objective-C category whose class field is null, or is bound to a
symbol other than `_OBJC_CLASS_$_`, was recorded as partial with
`category_class_unresolved`, but no issue was raised, so the
`objc_properties_categories` coverage facet reported `partial` with a
null reason. swiftc emits such categories for @objc members of an
extension on another module's Swift class and binds the class field to
the class metadata symbol (`_$s…CN`); Keynote and Notability carry them.

Report the reference as a `category_class_unresolved` issue naming the
bound symbol, or stating that the reference is null, matching the issue
already raised for an unreadable local class reference.
2026-10-29 15:14:10 +08:00
Dragolone 95637a3d70 fix(artifacts): name every U-Boot uImage type in the pinned image.h (#8007)
TYPE_NAMES stopped at flat_dt (8), while the U-Boot include/image.h
commit that the tables are pinned to defines image types 0-47. A header
declaring a later type, such as kernel_noload (14) or tfa-bl31 (45),
was reported with type_name "unknown".

Add types 9-47 with their mkimage -T short names from boot/image.c at
the same commit. IH_TYPE_LOADABLE (22) has no short name there and is
named "loadable", as other tables already name identifiers U-Boot does
not list. Identifiers past the enum stay "unknown".
2026-10-29 15:13:37 +08:00
ShuaixinHuang ca666ec130 fix(pe): reject invalid certificate bit-string padding (#8011) 2026-10-29 15:11:28 +08:00
gensokyo-dev 45cc935964 fix(native): accept walkable Mach-O command tables (#8002)
* fix(native): accept walkable Mach-O command tables

* test(native): verify large command tables through macOS CLI and MCP
2026-10-29 14:39:20 +08:00
morluto d82ba11ce2 test(ci): allow more time for Windows CLI subprocesses 2026-10-29 14:35:12 +08:00
LN Bodicherlaandgensokyo-dev c9bf6a9df7 feat(managed)!: show readable type names in member signatures (#5309)
feat(managed): show readable type names in member signatures

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-29 14:34:42 +08:00
morluto afc18131f4 fix(ci): reuse shared JavaScript AST child traversal 2026-10-29 14:33:14 +08:00
morluto 54f5cf7e14 fix(javascript): retain static facts under projection pressure (#7986)
* fix(javascript): retain static facts under projection pressure

* fix(javascript): scope IPC ambiguity to omitted projections

* fix(javascript): preserve IPC uncertainty for omitted sources

* fix(javascript): qualify IPC pairing by wrapper coverage

* fix(javascript): retain provisional IPC wrapper matches
2026-10-29 14:02:35 +08:00
gensokyo-dev f60e42a9ae fix(mcp)!: bound validation work before tool dispatch (#7905)
Reuse the pinned SDK's combined array-element and object-member admission
before canonical validation, deferred runtime loading and tool execution.
Share a configurable finite allowance across eager/deferred HTTP and stdio,
and project refusals to bounded, actionable transport resource errors.

Preserve canonical CLI/application contracts, caller-selected input values,
ordinary validation semantics and complete Evidence access. Exercise actual
transport boundaries, real artifact/TShark workflows, packaged installation,
continued service and downstream identity/capacity regressions.

Fixes #7882

BREAKING CHANGE: MCP tool arguments now default to 1,024 combined array
elements and object members per call. Select a larger positive finite
REA_MCP_MAX_INPUT_ELEMENTS allowance and restart for larger inline inputs,
or use retained/file selectors where supported. Inputs are never truncated.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-29 05:56:38 +00:00
morluto ddefba83ef test(artifacts): handle blocked open-parent renames (#7904)
* test(artifacts): handle blocked open-parent renames

* test(artifacts): exercise blocked parent rename cleanup
2026-10-29 13:45:12 +08:00
gensokyo-dev b966ebeb22 docs(readme): align Linux x64 analysis prerequisites (#7997) 2026-10-29 13:44:07 +08:00
RRFZ fca331804a fix(javascript): select JSON and addon loaders by exact suffix (#7821)
Node's CommonJS loader matches registered extensions case-sensitively, so
require("./data.JSON") and require("./addon.NODE") run as JavaScript.
Derive target_json_status and the native loads relation from the exact
loader suffix instead of the inventory's case-folded file kind.

Fixes #7623
2026-10-29 13:43:55 +08:00
RRFZ 4fbce5c122 fix(cli): reject empty IPS and PE import targets before resolution (#7963)
inspect-apple-ips and inspect-pe-imports were the two commands in the
binary diagnostics group whose positional target was still a plain
string. An empty argument passed CLI validation, was resolved to the
working directory, and failed later as a non-file input, unlike their
siblings (inspect-elf-notes, inspect-pe-certificates and others) that
already reject it at validation.

Declare both targets with the shared nonempty, NUL-free local path
schema the rest of the file uses. Explicit "." is unchanged.

Fixes #7421
2026-10-29 13:43:25 +08:00
ShuaixinHuang 35ea02d27e fix(xml): reject ambiguous namespace attribute identities (#7991) 2026-10-29 13:38:37 +08:00
吴佳浩Alben 2bfd84b2c8 fix(javascript): emit no fork when a literal stdio array omits the IPC channel (#7992)
* fix(javascript): emit no fork when a literal stdio array omits the IPC channel

Node's fork() requires an explicit stdio array to carry the IPC channel:

    if (!ArrayPrototypeIncludes(options.stdio, 'ipc'))
      throw new ERR_CHILD_PROCESS_IPC_REQUIRED('options.stdio')

The throw is synchronous, before any child process exists, but the analysis
reported a resolved fork with stdioMode "array" — byte-identical to the valid
`[..., "ipc"]` form — which projects to a child-process node, a resolved spawns
relation and resolved connects-stdio.

Measured on Node 24.22.1:

    fork({stdio: ["inherit","inherit","inherit"]}) -> THROWS ERR_CHILD_PROCESS_IPC_REQUIRED
    fork({stdio: ["pipe","pipe","pipe"]})          -> THROWS ERR_CHILD_PROCESS_IPC_REQUIRED
    fork({stdio: ["ipc"]})                         -> SPAWNED connected=true
    fork({stdio: ["inherit","inherit","inherit","ipc"]}) -> SPAWNED connected=true
    fork({stdio: "pipe"})                          -> SPAWNED connected=true
    spawn({stdio: ["inherit","inherit","inherit"]})-> SPAWNED connected=false

A string stdio is normalised with "ipc" appended, so only the array form can omit
it. The same array is valid for spawn, which has no IPC requirement.

Drop a fork candidate only when its stdio array is fully literal and provably
lacks "ipc"; a spread or a non-literal element may still supply the channel and
stays a candidate.

* chore: retrigger title and readiness checks after the title was corrected
2026-10-29 13:38:29 +08:00
d39b3000ec feat(artifacts): inventory and extract U-Boot FIT images (#7771)
* feat(artifacts): inventory and extract U-Boot FIT images

open_binary refused U-Boot Flattened Image Tree files as an unsupported
format, so inspect_artifact and extract_artifact could not list or
recover a FIT's kernel, devicetree, ramdisk and loadable images.

Recognize an FDT v16/v17 with a top-level /images node and parse it with
the existing parseDevicetree. Each /images child becomes an inventory
entry named images/<unit-name>.bin that extracts its stored bytes from
embedded data, data-offset (past the 4-aligned devicetree end) or
data-position (from the file start). Image format_metadata records the
declared type, arch, os, compression, load and entry; root metadata
records the description, timestamp and configurations.

crc32, md5, sha1, sha256, sha384 and sha512 hash nodes are verified in
one streamed pass per image; other algorithms are reported unverified.
Signatures are reported, not verified, and nothing is decompressed,
decrypted or executed. Data outside the file, overlapping or duplicate
image data, a missing or repeated data source and hash mismatches fail
closed. The devicetree is bounded by the fixed 16 MiB allowance;
external image data is streamed from disk.

Refs #7129

* fix(artifacts): bound FIT configuration references and suggest analysis only for plain images

* fix(artifacts): retain buffered FIT stream cancellation

* test(artifacts): gate FIT faults on the observed read phase

* fix(artifacts): verify FIT links and summary identities

* fix(artifacts): bound FIT diagnostics and retain unknown signatures

* fix(artifacts): compare FIT declarations and resolved data links

* fix(artifacts): admit FIT raw probes through the shared loader contract

* fix(artifacts): preserve FIT field availability independently

* fix(artifacts): isolate nested entry metadata from reader facts

---------

Co-authored-by: gensokyo-dev <[email protected]>
Co-authored-by: gensokyo-dev <342580529+users.noreply.github.com>
2026-10-29 13:33:26 +08:00
gensokyo-dev d157560d40 fix(cli): reject empty Evidence file arguments (#7988) 2026-10-29 12:34:46 +08:00
morluto 429355ca4d fix(ci): repair native fixture and unused export 2026-10-29 11:29:10 +08:00
gensokyo-dev 50b2ab137f fix(browser): preserve DOM length units in captures and comparisons (#7971)
* fix(browser): declare DOM node value length units

* fix(browser): preserve unknown DOM length comparisons
2026-10-29 11:27:01 +08:00
gensokyo-dev cf9f010dcd feat(managed): filter and project retained member views (#7968)
* feat(managed): filter and project retained member views

* test(managed): guard relationship endpoint filter semantics
2026-10-29 10:39:34 +08:00
morluto c19f13ca03 fix(setup): preserve YAML annotations during refresh (#7944)
* fix(setup): preserve YAML annotations during refresh

* fix(setup): preserve yaml argument comment ownership
2026-10-29 10:12:09 +08:00
morluto 62ce357f16 fix(artifacts): preserve known metadata without content hashes (#7932)
* fix(artifacts): preserve known metadata without content hashes

* fix(artifacts): keep missing relation projections unknown
2026-10-29 10:10:41 +08:00
morluto 953a7689df fix(uninstall): preserve layered OpenCode registrations (#7969)
* fix(uninstall): preflight layered OpenCode fallback

* fix(uninstall): preserve inherited foreign registration facts

* fix(uninstall): preflight legacy OpenCode layer removal
2026-10-29 10:07:27 +08:00
morluto 3dcb40dc26 fix(uninstall): protect ZCode fallback registrations (#7970)
fix(uninstall): preserve inactive ZCode fallback servers
2026-10-29 10:05:35 +08:00
morluto 7b9bcf724f style: fix native documentation and test formatting 2026-10-29 10:02:22 +08:00
gensokyo-dev 7ca216a266 fix(docs): restore translated offline provider ownership notes (#7964) 2026-10-29 09:38:51 +08:00
morluto 419a211304 fix(cli): preserve caller paths in format inspections (#7855)
* fix(cli): preserve caller paths in format inspections

* fix(cli): retain caller path on partial evidence

* test(cli): preserve caller path in adapter parity checks

* test(rust): account for retained caller path

* fix(wasm): compare shared cli and mcp evidence
2026-10-29 09:26:22 +08:00
morluto 63f05d1cad fix(javascript): preserve uncertainty for unexamined sources (#7911)
* fix(javascript): preserve uncertainty for unexamined sources

* fix(javascript): compare observed package parsing status
2026-10-29 09:25:25 +08:00
morluto 95f0625781 fix(javascript): preserve uncertain with-scope member writes (#7914)
* fix(javascript): preserve uncertain with-scope member writes

* fix: retain nested initializer candidates

* fix(javascript): admit initializer values in worker transport

* fix(tests): remove duplicate MCP test imports
2026-10-29 09:23:34 +08:00
morluto 611c30cb20 fix(browser): deduplicate scenario coverage guidance (#7933)
* fix(browser): deduplicate scenario coverage guidance

* style(tests): fix CI formatting
2026-10-29 09:23:22 +08:00
morluto 78a1e1956e fix(pcap): validate selected resource limiter before capture (#7947)
* fix(pcap): validate selected resource limiter before capture

* fix(pcap): verify limiter capabilities and preserve probe output
2026-10-29 09:23:07 +08:00
morluto 59a895a193 fix(electron): retain unknown external module ownership (#7950) 2026-10-29 09:20:53 +08:00
morluto 3536ea2f49 fix(discovery): report debugger start host restrictions (#7965) 2026-10-29 09:20:33 +08:00
morluto 70a8325c38 fix(setup): preserve existing configuration mode (#7942) 2026-10-29 08:59:56 +08:00
morluto 9e1a1e700a fix(cli): prevent mcp discovery from registering clients (#7919)
* fix(cli): prevent mcp discovery from registering clients

* fix(cli): use shared output parsing for discovery errors
2026-10-29 08:57:38 +08:00
morluto 33d6975749 fix(certificates)!: disclose undecoded unsigned attributes (#7920)
* fix(certificates): disclose undecoded unsigned attributes

* test(certificates): use parser-owned limitation text
2026-10-29 08:56:07 +08:00
morluto 0386efd1e1 fix(pcap): retain producer contradiction diagnostics (#7937)
* fix(pcap): retain producer contradiction diagnostics

* test(pcap): align DNS fixture with empty captures
2026-10-29 08:43:14 +08:00
morluto c92322b473 fix(process): await Swift frontend lifetime pipe (#7948) 2026-10-29 08:43:04 +08:00
morluto 0448f318e6 fix(outputs): use neutral destination diagnostics (#7949) 2026-10-29 08:42:56 +08:00
morluto 640e19d79d fix(native)!: own Mach-O load commands in binary reader (#7952)
* fix(native): retain selected Mach-O slice identity

* fix(native)!: own Mach-O load commands in binary reader

* fix(native): preserve malformed Mach-O and image base limits

* fix(native): preserve leading BOM in Mach-O names

* test(native): update Mach-O provenance verification

* fix(native): retain completed Mach-O inspection on cleanup failure

* fix: bound Mach-O projected section output

* fix(native): own retained Mach-O command bytes

* fix(native): retain Mach-O outcomes on final cancellation

* fix(cli): preserve caller path in partial evidence

* fix: reserve Mach-O projection envelope budget
2026-10-29 08:37:36 +08:00
RRFZ 6db024dc96 fix(cli): reject empty native and managed targets before resolution (#7956)
Local file commands in the core binary, native, managed and native-tool
CLI groups declared their positional target as a plain string. An empty
argument therefore reached path admission, where it resolved to the
working directory, as docs/cli.md says it never should.

Declare those targets with the shared nonempty, NUL-free local path
schema already used by analyze, so the CLI rejects them as a
VALIDATION_ERROR naming the field before any analysis runner is called.
Explicit "." is unchanged.

Fixes #7436
Fixes #7404
2026-10-29 08:31:12 +08:00
吴佳浩Alben 4671947c97 test(firmware): pin the staging ceiling at the request boundary (#7775)
* test(firmware): exercise the staging ceiling through the emitted refusal

The ceiling recovery added in #6971 was covered through the wording helper only, so a wiring change that passed the schema ceiling where the selected value belongs, or that dropped the remediation, would have stayed green.

Adds boundary coverage that calls inventoryFirmwareOutput itself: a sparse file reaches the real byte ceiling without storing the bytes and asserts the projected refusal carries the ceiling recovery, and a one-byte tree below the ceiling asserts the raise advice. Verified red on both regressions — passing the schema ceiling for the selected value fails the below-ceiling case, and restoring the single-form remediation fails both.

* test(firmware): compare the emitted recovery with its owner

The wiring test matched three phrases of the emitted remediation, so an ad-hoc or truncated action that kept those phrases would still pass while the emitted recovery had diverged from firmwareStagingBudgetRemediation.

Assert exact equality with the owner's output for the selected value in both cases instead. Verified red: replacing the emitted action with a divergent sentence that keeps the ceiling phrases now fails both cases, where the phrase matching passed.

* chore: retrigger title and readiness checks after the title was corrected

* test(firmware): drive the staging ceiling through the request boundary

greptile and codex both flagged that the ceiling tests called
inventoryFirmwareOutput directly, so they would still pass if request parsing or
the provider wiring dropped or replaced max_output_bytes.

Add a request-level test that records the parsed request a provider receives:
the caller's max_output_bytes arrives unchanged at the schema ceiling and below
it, the documented default applies when omitted, and a budget above the schema
maximum is rejected before the provider runs. That is the wiring the previous
tests assumed rather than asserted.
2026-10-29 08:24:10 +08:00
吴佳浩Alben b7442c1958 fix(javascript): match resource release methods to the acquired handle (#7773)
* fix(javascript): match resource release methods to the acquired handle

Every acquisition family admitted every release method, so `h.close()`,
`h.destroy()` and `h.end()` each resolved as a complete release of whatever the
binding held. Node exposes a different subset per acquisition, and the rejected
pairs throw at the call site instead.

Measured on Node 24.22.1:

| acquisition | value | release members |
| --- | --- | --- |
| `fs.openSync` | number | none |
| `fs.open` (callback) | undefined | none |
| `fs.createReadStream` | ReadStream | `close`, `destroy` (`end` is the byte-offset field) |
| `fs.createWriteStream` | WriteStream | `close`, `destroy`, `end` |
| `fs/promises.open` | FileHandle | `close` |
| `net.connect` | Socket | `destroy`, `end` |
| `tls.connect` | TLSSocket | `destroy`, `end` |

So `fs.openSync(...)` + `fd.close()`, `createReadStream(...)` + `.end()`,
`net.connect(...)` + `.close()` and the FileHandle cases emitted a `releases` /
`resolved` fact for a call that throws.

Carry the specifier with each acquisition candidate, list the release methods
each pair actually has, and emit no release when the pair is not one of them. A
release stays `complete` only when the binding held exactly one acquisition and
that acquisition admitted the method.

`tls.createConnection` is not a Node export at all: `'createConnection' in
require('node:tls')` is false and the ESM import does not link. Drop it from the
table so a `tls.createConnection` call yields no acquisition.

* chore: retrigger title and readiness checks after the title was corrected

* fix(javascript): cover a mixed-family binding before completing a release

greptile asked for the mixed-family case: a binding that can hold either a
FileHandle or a socket, then calls close(). The FileHandle is the only linked
acquisition and the release stays partial.

That case also showed the `candidates.length === 1` guard was dead: an
acquisition of another family is not in `linked`, so `holdsOnlyAcquisitions`
already returns false for it and the release already stayed partial without the
guard. Removing the guard and keeping the test means the behaviour is now pinned
by a test rather than by two overlapping conditions.
2026-10-29 08:23:53 +08:00
Ha1baraA1 a965cbab06 fix(ghidra): omit duplicate load-image result (#7777)
* fix(ghidra): omit duplicate load-image result

* docs(mcp): describe load-image evidence projection
2026-10-29 08:23:38 +08:00
64d282b0a6 fix(process): normalize descendants of slash-spelled directory roots (#7803)
* fix(process): normalize descendants of slash-spelled directory roots

A working directory or observation path ending in / or /. kept its
trailing separator as the alias, so descendant paths never met the
delimiter lookahead and stayed literal. Strip those spellings before
building aliases and version the path normalization contract as v3.

Fixes #7584

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(process): normalize filesystem root descendants

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-29 08:23:19 +08:00
RRFZ 30936d7596 fix(managed): report member signature issues at artifact offsets (#7879)
Field, MethodDef and MemberRef signature issues reported the invalid operand's offset inside its blob, while local signature issues in the same coverage array used artifact file offsets. Translate both through one helper that adds the blob's artifact base.

Fixes #7385
2026-10-29 08:23:04 +08:00
ShuaixinHuangandmorluto 3a46047aa7 fix(pe): reject surrogate code units in BMPString names (#7817)
* fix(pe): reject surrogate code units in BMPString names

* chore: preserve base browser imports

---------

Co-authored-by: morluto <[email protected]>
2026-10-29 08:20:32 +08:00
morluto 7c5700542e test(reference): pin excluded package main resolution (#7941) 2026-10-29 08:18:13 +08:00
morluto ef9ab91e42 fix(il2cpp): validate retained declaring type relationships (#7946) 2026-10-29 08:16:57 +08:00
morluto 5147b6e306 fix(environment)!: attribute source errors to caller fields (#7900)
* fix(environment): attribute source file errors to caller fields

* style(environment): format source admission tests
2026-10-29 08:12:09 +08:00
morluto c7722c8eeb fix(cli): honor token controls for builtin documents (#7897) 2026-10-29 08:11:19 +08:00
morluto b0b25ad93e fix(ida): report registration timeout bounds (#7893) 2026-10-29 08:11:07 +08:00
morluto 3a512303d9 fix(cli)!: refuse lossy text output (#7852)
* fix(cli)!: refuse lossy text output

* fix(cli): retain failure identity on text refusal

* fix(cli): check failed TOON token windows

* test(cli): bound keyed archive case duration
2026-10-29 08:09:49 +08:00
morluto 794907fa3d fix(javascript): trace boundary results to assigned bindings (#7912) 2026-10-29 07:58:57 +08:00
morluto 2129c17925 fix(native): retain selected Mach-O slice identity (#7940) 2026-10-29 07:57:19 +08:00
morluto 0179d94420 fix(browser): disclose opaque redirect coverage gaps (#7943) 2026-10-29 07:57:00 +08:00
Hasan Zayni bbd4989654 fix(config): treat a blank analyzer override as absent beside an existing Ghidra project (#7923)
REA_GHIDRA_DISABLED_ANALYZERS parses a blank or comma-only value to no override, but the existing-project conflict check tested the raw value. MCP startup exited and doctor reported config_drift for an input that selects nothing. The check now uses the parsed value.

Fixes #7422
2026-10-29 07:56:50 +08:00
Hasan Zayni 32b3722d2f fix(ghidra): report unusable existing-project selections as REA_GHIDRA_PROJECT_PATH configuration errors (#7922)
A selected .gpr marker that does not exist and a target that existing-project mode cannot serve both surfaced as execution_failure with no setting and a doctor action that cannot help. Both now return configuration_invalid naming REA_GHIDRA_PROJECT_PATH. The ENOENT diagnostic of the missing marker is kept.

Fixes #7417
Fixes #7416
2026-10-29 07:56:38 +08:00
morluto 844bb46351 fix(javascript): retain Electron switch conditions (#7910)
* fix(javascript): retain Electron switch conditions

* fix(javascript): bound switch path traversal
2026-10-29 07:56:15 +08:00
morluto 086abf3996 fix(javascript): distinguish bundled script locations (#7909) 2026-10-29 07:56:06 +08:00
morluto 9b4546276c fix(browser): preserve frame tree root identity (#7915) 2026-10-29 07:55:57 +08:00
morluto f256492ff3 fix(apple): recognize AppKit cell ownership (#7916) 2026-10-29 07:55:05 +08:00
morluto 63491645fd fix(ledger): withhold readiness for unresolved evidence (#7928) 2026-10-29 07:54:41 +08:00
Hasan Zayni a4bd924772 fix(call-path): reject incompatible coordinate mappings (#7930)
* fix(call-path): reject incompatible coordinate mappings

Use the existing provider-owned coordinate context comparison before composing dossiers. Preserve same-mapping profiles and missing-dossier uncertainty. Fixes #7345.

* test(call-path): assert the structured rejection instead of its wording

docs/testing.md asks for structured error checks. Assert the issue path and reason, and keep the MCP category and code.
2026-10-29 07:54:09 +08:00
morluto 66f5b650d9 fix(apk): explain unknown signer comparison (#7927) 2026-10-29 07:53:38 +08:00
morlutoandgreptile-apps[bot] 1631dcb09a docs: include Kuna in native provider guidance (#7929)
* docs: include Kuna in native provider guidance

* docs(i18n): include Kuna in native provider guidance

* docs: align provider guide links

* Update README.md

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* docs: align provider links and translated formatting

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-10-29 07:53:28 +08:00
morluto 42d5425417 fix(browser): enforce initial navigation default deadline (#7934) 2026-10-29 07:53:18 +08:00
hhangandhhang 07dfd12613 fix(pe): reject non-MZ inputs before image inspection (#7709)
Co-authored-by: hhang <[email protected]>
2026-10-29 07:45:32 +08:00
吴佳浩Alben f1da7f7670 fix(javascript): read the spawn env option as Node reads it (#7713)
* fix(javascript): read spawn env as Node reads it

Node's normalizeSpawnArguments starts with `const env = options.env ||
{ ...process.env }`, so a falsy env is replaced by a copy of the parent
environment. A child started with env: null, undefined, 0, "" or false
therefore inherits everything, exactly as if no env were passed.

REA tested the key's presence alone, so every one of those reported
environment_supplied: true and the graph emitted a resolved supplies-env
relation. The presence test also missed the opposite direction: an env
supplied through an inline object spread reported false although Node uses
it.

Read the declared value the way stdioMode already reads stdio: an explicit
property whose statically known value is falsy does not supply an
environment, and an inline spread that carries env does.

Verified on Node v24.22.1 with a child that prints a parent marker variable:
no options, env: null, undefined, void 0, 0, "" and false all print the
marker, while env: {} prints nothing and env: { A: "1" } prints only that.

* fix(javascript): read falsy numeric literals as Node does

greptile flagged that environmentSupplied still reported a supplied environment for
`env: -0` and `env: 0n`: staticJavaScriptTruthiness recognized neither form, so it
returned undefined and `!== false` turned that into true. Node's
normalizeSpawnArguments uses `options.env || { ...process.env }`, so both inherit.

Extend the shared truthiness reader to cover a BigInt literal and a negated numeric
literal, and add regression cases for `-0`, `0n` and `0.0`.

The reader is shared with the route scan and the state tracker; both treat
`undefined` as "unknown", so a more precise `false` only strengthens them.
2026-10-29 07:45:22 +08:00
Wenyu Chiou 3142f7b0dd fix(adb): align CLI selector schemas with canonical inputs (#7722)
* fix(adb): align CLI selector schemas with canonical inputs

Reuse canonical selector constraints for ADB CLI admission and cover schema, parser, and inert provider boundaries. Independent source review approved tree bc722f8d1b1f8d014be29533e6845c6f897d5918; full contribution checks remain pending.

* test(adb): expect CLI serial validation refusal

Independent review approved staged diff 35418e6994339af838b490be51278fd41b9f8e3e. Focused serial refusal test, lint, and formatting passed with existing dependencies.

* test(adb): assert CLI selector validation stage

Independent review approved staged diff a1164a8dcf1df1f0d60323d7a53a69ee2bfdffeb. Focused dispatch tests, targeted lint and formatting passed using existing dependencies.

* fix(adb): retain safe selector validation constraints

Independent review: review_ci_delta APPROVE for diff 18748a3b4b112dc96b95f7c1099bd479e1d1587b. Focused tests, typecheck and targeted lint passed; the aggregate check remains limited by a matching baseline Knip finding.
2026-10-29 07:44:43 +08:00
ShuaixinHuangandmorluto fc24b08851 feat(artifacts): read Zstandard ZIP members (#7780)
* feat(artifacts): read Zstandard-compressed ZIP members

* fix(artifacts): classify ZIP dictionary failures

---------

Co-authored-by: morluto <[email protected]>
2026-10-29 07:44:10 +08:00
ShuaixinHuang edc908af58 fix(xml): reject ambiguous namespace attribute identities (#7785) 2026-10-29 07:38:46 +08:00
PARK HYEONMIN (박현민) b4923f85c5 docs(ghidra): count 27 read-only operations in current guides (#7794)
The inventory registry gained read_binary_inventory_summary, so the
read-only inventory is fifteen inventory and twelve function operations.
Update the adapter summary and the Windows lane descriptions to match the
registries the Windows verifier derives its coverage from. The historical
Windows verification record keeps its observed 26-operation count.

Fixes #7611
2026-10-29 07:38:33 +08:00
ShuaixinHuang 9ac9f91ab5 fix(firmware): validate Intel HEX start-record offsets (#7806) 2026-10-29 07:37:39 +08:00
ShuaixinHuang c2cc7e6eb0 test(cli): cover literal Markdown heading output (#7866) 2026-10-29 07:37:20 +08:00
morluto a001231256 fix(adb)!: report local filesystem admission failures (#7885)
* fix(adb)!: report local filesystem admission failures

* test(adb): assert filesystem error provenance
2026-10-29 07:37:08 +08:00
RRFZandmorluto 8c83886891 fix(pe): report exhausted certificate decoder allowances as resource limits (#7881)
* fix(pe): report exhausted certificate decoder allowances as resource limits

A PKCS#7 payload that exhausted the fixed 64 KiB decoded-text or 16,384-value ASN.1 allowance was refused as malformed input with advice to correct request fields. Keep the allowance and limit on the decoder failure and report it as a nonretryable resource_constraint with fixed-allowance recovery.

Fixes #7531

* test(pe): cover certificate allowances through MCP

---------

Co-authored-by: morluto <[email protected]>
2026-10-29 07:36:56 +08:00
morluto fd297b1b17 fix(apple): preserve bounded archive diagnostics (#7890)
* fix(apple): preserve bounded archive diagnostics

* test(apple): assert diagnostic facts without freezing prose
2026-10-29 07:36:29 +08:00
morluto 16cfe30dab fix(setup): identify invalid launch environment overrides (#7899)
* fix(setup): identify invalid launch environment overrides

* test(setup): cover merged environment recovery
2026-10-29 07:34:43 +08:00
morluto 473cfa36b8 fix(evidence)!: distinguish inline records from bundles (#7895)
* fix(evidence): distinguish inline records from bundles

* fix(evidence): preserve bundle integrity failure reasons
2026-10-29 07:34:31 +08:00
morluto 5082b50f07 fix(decompile): retain limitations across failed resume (#7913) 2026-10-29 07:30:44 +08:00
morluto 31c028f496 fix(mcp): align retained view handoff guidance (#7926) 2026-10-29 07:29:44 +08:00
Hasan Zayni e0719cffa4 fix(ledger): honor every selected fixture proof (#7931)
Prevent a passing fixture entry from hiding applicable failures in another selected entry. Fixes #7412.
2026-10-29 07:27:57 +08:00
morluto 21b192706d docs(website): correct client and IDA support guidance (#7918)
* docs(website): correct client and IDA support guidance

* style(website): format setup support guidance
2026-10-29 05:37:06 +08:00
morluto 286629b570 fix(test): remove duplicate unknown session imports (#7917) 2026-10-29 05:30:05 +08:00
morluto 50d731d456 fix(tests): remove duplicate MCP test imports 2026-10-29 05:19:41 +08:00
morluto f9acfdcf49 fix(cli): retain committed evidence receipts on output failure (#7906) 2026-10-29 05:11:02 +08:00
morluto 9b880e0e3e fix(setup): report concurrent skill destination changes (#7898)
* fix(setup): report concurrent skill destination changes

* fix(setup): avoid rollback after exclusive link refusal
2026-10-29 05:10:45 +08:00
morluto 76c7698ac9 fix(cli)!: preserve native value input diagnostics (#7889) 2026-10-29 05:10:28 +08:00
morluto 83cd1e04c9 fix(javascript)!: report ambiguous artifact paths (#7864)
* fix(javascript): report ambiguous artifact paths

* fix(javascript): retain unavailable colliding sources
2026-10-29 05:10:18 +08:00
morluto 29945d435d fix(process): preserve availability when macOS ownership preparation fails (#7856)
* fix(process): preserve availability when macOS ownership preparation fails

* test(process): verify affected macOS provider availability
2026-10-29 05:10:04 +08:00
morluto 6c205d8a79 fix(evidence): align bundle receipts and conflict recovery (#7849) 2026-10-29 05:09:54 +08:00
morluto 4e663beeb8 fix(javascript): retain guards after labelled breaks (#7841)
* fix(javascript): retain guards after labelled breaks

* fix(javascript): bound labelled exit inspection

* fix(javascript): preserve local break completion

* fix(javascript): avoid exits through unknown control flow

* fix(javascript): retain guards after bounded jump scan
2026-10-29 05:09:45 +08:00
morluto 1e088c19ad fix(environment)!: report recorded reads and target uncertainty (#7834)
* fix(environment)!: report recorded reads and target uncertainty

BREAKING CHANGE: Environment state and coverage can report method-replay for non-GET safe reads; exhaustive reason consumers must handle it.

* docs(environment): include safe-method replay reason
2026-10-29 05:09:31 +08:00
morluto cc5a4062ff fix(browser): preserve unknown WebMCP comparison facts (#7833) 2026-10-29 05:09:22 +08:00
morluto 6c76a7ffb0 fix(wasm): retain core facts with invalid custom names (#7822)
* fix(wasm): retain core facts with invalid custom names

* fix(wasm): retain objdump output on parse failure
2026-10-29 05:08:41 +08:00
morluto 114731eb1e fix(process): retain uncertain cleanup ownership (#7845)
* fix(process): retain uncertain cleanup ownership

* fix(process): retain moved members through cleanup retry

* test(process): reconstruct ownership ledger in cleanup fixture
2026-10-29 05:08:29 +08:00
morluto 583a316e11 fix(macho): preserve POSIX app executable names (#7888) 2026-10-29 05:08:17 +08:00
morluto f6380282fb fix(web)!: retain invalid browser selection (#7903)
fix(web): retain invalid browser selection
2026-10-29 05:08:02 +08:00
morluto 2aa0d45e13 fix(mcp): guide oversized unknown recovery (#7876) 2026-10-29 05:07:35 +08:00
morluto 5f146b3b19 fix(ida): retain selected endpoint on connection failures (#7894)
* fix(ida): retain selected endpoint on connection failures

* fix(ida): redact encoded endpoint credentials and preserve causes
2026-10-29 05:07:02 +08:00
morluto 553f19590f fix(harmony): exclude symlinks from unavailable files (#7886) 2026-10-29 05:05:35 +08:00
morluto e03ff93913 fix(frida): retain selected discovery endpoint on failure (#7892) 2026-10-29 05:04:53 +08:00
morluto 78a350e0b6 fix(skill): clarify packet capture tool selection (#7901) 2026-10-29 05:04:35 +08:00
morluto 52617bd50e fix(model): recognize safetensors ZIP signature collisions (#7816) 2026-10-29 04:59:25 +08:00
morluto 675c73fb4d fix(apple): preserve post-table plist objects (#7820) 2026-10-29 04:59:14 +08:00
morluto bd687bbc40 fix(ghidra)!: distinguish unlisted instruction addresses (#7823)
* fix(ghidra)!: distinguish unlisted instruction addresses

BREAKING CHANGE: Ghidra now returns not-in-listing for in-memory addresses without listed instructions or defined data. Consumers matching the former undecodable value must handle the new status.

* fix(ghidra): invalidate snapshots with old instruction status

* test(ghidra): update raw profile commitment goldens
2026-10-29 04:59:04 +08:00
morluto b0880d660f fix(qlog): exclude hidden custom events from incomplete facts (#7825) 2026-10-29 04:58:53 +08:00
morluto 2dd9a3092e fix(artifacts): extract readable inventoried entries (#7827)
* fix(artifacts): extract readable inventoried entries

* test(artifacts): align directory omission coverage
2026-10-29 04:58:43 +08:00
morluto 5c60720ad7 fix(pe): distinguish bounded imphash name reads (#7830) 2026-10-29 04:58:33 +08:00
morluto 9b7c2bb1ac fix(javascript): retain anchored route constants under reserved prefixes (#7838) 2026-10-29 04:58:22 +08:00
morluto 0759fb9ad5 fix(build): explain unsupported source loader runtimes (#7839) 2026-10-29 04:58:11 +08:00
morluto 46c457f74c docs(ghidra): fix DOL guide PowerPC link (#7857) 2026-10-29 04:57:59 +08:00
morluto 1b636c890f fix(macho): retain inspection when vtool rejects universal container (#7865)
* fix(macho): retain inspection when vtool rejects universal container

* test(macho): assert facts retained after vtool refusal
2026-10-29 04:57:22 +08:00
morluto fe52ea12c3 fix(evidence): explain fixed analysis view page recovery (#7860)
* fix(evidence): explain fixed analysis view page recovery

* fix(evidence): explain unpublished view recovery
2026-10-29 04:55:53 +08:00
morluto 00bd92c56e fix(ida): align workspace discovery with readiness (#7863) 2026-10-29 04:55:44 +08:00
gensokyo-devandEntrpi 37827af591 feat(artifacts): compare inventories from Evidence sources (#7869)
* feat(artifacts): compare artifacts by Evidence reference and from the CLI

compare_artifacts made agents send back the complete inventory Evidence
that REA already retains, and the CLI had no artifact comparison.

Each side of compare_artifacts now takes exactly one of: complete inline
Evidence (unchanged), {kind: "retained-evidence", evidence_id}, or
{kind: "evidence-file", path, evidence_id?}. The two references are the
sources inspect_analysis_view accepts; both tools now compose one
definition in evidenceReference.ts. A summary still resolves to its exact
retained parent, and every source form gives the same comparison Evidence.
An unresolvable retained reference is refused with a typed missing
reference error.

The application layer owns source resolution and the comparison Evidence,
so MCP and the new `rea compare-artifacts` command share one workflow.
readEvidenceFileSource reports bundle-selection refusals at the caller's
own field path.

* refactor(artifacts): resolve compare_artifacts sides like compare_functions

compare_functions, compare_wasm_interfaces and the JavaScript application
comparisons name each side with evidenceInputSchema and resolve it with
resolvePairedEvidenceRequest. compare_artifacts reached the same result
for inline and retained sides through its own dispatch.

evidenceSourceInputSchema now extends evidenceInputSchema with the
Evidence-file reference, and resolvePairedEvidenceSources sends inline and
retained sides to the same resolveEvidenceInput and file sides to the
shared Evidence file reader. compare_artifacts uses both, so the forms it
shares with compare_functions are parsed and resolved by one owner. The
advertised input schema is unchanged.

* docs(cli): point rea compare to compare-artifacts for inventory contents

rea compare (compare_bundles) compares records by Evidence identity and
explicit pairs and never reads artifact contents, so two build
inventories stay unresolved there. Its help and the CLI guide now name
compare-artifacts for that comparison.

* fix(artifacts): resolve summary parents within Evidence source bundles

* perf(evidence): reuse file-owned immutable authentication proofs

* test(evidence): inject failures at both authentication boundaries

---------

Co-authored-by: Entrpi <[email protected]>
2026-10-29 03:12:03 +08:00
gensokyo-dev 2f3c71f39e docs(errors): align byte entropy recovery catalog (#7884) 2026-10-29 03:03:04 +08:00
RRFZ b75419b61e test(firmware): keep producer fixtures within supported Node limits (#7048)
* test(firmware): bound fixture hashing and avoid Node startup warnings

* test(firmware): apply the Wasm flag only on Node 22
2026-10-29 02:42:21 +08:00
gensokyo-dev 8f9af920ef fix(pcap): redact HTTP credentials in failed capture diagnostics (#7871)
Project bounded JSON diagnostics using shared URI roles and source spans.
Keep complete parser input unchanged and compute safe diagnostics lazily.
Preserve byte facts, error classification, path data and cleanup ownership.
Reuse JSON escape-coordinate mapping with IDA diagnostics.

Fixes #7812

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-28 18:14:22 +00:00
Rudy Mizrahi Celekli e23cb3b240 fix(browser): preserve script exports with filesystem-unrepresentable paths (#7526)
fix(browser): isolate unrepresentable script export paths

Signed-off-by: Rudy Celekli <[email protected]>
2026-10-29 02:13:54 +08:00
gensokyo-dev 4b0ff68e2e fix(browser): retain prior-hop response facts in session timelines (#7807)
* fix(browser): retain prior-hop response facts in session timelines

* fix(browser): share response URL classification

* fix(browser): preserve malformed response status failures

* fix(browser): account for filtered redirect response coverage

* test(browser): supply prior response URLs in redirect fixtures

* fix(browser): retain malformed orphan response status coverage
2026-10-29 02:04:15 +08:00
Jiakai Xu 19032204aa fix(javascript): resolve relative ESM backslash paths (#4323)
Normalize raw URL separators after admitting an original relative ESM
request, before artifact path validation and root confinement. Preserve
the authored declaration and the existing encoded-separator checks.

Retain Node-backed static and dynamic loader controls and compare the
application graph with the historical importer already present on main.
Narrow PR #4323 to this remaining case after the upstream #4269 fix.

Signed-off-by: Jiakai Xu <[email protected]>
2026-10-29 02:03:00 +08:00
Dragolone f19436c156 fix(artifacts): split U-Boot script uImages on their size table (#7805)
U-Boot's mkimage writes the multi-file size table for script images
(`mkimage -T script`, the boot.scr format) exactly as it does for multi
images, `mkimage -l` lists the script as "Image 0", and the `source`
command skips the table before running the script ("scripts are just
multi-image files with one component", boot/image-board.c).

The uImage reader parsed the table only for IH_TYPE_MULTI, so a script
image reported sub_image_count 0 and exposed only payload.bin, whose
first bytes are the binary size table rather than the script text.

Treat IH_TYPE_SCRIPT like IH_TYPE_MULTI: parse the same bounded table,
expose image-<n>.bin components and report the size-table limitation.
payload.bin is unchanged. A script payload without a valid table now
fails closed, as a multi image already does.
2026-10-29 01:57:09 +08:00
morluto 44331d04d2 fix(browser): retain launch failure diagnostics (#7826) 2026-10-29 01:56:39 +08:00
morluto 0a272d5cf5 fix(capture): bound preview headlines by source format (#7832)
* fix(capture): bound preview headlines by source format

* test(capture): cover scalar HAR preview extensions
2026-10-29 01:56:07 +08:00
morluto 0747e46401 fix(cli): recognize integrity failures with partial observations (#7836) 2026-10-29 01:55:57 +08:00
morluto 183e2e2d1e fix(il2cpp): validate structural record extents (#7861) 2026-10-29 01:55:47 +08:00
morluto 5119d08daf fix(web): preserve portable captured script paths (#7862) 2026-10-29 01:55:38 +08:00
morluto 1e421242b9 fix(javascript): preserve uncertainty for incomplete runtime captures (#7854) 2026-10-29 01:53:03 +08:00
morluto 5bef2b48b6 fix(input)!: classify unresolvable source paths (#7847) 2026-10-29 01:52:34 +08:00
morluto e79ad6ca8e fix(jeb): preserve selected endpoint in failures (#7835)
* fix(jeb): preserve selected endpoint in failures

* fix(jeb): retain endpoint on typed failures
2026-10-29 01:30:24 +08:00
morluto 128c2cf632 fix(sqlite): report SQL statement resource allowance (#7829) 2026-10-29 01:30:08 +08:00
morluto aaf4d21068 fix(source-map): clarify policy and evidence provenance (#7828) 2026-10-29 01:29:59 +08:00
morluto aba158506b fix(javascript): preserve repeated native resolver calls (#7824) 2026-10-29 01:29:48 +08:00
morluto 477f63ae21 fix(session)!: classify unavailable snapshot prerequisites (#7837)
fix(session): classify unavailable snapshot prerequisites
2026-10-29 01:28:57 +08:00
morluto 60ab4da329 fix(cli): correct completion options and setup guidance (#7851)
* fix(cli): align MCP doctor completion with its options

* fix(cli): explain zsh completion initialization

* fix(cli): include launcher timing in doctor completion

* style(cli): format doctor completion schema
2026-10-29 01:28:04 +08:00
morluto f9e7571a3d feat(javascript): discover semantic call literals in feature traces (#7840)
* feat(javascript): discover semantic call literals in feature traces

* fix(javascript): bound retained call literals by transfer capacity

* test(javascript): align feature no-match diagnostic
2026-10-29 01:25:23 +08:00
morluto 685f6db960 fix(browser): preserve unknown CDP source coordinates (#7842) 2026-10-29 01:23:56 +08:00
morluto b21a975faf fix(update): distinguish launcher failures from registry errors (#7843) 2026-10-29 01:23:29 +08:00
morluto d49a1504ca fix(erlang): respect legacy atom table layout (#7844) 2026-10-29 01:23:17 +08:00
morluto 4109271bcb fix(process)!: reject unsupported one-column terminals (#7848)
* fix(process)!: reject unsupported one-column terminals

* test(process): exercise actual two-column resize
2026-10-29 01:23:02 +08:00
morluto a6295e433b fix(python): preserve code objects after STORE_SLICE (#7815) 2026-10-29 01:11:27 +08:00
morluto af1ccb6506 fix(android): preserve manifest component spelling (#7818) 2026-10-29 01:10:45 +08:00
morluto 7dbebb4e7d fix(browser): preserve prefixed XHTML link hints (#7819) 2026-10-29 01:10:36 +08:00
morluto dfa0689890 fix(process): preserve comparison uncertainty and attribution (#7853)
* fix(process): preserve comparison uncertainty and attribution

* fix(process): retain known file differences with unknown effects

* fix(process): preserve proven filesystem path differences

* fix(process): preserve trace and symlink differences
2026-10-29 01:01:16 +08:00
morluto 251e27ef3b fix(website): align Electron guide with downloadable source (#7858)
* fix(website): align Electron guide with downloadable source

* test(website): detect renderer example drift
2026-10-29 00:56:14 +08:00
Entrpiandgensokyo-dev 64196b08ca feat(artifacts): inventory and extract ESP32 firmware images (#7498)
* feat(artifacts): inventory and extract ESP32 firmware images

ESP32-family app and bootloader images (magic 0xE9) had no reader, so
open_binary refused OTA downloads, app partitions and bootloaders.

Add the esp-image container format behind inspect_artifact and
extract_artifact. A pure decoder reads each byte once and keeps only
fixed-size fields. Derived facts cover the chip, from a table cited to
ESP-IDF v6.1; segment classification as ESP-IDF's should_map and
should_load; checksum and appended SHA-256 results; app and bootloader
descriptors; Secure Boot v2 signature blocks, observed and unverified;
and undescribed trailing byte ranges. Truncation and undescribed bytes
make coverage unknown. ESP8266 images are refused with a specific
reason, and ciphertext stays unrecognized.

Add the format to every target, Evidence, snapshot, live-summary and
artifact vocabulary, document it, and add an optional verify:esp-images
lane that compares esptool-built images with esptool image-info and
espsecure signature-info-v2.

Refs #3615

* test(artifacts): run the ESP image lane on esptool v5.6.0

The lane compared descriptor fields only when esptool image-info printed
one, so a descriptor that REA reports and esptool does not print passed
without comparison. Compare the descriptor kind in both directions.

Record that the lane passed for all 13 images with esptool and espsecure
v5.6.0, the version the layout facts cite, as well as with 4.12.0.

* refactor(artifacts): define ESP image layout sizes once

The decoder and the derived facts each defined the segment-header,
appended-digest and flash-sector sizes, the erased-byte scan and the
offset formatter. Define them once with the other fixed-layout structures
and import them in both places. The signature slot count is the one
constant that drives the slot scan.

Correct the observedEnd comment: it is the end of the last chunk read.

* fix(artifacts): report ESP-IDF's segment length limit by chip

ESP-IDF's verify_segment_header rejects a segment of 16 MiB or more
unless the chip maps flash through 32-bit cache addresses
(SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP: ESP32-S3, P4, C5, C61, H4 and
S31 in v6.1). Record that capability in the chip table and add a
limitation for such segments; unknown chips get none.

`loaded` repeats should_load. It does not mean the bootloader accepts the
segment: verify_load_addresses still rejects one outside the chip's RAM,
which REA does not model. Say so in the docs, the skill reference and the
inventory limitation.

* test(artifacts): check ESP lane tools first and verify extraction

The lane started work before checking its tools, so a missing RISC-V
target, ld.lld, esptool or espsecure surfaced as a raw spawn or command
error. Check each one before building and name the variable to set. Warn
when esptool is not v5.6.0, the release the layout facts cite.

Assert each segment's class for the ESP32-C3 app, its variants and the
bootloader, as the Xtensa image already did. Extract the app and the
signed image through the CLI and compare every file with the bytes at
esptool's segment offsets or in the appended signature sector; the
source's SHA-256 must be unchanged and equal the reported root_sha256.

* docs(artifacts): state what the ESP image lane does not establish

The Verification section listed the lane's checks but not its gaps: only
ESP32-C3 and ESP32 images come from a real producer, no real project
build, OTA download or flash dump is inspected, no signature is verified,
and the lane does not run in CI.

Record the timing of the final lane run on esptool v5.6.0.

* fix(artifacts): compare ESP segment declarations

Segment entries hash only their data, so compare_artifacts reported a
segment that moved to another load address with the same bytes as
unchanged; only the image itself changed. Compare each segment's
load_addr and data_len as its declaration, as Node SEA and PyInstaller
members are compared, and count a changed declaration as a metadata
change, also when content is unavailable.

Header offsets are layout and the classification is derived, so neither
is compared.

* test(artifacts): run ESP lane commands as owned process trees

The lane ran its tools through execFile. A timeout killed only the direct
child, so a linker or assembler that Clang or GCC had started could keep
running while the lane removed its workspace. Run every command through
createVerifierCommands, check the tools inside withVerifierCleanup, and
remove the workspace only after commands.close() has stopped every tree;
a failed close keeps the workspace.

Only a nonzero exit now counts as a refusal or an expected esptool
failure; timeouts and spawn failures propagate. Supervising each command
roughly doubles the lane's run time.

* test(artifacts): cancel ESP decoding after its first decoded chunk

The cancellation test requested cancel or close on setImmediate, which
can land while the file is still being opened and checked, so it never
showed that decoding had started. It also passed against a reader that
ignored both requests while decoding. Acknowledge the decoder's first
chunk, then cancel or close, join the operation, and assert that no
later chunk reaches the decoder and that the reader ends closed.

* docs(artifacts): record which ESP metadata comparison ignores

Segments are compared by their declaration. The image's and the
signature blocks' format_metadata are not: every field comes from their
own bytes, which content comparison already covers, and a block's
image_digest_matches follows the image's content.

* docs(artifacts): state that ESP mmu_page_size is a base-2 logarithm

The app descriptor's mmu_page_size keeps ESP-IDF's name and value, the
MMU page size in log base 2 as esp_app_desc_t declares it, so 16 means
64 KiB. Say so in docs/esp-image.md and the schema comment; a reader
could otherwise take 16 as 16 KiB.

* fix(esp-image): retain member consumption and share lifecycle regressions

* test(artifacts): scope MCP catalogs and budget full-schema validation

* test(artifacts): verify compact output profiles and document bounded catalogs

* test(artifacts): close readers when cleanup-test admission fails

* test(artifacts): compare ESP image limitations with their owners

The decoder and reader tests froze complete limitation sentences, so a
harmless rewording failed them. The wording now has two owners:
ESP_IMAGE_LIMITATIONS in espImageFacts.ts, which the decoder, the inventory
and the reader use, and ESP_DESCRIPTOR_LIMITATIONS beside the descriptor
decoder. Tests compare delivered limitations with the owner, called with the
facts each case establishes (segment index, declared and available bytes,
offsets, chip, page range), next to the structured assertions they already
make. Delivered text is unchanged.

* test(esp-image): assert structured facts and owned guidance

* fix(esp-image): keep spi_flash_mode and descriptor fields before a truncated tail

ESP-IDF v6.1's esp_app_desc_t declares spi_flash_mode at byte 181, after
mmu_page_size, as the committed reference layout shows; the descriptor now
keeps it as stored. The decoder also required all 256 descriptor bytes,
though it reads none past byte 181, so a file ending in the reserved tail
lost the version, project, digest and revision facts it does hold. The app
descriptor now needs only its fields; the segment's truncation is reported
as before.

* test(esp-image): pin the P-192 public key digest to espsecure's layout

espsecure packs ECDSA signature blocks as "<BBBx32sB64s64s1031x" and
zero-pads a 48-byte P-192 point to 64 bytes, so the signature starts at
byte 101 for every SHA-256 curve. signature_info_v2 hashes sig_block[36:101]
and _digest_sbv2_public_key the curve ID with the padded point. No test built
a P-192 block; this one checks public_key_sha256 against that definition.

* fix(esp-image): keep each app descriptor field the file holds in full

A file can end anywhere inside the 256-byte esp_app_desc_t. The decoder
needed every field byte, so a cut at byte 176 dropped the version, project
and app_elf_sha256 it does hold. Once the 4-byte magic identifies an app
descriptor, each field is now kept when the file holds all of its bytes and
is null otherwise; observed_length records where the descriptor ends, so a
cut field is told apart from text that is not UTF-8. The fields after the
magic become nullable in the metadata schema.

* fix(esp-image): report a signature block whose image digest does not match

A CRC-valid Secure Boot v2 block can carry another image's digest. The
block recorded image_digest_matches false, but no limitation said so, unlike
a checksum or appended-SHA mismatch, so CLI and MCP summaries showed only
the generic unverified note. The mismatch is now a limitation; coverage
stays complete and signature_status stays unverified. The three other
signature-sector limitations move into ESP_IMAGE_LIMITATIONS with their
text unchanged, so all ESP image wording has one owner.

* refactor(esp-image): remove redundant descriptor byte guards

---------

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-28 23:18:22 +08:00
gensokyo-dev 6c895eeb8e fix(process)!: redact sensitive terminal echoes before retaining Evidence (#7804)
Seal sensitive terminal chunks before deferred rendering, apply one bounded
capture-local literal matcher, and retain exact redacted byte accounting.
Keep private input facts in explicit fields and separate comparison policies.
Retain distinct terminal failures once and verify structured refusal facts.

Fixes #7782

BREAKING CHANGE: sensitive interaction data is empty with sensitive and input_bytes fields instead of a byte-count placeholder. Sensitive raw_data is also redacted. Read input_bytes and recapture both comparison sides when migrating older private-input Evidence.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-28 14:39:34 +00:00
ShuaixinHuang 8f97a45483 fix(plist): end OpenStep comments at native line separators (#7793) 2026-10-28 22:23:16 +08:00
Dragolone 6fd5d347c7 fix(browser): ignore repeated CSP directives within one policy (#7798)
CSP3 parsing keeps the first directive of each name in a policy and ignores
later repeats; Chrome reports "Ignoring duplicate Content-Security-Policy
directive". parseCsp flattened every policy's directives into one stream, so
a header such as `script-src 'self'; script-src 'unsafe-inline'` reported the
ignored `'unsafe-inline'` directive as declared and counted nonces and hashes
from it. Track directive names per policy so only the effective directive is
retained, while the same name in separate comma-separated or repeated-field
policies is still listed once per policy.
2026-10-28 22:23:00 +08:00
ShuaixinHuang b14b94f0f5 fix(asn1): reject non-minimal OID subidentifiers (#7800) 2026-10-28 22:22:43 +08:00
Ysopwnableandgensokyo-dev 7b6d872a25 docs: celebrate 400,000 GitHub stars 🎉 (#7801)
Co-authored-by: gensokyo-dev <[email protected]>
2026-10-28 22:12:43 +08:00
gensokyo-dev b9a8f8e9f2 docs(update): align error catalog with current recovery (#7795) 2026-10-28 21:04:12 +08:00
gensokyo-dev 23e7c4e8e2 fix(setup): preserve specific skill path recovery (#7791) 2026-10-28 20:49:05 +08:00
gensokyo-dev ac545adae2 fix(apk): classify fixed inspection allowances as nonretryable (#7784) 2026-10-28 20:13:58 +08:00
ShuaixinHuang 9593bc536b fix(protobuf): reject malformed descriptor field declarations (#7730) 2026-10-28 19:52:11 +08:00
JG Tromp 7c389cbefc fix(javascript): keep both-direction feature traces from crossing shared containers (#7743)
* fix(javascript): keep both-direction feature traces from crossing shared containers

trace_application_feature with direction "both" walked the application
graph as if it were undirected. From a seed, one outgoing or incoming step
into a shared container (an asset or the artifact root) followed by steps
in the other direction reached every sibling of that container, so a trace
seeded on one storage key returned the whole connected graph.

"both" now returns the union of the outgoing and incoming closures. Each
walk keeps its own predecessor chains, so a terminal path never changes
direction midway. "outgoing" and "incoming" are unchanged.

* test(javascript): check both-direction trace paths end to end

The existing tests checked predecessor maps but no returned path. Add a
trace whose seed reaches one storage terminal outgoing and another
incoming, and assert each path's complete node_ids and edge_ids. A
pathTo that reads only the first walk's map returns a one-node path for
the incoming terminal and fails this test.

* fix(javascript): confine only ascended containers in both-direction traces

Making "both" the union of separate outgoing and incoming walks dropped
modules that a feature reaches by crossing directions. In the Notes
known-answer evaluation, the notes:export channel is pointed at by both
the preload asset (invokes) and the handler (handles); its preload,
renderer and csv modules are reached only through relationships that
change direction, so the trace kept main.js alone and the feature_modules
claim failed in tests/boundary/mcp/agentKnownAnswerMcp.test.ts.

Walk both directions in one traversal again, and confine only the
containment case the change was meant to stop: a node reached by stepping
up a contains edge from one of its children follows only further contains
steps up. A shared asset or artifact root then no longer leads into its
other children, while relationships across the feature are kept. The
Notes trace returns csv.js, main.js, preload.js and renderer.js again
(30 nodes; the previous main returned the whole 32-node graph).
outgoing and incoming traces are unchanged, and paths come from one
predecessor map again, as before this branch.
2026-10-28 19:51:59 +08:00
JG Tromp 8b74f30bf9 fix(javascript): stop double-expanding application projection estimates (#7744)
* fix(javascript): stop double-expanding application projection estimates

estimateJavaScriptStaticApplicationProjection multiplied the per-record
metadata allowance (2 KB plus the path) by the 8x expansion that it also
applies to checkpoint bytes. A projected record serializes to about 0.46 KB,
so the allowance alone already covers retention; expanded again, the
charge was about 25x the serialized application relationships.

The charge accumulates in the parent's shared result budget. On a
synthetic 2.8 MB Vite-style build (88 files, one 456 KB chunk), the first
10 files used 2.0 GB of a 2.08 GB budget while the parent heap held about
300 MiB. The other 78 files lost their application relationships and were
offered a 0-byte semantic budget. On a 201-file build the charges exceeded
the budget at file 93 and the analysis failed with resource_constraint,
leaving the remaining sources without static facts.

Keep the 8x expansion for checkpoint and repeated bytes and count the
per-record allowance once. The same builds now refuse 14 and 102
projections instead of 78 and a failed run; peak RSS stays at 1.2 GB and
2.0 GB under a 4.2 GB parent heap limit.

workerFailureComposition simulated 64 KiB of parent result budget, which
the corrected charge for its one-finding checkpoint fits. Lower that
headroom to 32 KiB so the case still exercises a refused projection.

* test(javascript): cover application projections near the shared parent budget

The estimate test compares one file's charge with its serialized graph,
but no test put several sources against one parent result budget. Replay
one recorded static checkpoint for five sources against an exact budget:
sources 1-3 fit, source 4 misses by half a source and keeps its static
facts with the reported required and budget bytes, and the last source
fits again once no checkpoint reserve is held back. A worker that charges
the projection twice, or not at all, passes the existing tests and fails
this one.

* test(javascript): cover a malformed source before a valid one under the shared budget

The testing guide asks representation-expansion and capacity changes for
a large malformed input followed by a valid input, and for escaped or
expanded representations.

Under an exact parent budget, a 3 MiB checkpoint cut off inside a string
comes first and is rejected as unreadable output with no static facts.
The valid source after it keeps its application relationships; it fits
only if the rejected bytes took no charge. A worker that charges the
static checkpoint on receipt, before parsing, passes the existing tests
and fails this one.

The estimate ratio test also runs with a nested source path and storage
keys holding quotes, backslashes, a tab and multibyte text, which expand
in serialized JSON; the charge stays within 3x to 8x of the serialized
application graph (5.3x).
2026-10-28 19:51:38 +08:00
JG Tromp 7aa943c14b fix(javascript): resolve Vite build-output preload dependencies (#7745)
* fix(javascript): resolve Vite build-output preload dependencies

With an absolute base, Vite writes __vite__mapDeps entries relative to the
build output directory (for example assets/chunk.js), and its preload helper
prefixes the configured base at runtime. REA emitted these entries as
dynamic-import module specifiers, so a scheme-less path without a leading
dot resolved as a bare package and every entry was reported as an
unresolved "external" module, even when the build output directory was
selected.

The static analyzer now marks such entries with a vite-output: specifier,
as Webpack chunk loads are marked with chunk:. Entries starting with ./,
../ or /, and scheme-qualified entries, keep their previous handling. The
graph resolves a marked entry as a URL path under each ancestor directory
of the importing file; exactly one ancestor holding the file establishes
the build output directory. Otherwise the entry is not-found (or
unavailable when several ancestors match) with a limitation that names
the build output directory.

On a synthetic 7-file Vite build, the 12 preload entries that were
"external" now resolve when the build output directory is selected, and
are not-found with that guidance when only assets/ is selected.

* fix(javascript): keep unanalyzed Vite output candidates

resolveViteOutputDependency considered only resolved ancestors. A file
that exists under an ancestor but was not analyzed (for example
dist/assets/lazy.css for the entry assets/lazy.css) resolves there as
unavailable, and that result was replaced by the root's not-found with a
limitation saying that no ancestor holds the file.

Keep resolved and unavailable ancestor candidates together. One candidate
is returned with its own path and limitations; several are reported as
unavailable with every candidate path and limitation. Only when no
ancestor can hold the file does the root's not-found result stand.
2026-10-28 19:46:45 +08:00
Dragolone 33698e6b31 fix(apktool): read Apktool 2.9+ metadata in its line-oriented dialect (#7747)
Apktool 2.9.0 replaced SnakeYAML with the YamlWriter that 3.x still uses:
apktool.yml starts with an untagged `version: 2.x.y` line and strings are
written unquoted with Java-style escapes. Only a `version: 3.x.y` header
selected the producer dialect, so 2.9.0-2.12.x output went through YAML
core parsing: a versionName of `1.0 #beta` became `1.0`, escaped quotes kept
their backslashes, an empty name became null, and `1.0: beta` made the whole
decode fail as invalid metadata.

Select the line-oriented reader for 2.9.0 and later as well. Older tagged
SnakeYAML documents keep YAML scalar semantics.
2026-10-28 19:46:11 +08:00
Dragolone fea4f2e397 fix(javascript): test literals for Next page paths in linear time (#7748)
Every source string literal without an established Next root was tested
against /(?:^|\/)app\/(?:[\s\S]*\/)?page(?:\.[cm]?[jt]sx?|-[^/?#]+\.js|)(?:[?#].*)?$/u.
The unanchored search restarted at every app/ segment and rescanned to the
end of the literal, and each page? or page# candidate scanned to the next
line terminator before $ failed. A long literal therefore took quadratic
time on the analysis thread: about 6 s for a 256 KB literal of repeated
app/ segments, and 3.5 s for 224 KB of x/page? followed by a newline.

The first app/ segment admits every later page segment, and . cannot cross
a line terminator, so a query or fragment after the page filename starts on
the last line. Test the tail after the first app/ segment one page segment
at a time instead; results are unchanged.
2026-10-28 19:45:59 +08:00
ShuaixinHuang 09225b08e1 feat(artifacts): read Godot 3 PCK version 1 archives (#7781) 2026-10-28 19:43:43 +08:00
gensokyo-dev c77735fa83 fix(setup)!: bind managed registrations to selected installation
Use one command owner for setup, client writers, Gemini policy and CLI defaults.
Migrate recognized runner registrations with backups and remove runner prewarm.
Retain unknown identities and exercise real offline npm, CLI and MCP workflows.

Fixes #7757

BREAKING CHANGE: managed MCP registrations use the selected absolute runtime
and REA entry script, including package-runner cache paths. Keep that installation
available or restore it before setup; unknown registrations require confirmed
manual repair. Setup no longer returns prewarm or emits its progress events.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-28 11:34:28 +00:00
Cipherandgensokyo-dev 18a8e71c9f feat(artifacts): add U-Boot legacy uImage reader (part of #7129) (#7234)
* feat(artifacts): add U-Boot legacy uImage reader (part of #7129)

Recognize legacy uImages by their 0x27051956 magic and inventory them as containers: 64-byte header facts (arch/os/type/compression raw and named, load/entry addresses, name, timestamp) with header and data CRC32 verified, stored payload extractable as payload.bin, and multi-file images split from the stored size table into image-<n>.bin. Compressed payloads stay as stored; nothing is executed or decompressed. Wires the format through classification, the artifact reader dispatch, extraction, and the evidence/snapshot format vocabularies. Related to #7129 (uImage part only); HEX/SREC and FIT are out of scope.

* fix(uimage): preserve aligned component ranges and exact header facts

* fix(uimage): retain buffered members through consumption and cancellation

* fix(uimage): preserve active read and validation failure precedence

---------

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-28 19:11:41 +08:00
gensokyo-dev 06d1247836 fix(evidence): preserve residual unknown constraint diagnostics (#7770) 2026-10-28 18:50:33 +08:00
ShuaixinHuang f483eab543 fix(captures): exclude normalized native numeric values (#7764) 2026-10-28 18:46:30 +08:00
gensokyo-dev df7119aeed fix(mcp): distinguish validation from connection loss (#7761)
* fix(mcp): distinguish validation from connection loss

* fix(mcp): reuse parsed HTTP disconnect facts
2026-10-28 18:17:45 +08:00
gensokyo-dev 60bad9ed06 fix(hopper)!: admit macOS arguments before application handoff (#7732)
Admit the final macOS Hopper launcher arguments before application handoff.
Keep prepared-image source identity, return precise typed refusal locations,
and preserve bootstrap/lease cleanup. Update native CLI/MCP recovery
coverage and the installation guide.

Fixes #7727

BREAKING CHANGE: macOS Hopper launches refuse double quotes, backslashes
and line breaks in final helper paths or arguments before application
handoff. Select literal-safe launcher/runtime/database paths and loader
arguments, or a compatible provider. Original executable names can remain
unchanged when their prepared image path is literal-safe.

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-28 09:12:30 +00:00
gensokyo-dev 3b242491a4 fix(cli): attribute keyed archive errors to archive argument (#7731)
* fix(cli): attribute keyed archive errors to archive argument

* test(cli): assert input-error projection reference reuse
2026-10-28 16:48:20 +08:00
blankymandgensokyo-dev e78ac1a55b feat(artifacts): read UnityFS AssetBundle containers (#7699)
* feat(artifacts): read UnityFS AssetBundle containers

inspect-artifact and extract-artifact now recognize the UnityFS signature
and treat format versions 6 through 9 as containers. Header facts (format
version, player/engine strings, declared size, dataflags, blocks-info
bounds and the declared 16-byte data hash) are retained alongside a
directory of CAB-* and .resS members. Member bytes stream on demand:
only the blocks covering the requested member are read and decompressed
with bounded expansion and cancellation.

Bundles declaring asset-bundle encryption keep header facts and report
unknown directory coverage. LZMA blocks-info reports unknown coverage;
LZMA member reads fail as unavailable while the directory stays
readable. Malformed counts, out-of-stream members and declared sizes
beyond the file fail as format errors. UnityFS classifies by bytes in
root detection, inventory graph construction and desktop inspection,
which emits a unityfs-header fact.

Validation: tsc --noEmit, oxlint (no new findings on touched files),
17 reader tests covering LZ4HC/uncompressed tables, blocks-info at end,
format 6 without padding alignment, multi-block members, malformed
input, unsupported compression, cancellation and abandoned streams;
full artifacts/domain/conformance suites pass. Verified against one
real YooAsset bundle (Unity 2021.3.32f1, format 8, LZ4HC): the
streamed SerializedFile contained its managed assembly byte-identical
to a UnityPy extraction. Other producer variants unverified.

* fix(unityfs): own bounded member reads and preserve partial evidence

* refactor(unityfs): clarify producer revision flag decisions

* fix(artifacts): preserve coverage authority and bound UnityFS block work

---------

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-28 16:47:39 +08:00
gensokyo-dev 6a226bd092 fix(apple): validate keyed archive selectors consistently (#7728) 2026-10-28 16:01:17 +08:00
gensokyo-dev 2b8fb387b6 fix(windows): resolve default tools before process launch (#7725)
Resolve Windows ADB, Apktool and update commands against the selected
PATH/PATHEXT before launch. Keep explicit paths and relative PATH choices,
report lookup failures, and reuse absolute batch invocation and ownership.

Add native launch/argv regressions, real npm metadata probes and focused
CI ownership so these boundaries retain Windows verification on the fast tier.

Fixes #7724

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Assisted-by: Yukari (gensokyo-skills:yukari-boundary-analysis)
2026-10-28 07:27:48 +00:00
gensokyo-dev 0e4b806db1 fix(cli): preserve missing-selection Markdown token windows (#7726) 2026-10-28 15:23:00 +08:00
gensokyo-dev a0a1962e06 fix(cli): validate byte queries before opening targets (#7723) 2026-10-28 15:00:01 +08:00
gensokyo-dev b0fb51cb4c fix(environment): share inline state byte admission (#7721)
Reuse shared padded-base64 facts and derive encoded admission from the existing decoded-byte budget. Refuse overflow before decoded allocation and retain padded syntax. Cover capacity, compact HTTP replies and live MCP state readback.

Fixes #7719

Assisted-by: Reimu (gensokyo-skills:reimu-incident-triage)
Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
2026-10-28 06:48:26 +00:00
5ae77656e7 feat(workflows): expose guided prompts through CLI and MCP (#6995)
* feat(workflows): expose guided prompts through CLI and MCP

* fix(workflows): address guided workflow review findings

* fix(workflows): preserve scoped contracts and actionable validation

* test(workflows): allow bounded CLI startup on shared hosts

* test(workflows): audit guidance effects and content provenance

* perf(workflows): defer rendering and separate catalog scope

---------

Co-authored-by: Deepak-Kambala <[email protected]>
Co-authored-by: gensokyo-dev <[email protected]>
2026-10-28 14:12:39 +08:00
gensokyo-dev b594fbc3e7 fix(apple): scope application roots to the inventory format (#7714) 2026-10-28 13:28:03 +08:00
gensokyo-dev 8397a0c9eb fix(plugins): align listing metadata with REA branding (#7711)
Use one packaged icon for Codex and Claude, and align listing descriptions with the repository About.
2026-10-28 05:16:41 +00:00
gensokyo-dev fbb0e79354 fix(cli): reject empty observation duration selections (#7710) 2026-10-28 12:57:14 +08:00
Aadityaandgensokyo-dev c36971953c feat(artifacts): inventory and extract Intel HEX and Motorola S-record regions (#7136)
* feat(artifacts): inventory and extract Intel HEX and Motorola S-record regions

open_binary refused Intel HEX and S-record programming files as an
unsupported format, so inspect_artifact and extract_artifact could not
answer which bytes load at which addresses.

Recognize both encodings by a fully valid first record and decode them
statically into address-contiguous regions, each an inventory entry named
0x<start>-0x<end>.bin and extractable as raw bytes. Root format_metadata
records the encoding and variant, record counts, unique and duplicate
bytes, address bounds, termination, declared start address, S0 header and
validated S5/S6 count. Gaps are never filled; start addresses are declared
facts, not proven entry points.

Checksum, record-type, byte-count, line-length, overlap-conflict, address
wrap and post-termination errors fail closed with the line number; a
missing termination record leaves coverage unknown. Decoding is bounded by
a 128 MiB file ceiling (decoded bytes are at most half the file and are
reserved after the size check) and 65,536 address-discontiguous runs.

Refs #7129

* fix(artifacts): refuse Intel HEX extended address records with a non-zero address

* fix(artifacts): bound HEX region copies and retain stream cancellation

---------

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-28 12:35:55 +08:00
gensokyo-dev ad7d4c1f4d docs(errors): align MCP validation status and verification columns (#7708) 2026-10-28 12:19:25 +08:00
gensokyo-dev b69d8c5467 docs(changelog): repair historical release heading links (#7707) 2026-10-28 12:12:42 +08:00
gensokyo-dev c01ed783ac fix(elf): share section-table presence validation with notes (#7706) 2026-10-28 12:08:25 +08:00
d3b31a0e29 feat(cli): report opt-in command timings (#7042)
* feat(cli): report opt-in command timings

* fix(cli): time standalone MCP doctor

* fix(cli): retain timing on doctor errors

* fix(cli): preserve formatted version output with command timings

---------

Co-authored-by: dhruvac29 <[email protected]>
Co-authored-by: gensokyo-dev <[email protected]>
2026-10-28 11:53:29 +08:00
gensokyo-dev 3d5c73f35c fix(cli): retain JSONL parser diagnostics under token counting (#7705) 2026-10-28 11:48:31 +08:00
gensokyo-dev e556134302 fix(deps): patch fast-uri, qs and HTTP/3 certifi (#7704)
Refresh compatible security fixes and verified dependency notices. Keep
historical HTTP/3 guest verification separate from the refreshed trust store.

Fixes #7700

Assisted-by: Aya (gensokyo-skills:aya-source-investigation)
2026-10-28 03:34:36 +00:00
aa6f6436c9 feat(cli): add CSV and TSV analysis views (#7254)
* feat(cli): add CSV and TSV analysis views

Co-authored-by: Copilot <[email protected]>

* Update tests/boundary/cli/filteredArrayOutput.test.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update src/cli.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(cli): address delimited export review feedback

* fix(cli): format delimited output block in cliResultOutput

* fix(cli): retain delimited view uncertainty and align completions

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: gensokyo-dev <[email protected]>
2026-10-28 11:27:40 +08:00
40b9c03f99 feat(environment): serve query numbers, counted values and made objects (#7332)
* feat(environment): serve the writes callers make without recorded form fields

- A create member a recording sent empty ("", null, false, [] or {}) is no
  longer required; a call that leaves it out is applied as sending that value
  (body.blank).
- List views render envelope members that list the listed entities' ids
  (Paperless's `all`), so creates in such collections are confirmed.
- Updates move their entity in collections kept sorted by a field they write,
  and a failed whole-collection read after an update can teach that order.
- A later create that stores an unruled field otherwise is withheld at the
  create, and an item read may fill values a create's answer had not loaded.
- An unsent field respelled between null, [] and {} is unchanged.
- The skill asks for one create with every field and one with only what a
  person must give.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): show how to read signed-in pages before recording

Agents guessed capture keys (artifacts, dom, final) to see pages behind
sign-in, which inspect_web_page cannot reach.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): accept every empty spelling recorded creates sent

A create that fills only what a person must give sends `null` where the
full create sent a string, and `null` or `false` for the same flag. The
merged plan now accepts each recorded empty value, and a call that leaves
the member out is applied as the earliest call sent it.

Also adds the spec folder for this change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): keep the vary-fields step neutral on UI or API writes

Agents read "the form" as a cue to write through the UI, where some
applications' request bodies are not exposed; a body-unusable UI write
now re-records once with request steps.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record verification for blank members and sorted writes

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): address review of blank members and sorted writes

- Bulk updates move their entities in turn against the others' earlier
  values and install the final order once, as replay does.
- A member's recorded empty values stay accepted once a later call teaches
  its default; a left-out member with a default keeps the default.
- Write answers spell empty lists and maps as their recorded answers did.
- A rename can teach a sort when the creates chose one by a field the
  update did not write, such as ids that ascend with titles.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve the writes that later reads explain

- An item read whose object is marked deleted (deleted, isDeleted or
  is_deleted true) agrees with an absent entity, as EspoCRM answers a
  deleted record; such an object never seeds or adopts an entity.
- maxSize, max_results and maxResults are page sizes, for whole-collection
  list lines and the list query's limit role.
- An item view also shows the fields only reads after its type's first write
  show, when no initial entity holds them (Vikunja's task subscription),
  without requiring them; write answers leave such a field out for entities
  without it, and it no longer withholds the write as incomplete-entities.
- The skill asks updates to change the fields a person would change, and
  expects a deleted object to read back as 404 or marked deleted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer sent empty members as sent, and keep a placed create's order

- A write answer spells an empty list or map the call did not send as its
  recorded answer did; one the call sent is answered as sent, so a create
  sending `[]` is not answered `null` because the first recorded create was.
- A read listing the whole collection that placed a create leaves the create
  only the sorted inserts whose order that read follows, so a later rename
  cannot teach a sort an earlier read ruled out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer bulk updates without fields only later reads show

A bulk update's answer renders each entity with the same allowance a single
update's answer has: a field only reads after the type's first write showed,
which no initial entity holds, is left out for an entity without it, so a
bulk update of a seeded task is no longer refused for lacking it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): correct how the EspoCRM contact update task passes

The agent trajectories show gpt-oss passes it by creating a replacement contact
and deleting the original, since the served update refuses emailAddress; the
update itself is refused in both builds.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer a read of a served-deleted entity marked deleted

An application that soft-deletes still answers a deleted record by id, marked
deleted. Serving now keeps an entity a served delete removed from a type whose
recorded item reads show that, until a reset or load and within the size
data/add loads, and answers a read of it with its last fields and the flag
true, instead of refusing the read.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers, check bulk answers with sent members, narrow inserts only on collection-order reads

- A create whose item read loaded values its answer had not records them
  (`observation.read.unloaded`), and a served create's answer keeps them as
  the recorded answer showed them, a zero-time owner included, while the state
  holds the read's.
- Replay checks a bulk update's recorded answers with each target's sent
  members, as serving answers them, so echoed `null` and `[]` no longer make
  the plan body-unusable.
- A whole-collection read whose query sorts it shows the query's order, so it
  no longer narrows a create's sorted insert candidates.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the census with main's unknown-clock rule merged

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve query numbers, counted values and made objects

- A query parameter accepts a number or boolean, which serving sends as its
  JSON text, as agents send page sizes and flags.
- A sequence may start at the value its first create took above every value
  its type held (Vikunja's per-project task index), and a later create's
  composed, template or started-sequence rule is adopted when it also spells
  the first create's value.
- A made-object rule explains an object the application makes with each
  created entity: members the request stamped, members holding the entity's
  own id, and counts one past the held objects' values.
- A create's answer names the id of the one object a one-element array member
  holds, so bulk creates link to their type.
- The skill reads each listed object by id before writing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): let a linked create take path values it stores

A create linked to its type's own collection, whose path has no parameters,
accepts any path values when its plan stores each one in a field, as a Vikunja
task stores its project; replay and serving apply it alike.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn a sort from a rename only when moving its entities reaches it

Serving moves only the entities a write changes in a collection kept sorted,
so replay now tries a sort after a rename only when the entities no write the
read exercised changed already follow it. Seeded folders listed out of title
order no longer teach a title sort that serving would answer with another
order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers a sent value did not echo, and learn no sort from query-sorted reads

- A served create keeps a value its recorded answer had not loaded unless the
  call sent that member and the plan stores it as sent, so a create sending
  `active: false` is answered `false` as recorded while the state holds the
  read's `true`.
- A rename no longer teaches a sort from a whole-collection read its query
  sorts, whose ties need not follow the collection's own order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): verify query values, counted values and made objects

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn the soft-delete flag in the state view and serve by it

Extraction now records the member later item reads set true on a record the
application soft-deleted, and the item view carries it as `deleted_flag`.
Serving reads that fact instead of scanning recorded bodies itself, so one
owner decides what a soft delete looks like.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the call-values checks at #7274 93821024

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn the soft-delete flag from item reads with a query too

A client may read a deleted record back only with a query, such as a
cache-busting parameter. Every successful read of the item tool now shows the
flag; only plain later reads still add fields.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the call-values checks at #7274 45832406

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn sorts only from orders a list read confirmed

- A sort retry after a failed whole-collection read requires the entities no
  write changed since a list last showed them to follow it already, rather than
  excusing every entity the update's tool ever wrote: an earlier rename a list
  confirmed in place stays where it was.
- An update takes its creates' sort only from a create a list read showed
  placed; replay still tries a sort a create guessed from the initial order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): drop entities read back as deleted and answer soft deletes as deleted

- A held entity a later read shows marked deleted is dropped, not adopted with
  the marked object's fields.
- Bulk-update replay renders answers with the optional and later-only fields
  serving uses, so a bulk update of created and seeded entities replays.
- A served delete of a soft-deleting type answers with the entity marked
  deleted, single and bulk.
- A deleted flag only query reads showed is a field of the item view, so a
  served tombstone keeps it where live records omit it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): check made objects as recorded and keep their ids and clocks honest

- A made object's clock counts as a write clock, so a capture with no clock
  anchor withholds the create instead of stamping 1970.
- Members holding the entity's identity follow the id written, generated or
  sent, through the type's id field.
- A later create's made object is checked as recorded, before its own members
  are rewritten, so one naming another entity withholds the plan.
- A later create's template is adopted only when it spells that create's value
  too, not just when the first create's text holds its source value.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): move updated entities only by placed sorts and keep query-sorted reads from confirming order

Replay moved an updated entity by a sort a create only guessed, while the
update plan exported only placed sorts, so a read could confirm an update
by a move serving would not make. Both now use the placed sort. A passing
list read clears its entities from the moved set only when the state
decides the order of every entity it lists, so a read whose query sorts
it no longer hides an earlier move from a later sort check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): count six withheld plans that explain more, not seven

The bulk task create counted among them is served on this branch.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): try a learned sort by moving each pending write in turn, as serving does

#retrySort sorted the whole collection, which a list could match while
serving, moving each renamed entity in turn against the others' values
before their own writes, gave another order. The state now records the
values each write replaced, and the retry replays the writes since a
list in collection order last showed their entities.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer a served delete with the deleted flag its recorded answer showed

An application may answer a delete with the record as it was and mark it
deleted only on later reads. Delete answers, single and bulk, now take
the flag's value from the recorded answer; reads of a served-deleted
entity still show it marked deleted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): set aside two hunks next to lines main's saved-values change rewrites

Main's #7267 changes the lines beside the blank-member docs and the
empty-spelling check in explainUpdate. Setting them aside lets that merge
apply cleanly; the commit after it puts them back on top of main's text.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): restore the set-aside hunks on main and bump the skill to 51

Puts the blank-member docs and the empty-spelling check back beside main's
slug and composed text and heldSlugRule. Main is at skill 50 with
different text, so this branch's skill changes take 51.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): bump the skill to 52 above #7260's 51

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): put back the call-values hunks main's merge took its side for, and bump the skill to 53

The merge of main kept main's side where it overlapped this branch, so it
could commit without a conflict. This restores this branch's side next to
main's: made-object agreement beside the & slug spellings, sequence starts
in the earlier evidence (now built by earlierOf), the combined value
imports, and recording step 2 beside main's UI-first step 3. Main is at
skill 50 and #7274 at 52, so this branch takes 53.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep sorts a list showed in place ruled out, and created answers' nested members as recorded

A whole list in collection order that showed a renamed entity where a
sort by the renamed field would have moved it now rules that sort out, so
a later rename of the same entity cannot teach it. A create's answer
leaves out members its item read added inside an object the answer
showed, as the recorded answer did; the state still stores them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep a later create's made object only with clocks its request stamped

followsMadeObjects only checked that a made object's clocks parsed, so a
later create whose object showed an older clock still passed, while serving
stamps the write's clock. Its clocks must now be in the rule's format and
within the stamp window of that create's request.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): compare soft-deleted read fields

* fix(environment): reject contradictory learned sequences

* fix(environment): preserve initially deleted item observations

* fix(environment): index stored deleted entities separately

* fix(environment): replay lists that include deleted records

* fix(environment): make no count of a made-object member earlier creates held alike

A count only a later create shows starts at the exemplar's value, which is
right only while the exemplar is the one create accepted: creates accepted
after it showed the member unchanged, which a count would have moved. The
merge now refuses such a count, as the top-level sequence check does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-28 07:51:03 +08:00
PM baec375c34 fix(cli): validate outline-depth before numeric coercion (#7505)
Fixes morluto/rea#7425

Signed-off-by: pqminh27 <[email protected]>
2026-10-28 05:16:49 +08:00
PM 423d190026 fix(cli): preserve Markdown table edge spaces (#7506)
Fixes morluto/rea#7432

Signed-off-by: pqminh27 <[email protected]>
2026-10-28 05:16:28 +08:00
Beqa 6efb384261 docs(uninstall): clarify malformed shared config retention (#7507)
Uninstall retains unverifiable shared registration storage without blocking
REA-owned purge; document that exception beside the stop-before-removal rule.

Fixes #7320
2026-10-28 05:16:13 +08:00
5fcf0d2dcc fix(browser): save from gzip, deflate and cached responses within a bound (#7361)
A saved response's decoded size is bounded by its received size, or the
declared length of one served from cache, times 1032 for each gzip or deflate
coding, the most DEFLATE expands. Grafana answers folder creates gzipped, so a
UI step saving a new folder's uid was refused. Other codings and unknown or
zero sizes stay refused before the body is read.

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-28 05:08:27 +08:00
7bc6c5bf61 feat(environment): serve the writes callers make without recorded form fields (#7260)
* feat(environment): serve the writes callers make without recorded form fields

- A create member a recording sent empty ("", null, false, [] or {}) is no
  longer required; a call that leaves it out is applied as sending that value
  (body.blank).
- List views render envelope members that list the listed entities' ids
  (Paperless's `all`), so creates in such collections are confirmed.
- Updates move their entity in collections kept sorted by a field they write,
  and a failed whole-collection read after an update can teach that order.
- A later create that stores an unruled field otherwise is withheld at the
  create, and an item read may fill values a create's answer had not loaded.
- An unsent field respelled between null, [] and {} is unchanged.
- The skill asks for one create with every field and one with only what a
  person must give.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): show how to read signed-in pages before recording

Agents guessed capture keys (artifacts, dom, final) to see pages behind
sign-in, which inspect_web_page cannot reach.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): accept every empty spelling recorded creates sent

A create that fills only what a person must give sends `null` where the
full create sent a string, and `null` or `false` for the same flag. The
merged plan now accepts each recorded empty value, and a call that leaves
the member out is applied as the earliest call sent it.

Also adds the spec folder for this change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): keep the vary-fields step neutral on UI or API writes

Agents read "the form" as a cue to write through the UI, where some
applications' request bodies are not exposed; a body-unusable UI write
now re-records once with request steps.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record verification for blank members and sorted writes

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): address review of blank members and sorted writes

- Bulk updates move their entities in turn against the others' earlier
  values and install the final order once, as replay does.
- A member's recorded empty values stay accepted once a later call teaches
  its default; a left-out member with a default keeps the default.
- Write answers spell empty lists and maps as their recorded answers did.
- A rename can teach a sort when the creates chose one by a field the
  update did not write, such as ids that ascend with titles.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer sent empty members as sent, and keep a placed create's order

- A write answer spells an empty list or map the call did not send as its
  recorded answer did; one the call sent is answered as sent, so a create
  sending `[]` is not answered `null` because the first recorded create was.
- A read listing the whole collection that placed a create leaves the create
  only the sorted inserts whose order that read follows, so a later rename
  cannot teach a sort an earlier read ruled out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers, check bulk answers with sent members, narrow inserts only on collection-order reads

- A create whose item read loaded values its answer had not records them
  (`observation.read.unloaded`), and a served create's answer keeps them as
  the recorded answer showed them, a zero-time owner included, while the state
  holds the read's.
- Replay checks a bulk update's recorded answers with each target's sent
  members, as serving answers them, so echoed `null` and `[]` no longer make
  the plan body-unusable.
- A whole-collection read whose query sorts it shows the query's order, so it
  no longer narrows a create's sorted insert candidates.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn a sort from a rename only when moving its entities reaches it

Serving moves only the entities a write changes in a collection kept sorted,
so replay now tries a sort after a rename only when the entities no write the
read exercised changed already follow it. Seeded folders listed out of title
order no longer teach a title sort that serving would answer with another
order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers a sent value did not echo, and learn no sort from query-sorted reads

- A served create keeps a value its recorded answer had not loaded unless the
  call sent that member and the plan stores it as sent, so a create sending
  `active: false` is answered `false` as recorded while the state holds the
  read's `true`.
- A rename no longer teaches a sort from a whole-collection read its query
  sorts, whose ties need not follow the collection's own order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn sorts only from orders a list read confirmed

- A sort retry after a failed whole-collection read requires the entities no
  write changed since a list last showed them to follow it already, rather than
  excusing every entity the update's tool ever wrote: an earlier rename a list
  confirmed in place stays where it was.
- An update takes its creates' sort only from a create a list read showed
  placed; replay still tries a sort a create guessed from the initial order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): move updated entities only by placed sorts and keep query-sorted reads from confirming order

Replay moved an updated entity by a sort a create only guessed, while the
update plan exported only placed sorts, so a read could confirm an update
by a move serving would not make. Both now use the placed sort. A passing
list read clears its entities from the moved set only when the state
decides the order of every entity it lists, so a read whose query sorts
it no longer hides an earlier move from a later sort check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): try a learned sort by moving each pending write in turn, as serving does

#retrySort sorted the whole collection, which a list could match while
serving, moving each renamed entity in turn against the others' values
before their own writes, gave another order. The state now records the
values each write replaced, and the retry replays the writes since a
list in collection order last showed their entities.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): set aside two hunks next to lines main's saved-values change rewrites

Main's #7267 changes the lines beside the blank-member docs and the
empty-spelling check in explainUpdate. Setting them aside lets that merge
apply cleanly; the commit after it puts them back on top of main's text.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): restore the set-aside hunks on main and bump the skill to 51

Puts the blank-member docs and the empty-spelling check back beside main's
slug and composed text and heldSlugRule. Main is at skill 50 with
different text, so this branch's skill changes take 51.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep sorts a list showed in place ruled out, and created answers' nested members as recorded

A whole list in collection order that showed a renamed entity where a
sort by the renamed field would have moved it now rules that sort out, so
a later rename of the same entity cannot teach it. A create's answer
leaves out members its item read added inside an object the answer
showed, as the recorded answer did; the state still stores them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-28 05:07:28 +08:00
aa210b7ccc feat(environment): serve the writes that later reads explain (#7274)
* feat(environment): serve the writes callers make without recorded form fields

- A create member a recording sent empty ("", null, false, [] or {}) is no
  longer required; a call that leaves it out is applied as sending that value
  (body.blank).
- List views render envelope members that list the listed entities' ids
  (Paperless's `all`), so creates in such collections are confirmed.
- Updates move their entity in collections kept sorted by a field they write,
  and a failed whole-collection read after an update can teach that order.
- A later create that stores an unruled field otherwise is withheld at the
  create, and an item read may fill values a create's answer had not loaded.
- An unsent field respelled between null, [] and {} is unchanged.
- The skill asks for one create with every field and one with only what a
  person must give.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): show how to read signed-in pages before recording

Agents guessed capture keys (artifacts, dom, final) to see pages behind
sign-in, which inspect_web_page cannot reach.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): accept every empty spelling recorded creates sent

A create that fills only what a person must give sends `null` where the
full create sent a string, and `null` or `false` for the same flag. The
merged plan now accepts each recorded empty value, and a call that leaves
the member out is applied as the earliest call sent it.

Also adds the spec folder for this change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(skill): keep the vary-fields step neutral on UI or API writes

Agents read "the form" as a cue to write through the UI, where some
applications' request bodies are not exposed; a body-unusable UI write
now re-records once with request steps.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record verification for blank members and sorted writes

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): address review of blank members and sorted writes

- Bulk updates move their entities in turn against the others' earlier
  values and install the final order once, as replay does.
- A member's recorded empty values stay accepted once a later call teaches
  its default; a left-out member with a default keeps the default.
- Write answers spell empty lists and maps as their recorded answers did.
- A rename can teach a sort when the creates chose one by a field the
  update did not write, such as ids that ascend with titles.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* feat(environment): serve the writes that later reads explain

- An item read whose object is marked deleted (deleted, isDeleted or
  is_deleted true) agrees with an absent entity, as EspoCRM answers a
  deleted record; such an object never seeds or adopts an entity.
- maxSize, max_results and maxResults are page sizes, for whole-collection
  list lines and the list query's limit role.
- An item view also shows the fields only reads after its type's first write
  show, when no initial entity holds them (Vikunja's task subscription),
  without requiring them; write answers leave such a field out for entities
  without it, and it no longer withholds the write as incomplete-entities.
- The skill asks updates to change the fields a person would change, and
  expects a deleted object to read back as 404 or marked deleted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer sent empty members as sent, and keep a placed create's order

- A write answer spells an empty list or map the call did not send as its
  recorded answer did; one the call sent is answered as sent, so a create
  sending `[]` is not answered `null` because the first recorded create was.
- A read listing the whole collection that placed a create leaves the create
  only the sorted inserts whose order that read follows, so a later rename
  cannot teach a sort an earlier read ruled out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer bulk updates without fields only later reads show

A bulk update's answer renders each entity with the same allowance a single
update's answer has: a field only reads after the type's first write showed,
which no initial entity holds, is left out for an entity without it, so a
bulk update of a seeded task is no longer refused for lacking it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): correct how the EspoCRM contact update task passes

The agent trajectories show gpt-oss passes it by creating a replacement contact
and deleting the original, since the served update refuses emailAddress; the
update itself is refused in both builds.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer a read of a served-deleted entity marked deleted

An application that soft-deletes still answers a deleted record by id, marked
deleted. Serving now keeps an entity a served delete removed from a type whose
recorded item reads show that, until a reset or load and within the size
data/add loads, and answers a read of it with its last fields and the flag
true, instead of refusing the read.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers, check bulk answers with sent members, narrow inserts only on collection-order reads

- A create whose item read loaded values its answer had not records them
  (`observation.read.unloaded`), and a served create's answer keeps them as
  the recorded answer showed them, a zero-time owner included, while the state
  holds the read's.
- Replay checks a bulk update's recorded answers with each target's sent
  members, as serving answers them, so echoed `null` and `[]` no longer make
  the plan body-unusable.
- A whole-collection read whose query sorts it shows the query's order, so it
  no longer narrows a create's sorted insert candidates.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* docs(environment): record the census with main's unknown-clock rule merged

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn a sort from a rename only when moving its entities reaches it

Serving moves only the entities a write changes in a collection kept sorted,
so replay now tries a sort after a rename only when the entities no write the
read exercised changed already follow it. Seeded folders listed out of title
order no longer teach a title sort that serving would answer with another
order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep unloaded create answers a sent value did not echo, and learn no sort from query-sorted reads

- A served create keeps a value its recorded answer had not loaded unless the
  call sent that member and the plan stores it as sent, so a create sending
  `active: false` is answered `false` as recorded while the state holds the
  read's `true`.
- A rename no longer teaches a sort from a whole-collection read its query
  sorts, whose ties need not follow the collection's own order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn the soft-delete flag in the state view and serve by it

Extraction now records the member later item reads set true on a record the
application soft-deleted, and the item view carries it as `deleted_flag`.
Serving reads that fact instead of scanning recorded bodies itself, so one
owner decides what a soft delete looks like.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn the soft-delete flag from item reads with a query too

A client may read a deleted record back only with a query, such as a
cache-busting parameter. Every successful read of the item tool now shows the
flag; only plain later reads still add fields.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): learn sorts only from orders a list read confirmed

- A sort retry after a failed whole-collection read requires the entities no
  write changed since a list last showed them to follow it already, rather than
  excusing every entity the update's tool ever wrote: an earlier rename a list
  confirmed in place stays where it was.
- An update takes its creates' sort only from a create a list read showed
  placed; replay still tries a sort a create guessed from the initial order.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): drop entities read back as deleted and answer soft deletes as deleted

- A held entity a later read shows marked deleted is dropped, not adopted with
  the marked object's fields.
- Bulk-update replay renders answers with the optional and later-only fields
  serving uses, so a bulk update of created and seeded entities replays.
- A served delete of a soft-deleting type answers with the entity marked
  deleted, single and bulk.
- A deleted flag only query reads showed is a field of the item view, so a
  served tombstone keeps it where live records omit it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): move updated entities only by placed sorts and keep query-sorted reads from confirming order

Replay moved an updated entity by a sort a create only guessed, while the
update plan exported only placed sorts, so a read could confirm an update
by a move serving would not make. Both now use the placed sort. A passing
list read clears its entities from the moved set only when the state
decides the order of every entity it lists, so a read whose query sorts
it no longer hides an earlier move from a later sort check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): try a learned sort by moving each pending write in turn, as serving does

#retrySort sorted the whole collection, which a list could match while
serving, moving each renamed entity in turn against the others' values
before their own writes, gave another order. The state now records the
values each write replaced, and the retry replays the writes since a
list in collection order last showed their entities.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): answer a served delete with the deleted flag its recorded answer showed

An application may answer a delete with the record as it was and mark it
deleted only on later reads. Delete answers, single and bulk, now take
the flag's value from the recorded answer; reads of a served-deleted
entity still show it marked deleted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): set aside two hunks next to lines main's saved-values change rewrites

Main's #7267 changes the lines beside the blank-member docs and the
empty-spelling check in explainUpdate. Setting them aside lets that merge
apply cleanly; the commit after it puts them back on top of main's text.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): restore the set-aside hunks on main and bump the skill to 51

Puts the blank-member docs and the empty-spelling check back beside main's
slug and composed text and heldSlugRule. Main is at skill 50 with
different text, so this branch's skill changes take 51.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore(environment): bump the skill to 52 above #7260's 51

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): keep sorts a list showed in place ruled out, and created answers' nested members as recorded

A whole list in collection order that showed a renamed entity where a
sort by the renamed field would have moved it now rules that sort out, so
a later rename of the same entity cannot teach it. A create's answer
leaves out members its item read added inside an object the answer
showed, as the recorded answer did; the state still stores them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(environment): compare soft-deleted read fields

* fix(environment): preserve initially deleted item observations

* fix(environment): index stored deleted entities separately

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-28 05:05:21 +08:00
Wenyu Chiou ef11f77836 fix(evidence): Reject non-file destinations before overwrite advice (#7495)
Check destination kind before overwrite policy and cover directory recovery,
regular-file controls, symlink modes and preservation.

Fixes #7444.

Independent review: APPROVE for patch SHA-256
3d65eb23d01da9b6df786ad0db337dcff79d85923f23678a5168babb88c16080,
relayed by the coordinating thread (reviewer identity not supplied in the
delegated packet). Triggers: file I/O, error handling, three shipping files.

Validation: baseline/candidate runtime builds and actual synthetic CLI probes;
initial focused run 70 passed, 2 Windows EPERM fixture failures, 3 skipped.
Final changed filesystem file 42 passed, 5 skipped; symlink semantics and
full aggregate checks remain unverified. Targeted format/lint/discovery passed.
2026-10-28 03:41:26 +08:00
0cd7ef456b feat(plugins): make Claude Code and Codex installs self-contained (#7514)
Ship Claude Code and Codex from one release-pinned npm artifact with bundled runtime dependencies, extraction-only MCP qualification, plugin-aware recovery, and synchronized release metadata.

Integrates #2815 and the original proposal #1977. The original commits remain available on the PR branch; retain their author and assistant credit in this squash.

Validation: required CI passed, real Codex/Claude loading verified, and reviewed packaging/recovery findings addressed.

Co-authored-by: GamerDubz <[email protected]>
Co-authored-by: morluto <[email protected]>
Co-authored-by: OpenAI Codex <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-27 17:13:17 +00:00
gensokyo-dev 269630f4e1 docs: archive historical verification and release inventories (#7519)
Retire redundant historical JSON copies from the active documentation tree after verifying identical published release snapshots and an immutable route-report archive. Preserve current release data, original evidence, release publication logic and historical access.

Validation: 48 release tests; documentation conformance and rendered archive link/digest; Git blob/SHA-256 checks; selected current-head CI passed. Greptile: 5/5 with no actionable findings. Codex GitHub review unavailable due quota.

Closes #7517.
2026-10-28 00:54:54 +08:00
gensokyo-dev 65f1c44734 refactor: retire superseded test-only runtime entrypoints (#7515)
Migrate MCP session tests to the named lifecycle output schema and preserve raw reply envelopes. Move R8 type/alias checks to the production field resolver and recovery guidance checks to their scoped factory; remove superseded test-only exports and an unused import.

Validation: 99 focused tests, an exact-old-schema negative control, full selected CI including all 8 shards and source tests, and Greptile source review passed. Fresh-head real stdio MCP analyzed [email protected] and retained a complete authenticated Evidence bundle after close; compact/full catalogs are unchanged. Full local typed lint hit the 3 GiB memory guard; scoped typed lint passed. Codex review quota exhausted.

Fixes #7513.
2026-10-28 00:22:43 +08:00
gensokyo-dev 6eb37a7749 fix(ci): restore qualification and reduce validation overhead
Use one typed-checker worker by default without changing semantic scope or caller overrides. Reuse the bounded CLI worker for pure argument validation while retaining fresh-process coverage and all upstream cases.

Keep registration tests independent of real package-runner downloads while asserting the actual prewarm command and startup context. Pass the advertised binary_session definition by name to package verification, retaining default SDK validation and complete catalog/contract checks while avoiding compilation of unrelated tool outputs. Preserve all four installed-tarball scenarios and existing deadlines.

Strengthen Hermes preview operation/backup assertions and clarify physical-path routing documentation.

Assisted-by: Suika (gensokyo-skills:suika-scatter-gather-planning)
2026-10-28 00:20:07 +08:00
S1MonandS1Mon bcc6775dc1 fix(cli): reject non-decimal Android overload index tokens (#7493)
Android overload selection declared a plain number, so the CLI argument
parser coerced the raw token with Number before the schema ran. An empty
token therefore arrived as 0, and hexadecimal, exponent, signed, and
float spellings arrived as their numeric value, leaving both commands to
proceed to artifact admission on a selector the caller never wrote as a
decimal integer.

Reuse the existing decimal token parser that the other integer CLI
options already use. Omitted and explicit decimal zero keep their current
meanings, and the published schema for overloadIndex is unchanged.

Validation: npm run compile, the cli-boundary vitest project for
tests/boundary/cli/cliIntegerArguments.test.ts (56 passed), npm run
typecheck, npm run lint, npm run lint:typed, npm run format:check, npm
run metadata:check, npm run verify:architecture-guards, and npm run
knip:production. The new cases fail against the base source and pass with
the change.

Fixes #7430.

Co-authored-by: S1Mon <[email protected]>
2026-10-27 23:25:32 +08:00
Pirro Zani 313af7119c fix(website): keep phone navigation labels from splitting mid-word (#7497)
The phone header gave each link an equal minmax(0, 1fr) column and
allowed overflow-wrap: anywhere, so single-word labels such as
"Showcases", "Anleitungen", "Руководства" and "Посібники" broke between
letters at 320-430px. Links now share the row as flex items that never
shrink below their longest word. Labels wrap only at spaces, and a word
wider than the whole row can still break, preserving the enlarged-text
fit from #3598.

Refs #3597
2026-10-27 23:25:04 +08:00
gensokyo-dev a95b83c2b0 perf(javascript): cache callable result syntax by AST identity (#7508)
Cache direct return/yield source expressions by immutable AST identity for all existing static and semantic consumers. Weak keys bound retention to AST lifetime; mutable analysis facts and Evidence remain unchanged. Refs #6311; full CastleIO analysis still times out.

Validation: 225 focused tests; baseline cache-regression controls; build, serial check:fast and test discovery passed. CastleIO direct-syntax facts equal with 78,272 warm lookups reduced from 2.72-2.81s to 13.0-13.4ms. Complete sourcemap-codec CLI analyses retained byte-identical Evidence; no end-to-end speedup or token reduction claimed.

CI: source 20,888 passed / 15 skipped; seven built-dependent shards, static, docs, package builds, Linux native baseline and real JS recovery CLI/MCP passed. Shard 6 Hermes path-preview failures both reproduce on exact main b9d1a61dd; Portable tests fails downstream. Greptile 5/5, no findings; Codex quota exhausted. Authorized admin bypass for unrelated baseline CI and unchecked human readiness; no human review attestation made.
2026-10-27 22:53:42 +08:00
morluto 7f90549916 chore(android): remove unused type exports 2026-10-27 22:52:33 +08:00
morluto b3fd0aa3ee test(setup): align Hermes symlink preview expectations 2026-10-27 22:52:33 +08:00
Beqa b9d1a61dd5 docs(ghidra): clarify Objective-C Message Analyzer libobjc log (#7249)
Clarify the Objective-C analyzer message, coverage limitation, structured failure diagnostics, and existing opt-out/startup resource controls.

Verification: exact documentation change applied on main 79d2fc054; docs:check passed. Installed Ghidra 12.2 analyzer/scheduler and REA error/launch owners inspected. No real macOS target reproduction; original failure remains unknown. PR CI and Greptile passed; Codex review unavailable.
2026-10-27 22:28:29 +08:00
Adolanium 79d2fc0540 fix(doctor): classify an unreadable skill identity as unknown (#7090)
rea doctor reported a skill copy with an unreadable or unresolved path as identity state unknown but classified its skill:identity check as config_drift, which claims the copy has drifted. docs/installation.md keeps an unreadable skill identity unknown, and the sibling registration checks already classify unknown state as unknown. The skill check and the DoctorScope fallback now do the same.
2026-10-27 21:34:05 +08:00
Saiyam Jain 097cd2c988 fix(browser): report non-absolute export paths at their input field (#7097) 2026-10-27 21:33:49 +08:00
84f62f76e5 fix(hermes): preserve external YAML anchor consumers (#5152)
* fix(hermes): preserve consumers of anchored registrations

Keep original alias values and comments before setup or uninstall replaces an anchored REA node. Preserve original nested bindings and retained sharing through the common YAML writer.

Fixes #3325

* test(hermes): assert retained alias object identity

* fix(hermes): preserve removed keys and surviving alias owners

* test(cli): restore retained-view cancellation phase coverage

* fix(setup): retain copied Hermes anchor comments

* chore(hermes): reverse incidental merge hook changes

Reverse the merge relative to its included-main parent to restore exact upstream bytes. Reapply only the independently reviewed shared-owner and regression patch in a normal follow-up commit. Keep all ordinary history and normal hooks; no remote push of the rejected hook drift.

Refs #3325

* fix(hermes): retain reviewed shared-owner integration

* chore(hermes): reverse incidental merge hook changes

Reverse the merge relative to its included-main parent to restore exact upstream bytes. Reapply only the independently reviewed shared-owner and regression patch in a normal follow-up commit. Keep all ordinary history and normal hooks; no remote push of the rejected hook drift.

Refs #3325

* fix(hermes): retain exact reviewed shared-owner regression

* test(native): align plist command fixtures with main

Adopt the two maintained-main fixture files as of
dd198d037f. Distinguish exact XML lint
validation from conversion commands and retain truthful provenance,
source-value, format, limitations and unknown-scalar assertions.

The original seven provenance failures reproduce before this repair.
The affected three-file group passes all 86 checks afterward. Product
code and installed-package bytes remain unchanged.

Co-authored-by: morluto <[email protected]>

* fix(native): retain bound-target dispatch failure contracts

Adopt morluto's canonical Apple dispatch metadata owner and bounded MCP
and cleanup controls from 41e10b240c.
Keep fresh admission separate from already-bound target changes and
retain access-denied classification, exact physical causes and cleanup
ownership. Update the two stale unit expectations exposed by Source CI.

The original unit pair reproduces before the correction. Current focused
regressions, package verification and installed feature controls pass.
Only the canonical Apple owner and related controls are ported; this does
not integrate unrelated later-main changes or create another contribution.

Co-authored-by: morluto <[email protected]>

* test: align plist provenance and package listing fixtures

Keep the exact XML lint invocation in CLI provenance and include the
required CLI environment owner in the synthetic package member list.
Preserve binary provenance and all LF, CRLF, literal-CR and bytecode checks.

* revert(hermes): restore canonical main before reviewed replay

This reverts commit 575a10d194, reversing
changes made to bb17e90f27.

* test(cli): retain full cancellation oracle with prepared projection

---------

Co-authored-by: hhang <[email protected]>
Co-authored-by: gensokyo-dev <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-27 21:33:17 +08:00
Afloat 095a51cf38 fix(browser): reject invalid UTF-8 in HTTP CDP discovery (#4524) 2026-10-27 21:33:01 +08:00
Jeff d47efe1a54 fix(native): reject mixed dyld refusal diagnostics (#5778)
* fix(native): classify confirmed dSYM dyld refusals

* style(native): format target refusal handling

* fix(native): confirm precise Mach-O layout refusals before export fallback

* test(cli): observe cancellation at stable source resolution boundary

* fix(native): reject contradictory dyld layout refusals

* fix(native): preserve mixed dyld diagnostic failures

* fix(native): retain the evidence behind contradictory layout refusals

When the imports and exports refusals disagree, or a refusal disagrees with
the parsed Mach-O header, inspect_macho returned a generic output error that
kept only one dyld_info capture. It dropped the header file type and the other
refusal, so the failure could not show why the admitted diagnostic was
rejected.

The contradiction now has its own error. Its diagnostics keep the parsed file
type and every admitted refusal (mode, admitted layout, exit code and output),
and the captured output is still the conflicting command. The test checks the
reason and the retained diagnostics for each contradiction case.

* test(native): allow time for real Mach-O CLI and MCP controls
2026-10-27 21:32:13 +08:00
Ahmed cbeeeda97b fix(javascript): resolve preceding exported variable initializers and computed method keys (#5387)
fix(javascript): resolve variable initializers before computed method keys
2026-10-27 21:31:59 +08:00
Chip Li b4118b9683 docs(hermes): explain nested-home routing and preview limits (#4145)
* docs(hermes): clarify sticky profiles for nested homes

* docs(hermes): qualify nested homes beneath default symlinks

* docs(hermes): cover canonicalized ancestor paths

* docs(hermes): clarify both missing-path containment errors
2026-10-27 21:31:40 +08:00
morluto ec3f84b626 test(ci): avoid pinning skip warning wording 2026-10-27 21:26:38 +08:00
1201c25542 fix(ci): align static checks and regression fixtures with current contracts (#7349)
* fix(ci): retire unused internal analysis declarations

* test: use an admitted app bundle for provider routing

(cherry picked from commit 00aa17f12a)

* test: keep bundle routing coverage outside oversized group

(cherry picked from commit 8658353b0d)

* fix(ci): align regression fixtures with current admission contracts

* test: bind extraction close fixtures to their ZIP digest

(cherry picked from commit 626d0250db)

* test(cli): match typed analysis outcomes in function detail fixture

* test(ghidra): preserve empty Java property separator framing

* test(electron): retain unknown IPC ownership for native module gaps

* fix(electron): share source-scoped call path identity

* test(captures): assert safe source identity on SAZ refusal

* test(apple): match root occurrence kind to inventory manifest

* fix(examples): align directory root occurrence identity

* test(electron): align equivalent fixture assertions with upstream

* test(process): assert retained capture root identity

* test(windows): declare the PE fixture optional header

* test(ci): refresh owned registration and verifier fixtures

* test(setup): use owned registrations for refresh fixtures

* test(process): control unavailable ownership in CLI cleanup fixture

* test(process): guard controlled compiler output arguments

* test(setup): align equivalent entrypoint guards with upstream

* test(process): release the cleanup target through an owned gate

* test(ci): align semantic identities and owned fixture facts

* test(pcap): retain the upstream DNS wire fixture branch

* test(pcap): use the canonical wire ownership fixture

* test(pcap): assert exact DNS wire query labels

* test(ci): preserve admission and ownership fixture prerequisites

* test(ci): align authenticated fixture and cleanup boundaries

* test(windows): align native artifact fixtures with upstream

* test(android): request complete evidence for inline MCP contracts

* test: avoid pinning diagnostic wording

* test: verify cleanup diagnostics at their source

* test: strengthen evidence and cleanup checks

* test: avoid pinning registration guidance

---------

Co-authored-by: Plastic-time <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-27 21:24:30 +08:00
gensokyo-dev 570abe95f2 feat(android): link native declarations to static JNI candidates (#7472)
Link original DEX native declarations to per-ABI function exports and relocated static JNI table candidates through shared CLI/MCP workflows. Preserve global attribution ambiguity, exact provenance, partial coverage and retained Evidence; default MCP delivery to bounded summaries with filtered/batch pages.

Use one immutable ELF relocation decoder with streaming IL2CPP materialization, cooperative bounded export/version parsing and bounded JNI state. Reuse validated session inventories without loading target libraries or executing JNI code.

Validation: relevant type/lint/build and parser/domain/public CLI/MCP regressions; genuine four-ABI NDK fixtures and independent library/slot oracles; actual JDK/JADX Conscrypt workflows with retained-source removal. Full measurements and limitations are recorded in docs/verification/android-jni-bindings-2026-10-27.md.

Closes #6403.
2026-10-27 18:53:22 +08:00
gensokyo-dev 740c0f5615 fix(windows): restore native verification fixture coverage (#7479)
Restore independent PE fixtures and dependency-complete standalone artifact verifier tests. Execute existing real Windows native behavior and inspection recovery proofs before unrelated curated tests.

Validation: 101 focused tests; full typecheck; scoped lint, module/discovery/format/docs checks; valid/corrupt real-image verifier controls; real Windows artifact, behavior, and inspection recovery proof steps passed. Greptile found no actionable issues. Codex review quota exhausted.

CI remains red from exact-base failures: Source 9, Windows 7 (base 15; loader 8 repaired), and built shard 4's 7 matching failures; 7 other shards cancelled by fail-fast. Later Windows package/Node 22/24 checks skipped. User explicitly authorized bypass of established main failures. No claim of complete CI or unavailable coverage.

Fixes #7474.
2026-10-27 18:50:40 +08:00
gensokyo-dev d6f88becd5 fix(mcp): summarize copied browser observations in input declarations (#7469)
Declare copied complete browser observations as abbreviated object operands, keeping canonical validation and normalization controls unchanged. Preserve all other tool declarations and Evidence identities.

Refs #4973 and #4081.
2026-10-27 17:09:22 +08:00
morluto b8cdbdf0ef test(sqlite): gate projection checks on native limits 2026-10-27 15:47:54 +08:00
gensokyo-devand555aaditya 03f17cf41d feat(android): apply caller-selected R8 mapping evidence (#7456)
Apply caller-selected R8/ProGuard mappings to shared Android inspections, preserving raw identities, exact verification, ambiguity and provenance. Add retained summaries and bounded/cached parsing, with measured real R8/Conscrypt workflows and review fixes.

Fixes #6329.

Co-authored-by: 555aaditya <[email protected]>
2026-10-27 15:47:08 +08:00
Rudy Mizrahi Celekliandgensokyo-dev 98422997c0 fix(setup): report Kuna cache aliases consistently (#7207)
fix(setup): report Kuna cache aliases consistently (#7207)

Unify lexical default-cache reports without changing removal authority. Plan selections before deleting managed directories; resolve absolute POSIX paths independently of ambient cwd. Preserve parent traversal, literal backslashes, caller data, and result/removal order.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 15:13:47 +08:00
gensokyo-dev 2817d30ab2 fix(docs): preserve verification reports after experiment archival (#7462)
Move the retained allocation report and unchanged receipt JSON into verification documentation. Keep one report producer, repair current and archived links, document test-support ownership, and remove retired lint inputs.

Fixes #7458.

Validated focused/Python checks, report consistency, docs rendering, and real Bash CLI/MCP facts against an independent oracle. Greptile reviewed all seven files without comments. CI source/Windows/shard-8 failures match clean-main or existing-main controls; the requester authorized merging with those established failures. Codex review quota was unavailable.
2026-10-27 15:10:48 +08:00
吴佳浩Alben 0676ad254c docs(clients): note Droid's FACTORY_HOME_OVERRIDE (#7382)
768b58c6d (fix(setup): honor Droid home override) made factoryDirectory
resolve from FACTORY_HOME_OVERRIDE, so setup now writes the registration
and the personal skill copy under that home instead of ~/.factory. The
Factory Droid section still described only ~/.factory, and the page names
every other client's home override (KIMI_CODE_HOME, QODER_CONFIG_DIR,
QWEN_HOME, HERMES_HOME, CODEX_HOME, GEMINI_CLI_HOME, PI_CONFIG_DIR, DSH_HOME),
so Droid was the only one missing.
2026-10-27 14:30:18 +08:00
morluto dfe6aaf6da fix(gpu): preserve omitted metadata in projected views 2026-10-27 14:23:55 +08:00
morluto e99b6c2c3b fix(dotnet): retain malformed method body diagnostics 2026-10-27 14:15:20 +08:00
morluto 365fb03e73 chore: archive analysis efficiency experiments 2026-10-27 14:10:07 +08:00
morluto 5b14823353 fix(gdb): retain confirmed detach during close 2026-10-27 14:09:06 +08:00
morluto c602fe8828 refactor(schemas): select native and GPU variants by name 2026-10-27 14:04:53 +08:00
morluto d14f199736 fix(debugger): retain verified detach across cleanup retries 2026-10-27 14:04:49 +08:00
morluto 1fe92bff8e fix(pe): bound forwarders to export directory 2026-10-27 14:04:44 +08:00
morluto 50822e1eff fix(evidence): include every subject format in bundles 2026-10-27 13:59:32 +08:00
morluto 59dc48db20 fix(pcap): attribute DNS answers using wire identities 2026-10-27 13:54:20 +08:00
morluto a2e2c29b59 refactor(analysis): move client cleanup to application 2026-10-27 13:49:44 +08:00
morluto abfc42cfb1 fix(wasm): distinguish source and internal failures 2026-10-27 13:49:43 +08:00
morluto 6941d5ab92 fix(native): classify legacy MZ signatures before COFF 2026-10-27 13:49:41 +08:00
morluto df0e2f7b3e fix(desktop): read bounded MZ signature evidence 2026-10-27 13:46:36 +08:00
morluto cce244f037 fix(providers): reject invalid parsed MCP JSON 2026-10-27 13:46:34 +08:00
morluto 4726b19f98 fix(reference): retain ambiguous source identities 2026-10-27 13:46:32 +08:00
morluto 4055cc4df1 fix(verification): retain browser profile until shutdown 2026-10-27 13:42:36 +08:00
morluto d3af70fa27 fix(ida): preserve startup failure ownership 2026-10-27 13:42:35 +08:00
morluto 2733979b4d fix(analysis): validate native UI seed addresses 2026-10-27 13:42:33 +08:00
morluto c9df40f810 refactor(verification): own browser fixture lifecycle 2026-10-27 13:36:57 +08:00
Rudy Mizrahi Celekliandgensokyo-dev 7d6bccb86d fix(harmony): classify exact manifest names once (#7206)
Use one exact-case manifest path classifier for Harmony model hints and components. Preserve unavailable content identity, resource exclusions, Stage precedence and Evidence provenance.

33 boundary tests, docs checks, serial static checks and real pinned-HAP CLI/MCP before/after task passed. Canonical complete projection Evidence stays identical; uppercase derivative now reports unknown/no manifests. Shipped verifier source-ID assertion reproduces on unchanged main. CI7pass4fail19skip7cancel; exactmain reproduces17source and20shard8 failures. Greptile4/5soleupstreamfile-readercleanup scoped/resolvednotfixed. Requester authorized readiness and unrelated-main bypass; human review is not attested.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 13:30:24 +08:00
morluto f59fc19d21 fix(managed): unify native module identity matching 2026-10-27 13:24:11 +08:00
morluto 4e67bc3999 refactor(analysis): consolidate selection ownership 2026-10-27 13:21:35 +08:00
morluto 6d14e25345 refactor(ida): centralize capability admission 2026-10-27 13:21:33 +08:00
morluto a37dbb953c refactor(artifacts): select extraction reader from inventory 2026-10-27 13:21:32 +08:00
morluto 6ed97a22ed fix(export): retain verification cleanup failures 2026-10-27 13:19:25 +08:00
morluto 1ea6903595 fix(ida): preserve path identity across symlink traversal 2026-10-27 13:19:25 +08:00
morluto c29a93097a fix(pcap): preserve metadata on duration overflow 2026-10-27 13:17:00 +08:00
morluto 5b292b630e fix(export): report publication cleanup failures to callers 2026-10-27 13:14:50 +08:00
morluto 01a725ecfa fix(setup): preserve configuration directory requirements 2026-10-27 13:14:50 +08:00
morluto 235e8bc056 refactor(evidence): centralize provider identity comparison 2026-10-27 13:13:06 +08:00
morluto 21483a1a47 refactor(artifacts): reuse descriptor range reader 2026-10-27 13:13:05 +08:00
morluto 98e47e37a2 refactor(pcap): centralize DNS packet facts 2026-10-27 13:10:24 +08:00
morluto 5aa23c3d17 refactor(providers): move inspection scope to application 2026-10-27 13:06:57 +08:00
morluto 82f50f56db fix(macho): validate slice overlap at shared reader 2026-10-27 13:06:56 +08:00
morluto 47f8669c1e fix(export): retain publication and cleanup failures 2026-10-27 13:06:29 +08:00
morluto ddb5337674 fix(setup): resolve Hermes home ancestors before profile selection 2026-10-27 13:06:29 +08:00
morluto b61fe25068 refactor(electron): reuse source range identities 2026-10-27 13:04:25 +08:00
morluto 65aeb80222 refactor(providers): share artifact cleanup binding 2026-10-27 13:04:23 +08:00
morluto c7afedc3d2 refactor(macho): consolidate universal image selection 2026-10-27 13:04:22 +08:00
morluto df8c90df8f fix(browser): retain cancellation after failed worker stop 2026-10-27 13:01:18 +08:00
morluto 8a8331b082 fix(setup): preserve Hermes home traversal 2026-10-27 13:01:18 +08:00
morluto 8d747c2acd fix(macho): unify segment mapping admission 2026-10-27 13:00:33 +08:00
morluto 0a9d92a54b fix(browser): share admitted accessibility identities 2026-10-27 12:57:32 +08:00
morluto 4b6fd03146 refactor(evidence): consolidate import staging 2026-10-27 12:57:31 +08:00
morluto c66729eca9 fix(workers): retain cancellation through final cleanup 2026-10-27 12:56:10 +08:00
morluto 4572f31589 fix(pcap): preserve DNS class when attributing answers 2026-10-27 12:56:10 +08:00
morluto 8691e48e67 refactor(evidence): return import counts from ledger owner 2026-10-27 12:54:37 +08:00
morluto 1dc33c0543 fix(native): reuse PE header layout evidence 2026-10-27 12:54:35 +08:00
morluto 21b6ea7fbd refactor(ida): consolidate pagination progress checks 2026-10-27 12:49:07 +08:00
morluto 8f894546c8 fix(browser): retain evidence across cleanup errors 2026-10-27 12:49:05 +08:00
morluto 178ab26290 fix(pcap): account for SRV owner fields 2026-10-27 12:46:46 +08:00
morluto 7968ceb450 fix(process): normalize capture environment overrides 2026-10-27 12:45:57 +08:00
morluto 160648cc60 fix(filesystem): unify stable file identity checks 2026-10-27 12:45:57 +08:00
morluto 3e590e5b2f fix(evidence): retain malformed native observations 2026-10-27 12:45:57 +08:00
Rudy Mizrahi Celekliandgensokyo-dev 921225d4b2 fix(apk): match signer serials by signed integer identity (#7205)
Match v1 APK certificate and signer serials by signed integer value. Normalize each comparison identity once and preserve raw certificate bytes and Evidence.

37 source/integration tests, 23 real Android SDK verifier cases, SDK-valid padded APK CLI/MCP oracle and serial static checks passed. Hosted real-apk-signature passed. CI27pass7fail2skip7cancel; exact-main controls reproduce17source and14targeted existing-main assertions. NativeWindows/Mac/Node22 baseline gaps and canceled shards are documented. Greptile sole finding is unchanged upstream browser privacy code, scoped and resolved without a fix claim. Requester authorized readiness and unrelated-main failure bypass; no human review is attested.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 12:45:43 +08:00
morluto 25375924f7 fix(pcap): attribute DNS addresses by record owner 2026-10-27 12:42:51 +08:00
morluto e152349c5d fix(process): distinguish omitted byte filenames 2026-10-27 12:42:51 +08:00
morluto 9e4cf28cef refactor(cli): remove obsolete JSON read error mode 2026-10-27 12:42:25 +08:00
morluto a49a3553f4 refactor(managed): consolidate member comparison keys 2026-10-27 12:42:24 +08:00
morluto 397a5599e3 refactor(asar): retain admitted archive extents 2026-10-27 12:42:21 +08:00
morluto 39c7f7e359 fix(evidence): retain malformed function observations 2026-10-27 12:42:18 +08:00
morluto 44310bba32 fix(il2cpp): validate selected FAT slice identity 2026-10-27 12:37:39 +08:00
morluto 279fc04095 fix(snapshot): retain publication receipt on cleanup failure 2026-10-27 12:37:38 +08:00
gensokyo-devandHarsh 7e8f7f6101 feat(android): expose selected manifest component declarations (#7379)
Extend static manifest declarations and retain precise source locations and historical unknowns. Share bounded selected component views across CLI and MCP with complete parent Evidence.

Verified real ApiDemos, an AAPT2-built fixture, legacy Evidence, default-package metadata and relevant CLI/MCP contracts. Recorded whole-task token estimates, timing/resource limits and independent main-failure controls in the PR.

Co-authored-by: Harsh <[email protected]>
2026-10-27 12:37:10 +08:00
morluto 3d311d9eca fix(cli): report failed browser cleanup retries 2026-10-27 12:31:48 +08:00
morluto b9e5a9f463 fix(process): retain unrepresentable filename evidence 2026-10-27 12:31:48 +08:00
morluto dd2cbbf1a2 fix(il2cpp): require FAT container identity 2026-10-27 12:31:35 +08:00
morluto 7cbf375d01 fix(evidence): retain authenticated parents on cancellation 2026-10-27 12:31:33 +08:00
morluto dcfb61826d fix(native): share Swift symbol recognition 2026-10-27 12:31:31 +08:00
morluto dd9f5cdc4d refactor(providers): share client close options 2026-10-27 12:27:34 +08:00
morluto 21f12b896e fix(native): order Objective-C category records 2026-10-27 12:27:32 +08:00
morluto f5edef3c96 fix(hopper): share cancellable probe output waits 2026-10-27 12:25:03 +08:00
morluto ad1a57b65d fix(native): own Objective-C category identity 2026-10-27 12:25:01 +08:00
morluto c4242cb85e fix(evidence): own standalone command finalization 2026-10-27 12:24:59 +08:00
morluto 2e7a206b20 fix(process): preserve symlink target bytes 2026-10-27 12:23:56 +08:00
morluto ff6b3fb9a1 fix(evidence): admit rebound APK and WASM views 2026-10-27 12:23:56 +08:00
morluto 14dd07e740 fix(exports): preserve ELF name byte identity 2026-10-27 12:17:29 +08:00
Rudy Mizrahi Celekliandgensokyo-dev 1cd82597da fix(browser): normalize discovery wire facts at the shared boundary (#7204)
Normalize transport-specific discovery facts at their shared owner; preserve upstream duplicate-ID rejection and correct discovery-time attachment uncertainty in all consumers.

53 focused regressions, serial static checks and real Chrome CLI/MCP fault injection/inspection pass. Greptile final head 5/5. Exact-main controls reproduce all 17 source and 21 shard-8 failures; seven shards cancelled and remain unverified. Requester authorized readiness and unrelated-main CI bypass. Human review is not attested.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 12:16:50 +08:00
morluto e334a13c79 fix(cli): merge mixed array filter selections 2026-10-27 12:14:36 +08:00
morluto effb796027 fix(evidence): validate retained views by semantic identity 2026-10-27 12:14:36 +08:00
morluto 5f9f13d77b fix(evidence): preserve view identity and cancellation outcomes 2026-10-27 12:12:34 +08:00
morluto 6de60993b8 fix(adb): retain output on command failures 2026-10-27 12:06:29 +08:00
morluto 47a8000cce fix(cli): project nested array slices 2026-10-27 12:06:29 +08:00
morluto 2f27d3ac92 fix(evidence): separate source and presentation identity 2026-10-27 12:06:29 +08:00
morluto 3e8923c6eb fix(evidence): share queued cancellation handling 2026-10-27 12:06:15 +08:00
morluto 0793b6c3ca fix(rizin): retain rejected debugger shutdowns 2026-10-27 12:06:14 +08:00
morluto f89b03e738 fix(gdb): retain rejected shutdowns for retry 2026-10-27 12:01:12 +08:00
morluto 7557e39dcd fix(providers): preserve cleanup retry diagnostics 2026-10-27 11:59:44 +08:00
morluto 0eff039d08 fix(mcp): preserve Android cleanup failures 2026-10-27 11:56:01 +08:00
morluto 5d30f82417 fix(artifacts): validate directory source spelling 2026-10-27 11:54:58 +08:00
morluto 7cc33fcf7e fix(server): preserve cleanup failure diagnostics 2026-10-27 11:52:46 +08:00
morluto 8aa6df2d86 fix(native): share otool build tool parsing 2026-10-27 11:52:21 +08:00
morluto a6a69ec63e fix(ghidra): require Windows cleanup ownership 2026-10-27 11:49:23 +08:00
morluto cd7a0eefd8 fix(apple): validate JVM interface identity 2026-10-27 11:49:22 +08:00
morluto c79bd41b5d test(hopper): verify bootstrap cleanup ownership 2026-10-27 11:45:25 +08:00
morluto 4e33bd3e08 fix(browser): preserve discovery identity ambiguity 2026-10-27 11:45:25 +08:00
morluto a486cfe518 fix(windows): validate declared PE header identity 2026-10-27 11:45:25 +08:00
morluto a116f2a7ae fix(process): close lease peers during release 2026-10-27 11:45:02 +08:00
morluto d2da713859 fix(setup): recognize inherited owned launcher 2026-10-27 11:45:01 +08:00
morluto f2277454b8 fix(setup): preserve unowned client registrations 2026-10-27 11:39:32 +08:00
morluto 4de432d868 refactor(pyinstaller): preserve parsed compression flags 2026-10-27 11:35:47 +08:00
morluto f812dc4135 fix(hopper): retain lease after startup failure 2026-10-27 11:35:46 +08:00
morluto 319fee4691 fix(electron): select nested handlers by source coordinates 2026-10-27 11:30:37 +08:00
morluto 5d5fef7391 fix(process): retain lease recovery cleanup owners 2026-10-27 11:30:35 +08:00
morluto 86d4a21215 docs(search): clarify provider case folding 2026-10-27 11:24:10 +08:00
morluto 7b25049dee refactor(browser): centralize passive source deadlines 2026-10-27 11:24:09 +08:00
morluto fe95b7611f fix(process): retain lease directory cleanup ownership 2026-10-27 11:24:07 +08:00
morluto 76eecf7fa1 fix(mcp): advertise standard route path schemas 2026-10-27 11:23:39 +08:00
morluto 081f2e2559 refactor(process): share stable file identity checks 2026-10-27 11:16:44 +08:00
morluto a18297f7d1 refactor(electron): use required native module facts 2026-10-27 11:16:43 +08:00
morluto 76441ed31b fix(browser): preserve comparison evidence identity 2026-10-27 11:15:38 +08:00
morluto 52b3c63495 fix(ida): complete private input writes 2026-10-27 11:15:38 +08:00
morluto 0d1d6e858d fix(ghidra): unify Unicode literal search semantics 2026-10-27 11:10:10 +08:00
morluto 492860ed07 test(captures): assert retained snapshot evidence 2026-10-27 11:10:10 +08:00
morluto 1635e559d2 refactor(go): simplify build metadata decoding 2026-10-27 11:10:10 +08:00
morluto 92fb319b27 refactor(gdb): reuse inferior identity reader 2026-10-27 11:10:10 +08:00
morluto 17da88f117 fix(process): report retained capture root 2026-10-27 11:08:55 +08:00
morluto 768b58c6db fix(setup): honor Droid home override 2026-10-27 11:08:54 +08:00
morluto 6207843814 fix(ida): preserve Unicode literal search matches 2026-10-27 10:59:38 +08:00
morluto e58feb48c3 refactor(mcp): reuse reverse engineering admission 2026-10-27 10:59:36 +08:00
morluto 3c0e021cb3 refactor(captures): retain SAZ member classifications 2026-10-27 10:59:35 +08:00
morluto f8f7ac96de refactor(mcp): share entropy summary delivery 2026-10-27 10:55:00 +08:00
morluto 1fdd3df7b4 fix(hopper): preserve regex inventory facts 2026-10-27 10:54:59 +08:00
morluto 82d3ab7aa8 fix(browser): respect response metadata grammars 2026-10-27 10:51:50 +08:00
morluto e4cdf65e2c refactor(mcp): share diagnostic evidence handling 2026-10-27 10:51:50 +08:00
morluto 37d6e8ca9a refactor(macho): reuse admitted header identity 2026-10-27 10:51:50 +08:00
morluto bae84d1b93 fix(native): validate plist target identity 2026-10-27 10:48:42 +08:00
morluto 0e17aab451 fix(providers): deduplicate nested cleanup notifications 2026-10-27 10:45:54 +08:00
morluto b989e3c3a3 fix(browser): parse HTTP Link whitespace correctly 2026-10-27 10:45:01 +08:00
morluto 6fa8e2ee3d refactor(node-sea): reuse Mach-O segment facts 2026-10-27 10:44:51 +08:00
morluto 79b8219f29 fix(certificates): unify OID decoding and validate reports 2026-10-27 10:40:48 +08:00
morluto f061989ad2 fix(artifacts): validate bundle resource target identity 2026-10-27 10:39:56 +08:00
morluto b7be0d90a9 fix(firmware): retain nested dependency diagnostics 2026-10-27 10:35:50 +08:00
morluto 92213a9155 test(artifacts): verify evidence refresh after reopen 2026-10-27 10:32:58 +08:00
morluto ec40c10749 refactor(process): share comparison dimension projections 2026-10-27 10:30:59 +08:00
morluto 5093d51c05 refactor(browser): share CDP script source capture 2026-10-27 10:30:57 +08:00
morluto 413f24b532 fix(artifacts): unify selected path failure classification 2026-10-27 10:30:56 +08:00
morluto 3655dfd7d5 fix(elf): validate completed note coverage 2026-10-27 10:30:54 +08:00
morluto 30216468cc fix(browser): share media type interpretation 2026-10-27 10:26:32 +08:00
morluto 4f2fc7ca28 refactor(pe): rely on path input contracts 2026-10-27 10:26:31 +08:00
morluto b0c48e8b65 fix(native): preserve mapping and literal coverage 2026-10-27 10:26:29 +08:00
morluto ded6542d93 refactor(plist): unify number source association 2026-10-27 10:22:33 +08:00
morluto b7cae1ad8c fix(artifacts): validate partial inventory edges 2026-10-27 10:19:00 +08:00
Rudy Mizrahi Celekliandgensokyo-dev 6749bd090d fix(browser): keep opaque cookie partitions unaligned (#7203)
Keep cookies with opaque partitions distinct from unpartitioned identities while retaining value hashes and incomplete comparison coverage. Preserve known partition hashes and use the existing shared CLI/MCP fingerprint owner.

Validated with 63 source and 57 storage boundary tests, builds/static checks, and real Chrome156 CLI/MCP controls. Live opaque-cookie emission was not reproduced; its protocol regression is explicit. Hosted CI's unrelated failures were reproduced against exact main a905a71e3; seven fail-fast-cancelled shards remain unverified; Greptile's sole existing-main finding was scoped and documented. Human readiness remains unasserted; bypass authorized by the requester.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 10:16:15 +08:00
morluto f53c256886 fix(macho): unify fixed-width name decoding 2026-10-27 10:15:49 +08:00
morluto 25fc08189e fix(wasm): parse interface group heads consistently 2026-10-27 10:12:38 +08:00
morluto d1c88fab1a fix(artifacts): validate partial inventory root identity 2026-10-27 10:11:49 +08:00
morluto bfdde7ee4c refactor(web): centralize isolated script paths 2026-10-27 10:05:33 +08:00
morluto 8dc4421325 fix(artifacts): reject inventory counts beyond manifest 2026-10-27 10:04:29 +08:00
morluto 9aee546aba refactor(process): unify trace outcome comparison 2026-10-27 10:03:18 +08:00
morluto c81b7ecebc fix(electron): refuse linked ASAR parent declarations 2026-10-27 10:03:17 +08:00
morluto 650873e772 fix(artifacts): preserve mounted DMG traversal coverage 2026-10-27 10:03:15 +08:00
morluto 2146caeb3d fix(electron): share ASAR node validation 2026-10-27 09:59:58 +08:00
morluto ed62f14be4 refactor(ci): consolidate lint task ownership 2026-10-27 09:55:24 +08:00
morluto 8e0b2a9765 fix(wasm): share WAT comment framing 2026-10-27 09:55:22 +08:00
morluto c1e0f531e6 fix(firmware): admit caller-selected source directly 2026-10-27 09:55:01 +08:00
morluto a905a71e31 fix(plist): preserve binary UID and dictionary identity 2026-10-27 09:49:28 +08:00
morluto f878266503 fix(artifacts): admit selected app bundle traversal 2026-10-27 09:48:52 +08:00
morluto 15a8f6847c fix(browser): reject inexact storage values 2026-10-27 09:45:11 +08:00
morluto f3a301eca5 fix(artifacts): validate selected path traversal 2026-10-27 09:45:10 +08:00
morluto 27ac1b6781 refactor(contracts): consolidate tool effect definitions 2026-10-27 09:43:10 +08:00
morluto 443d0778be fix(browser): resolve JSON pointers through array elements 2026-10-27 09:40:11 +08:00
morluto 01d6a95fd7 fix(ghidra): preserve configured seed path traversal 2026-10-27 09:39:43 +08:00
morluto 7ba1d0161e fix(browser): retain ambiguous scenario request identity 2026-10-27 09:35:59 +08:00
morluto 6979c589b0 fix(ghidra): preserve project access failures 2026-10-27 09:35:15 +08:00
morluto 6734dee6a8 fix(managed): retain comparison target cleanup ownership 2026-10-27 09:35:15 +08:00
morluto 83bbad2b2f fix(browser): advance storage pages by examined rows 2026-10-27 09:32:32 +08:00
morluto 242a0f2880 fix(evidence): retain comparison cleanup ownership 2026-10-27 09:31:17 +08:00
morluto 9be640a8b4 fix(providers): preserve selected filesystem identities 2026-10-27 09:31:17 +08:00
morluto 9eb8ba2b29 refactor(cli): use builtin argument owner directly 2026-10-27 09:29:20 +08:00
morluto 55b4efcb88 fix(providers): retain completed cleanup observations 2026-10-27 09:26:42 +08:00
morluto fef83241b1 fix(setup): validate Hopper download channel URLs 2026-10-27 09:26:40 +08:00
morluto 25b69bb803 fix(javascript): qualify network receiver evidence 2026-10-27 09:24:22 +08:00
morluto a293738c66 fix(electron): preserve symlink directory requirements 2026-10-27 09:24:22 +08:00
morluto f68b261db4 refactor(process): remove unused worker PID state 2026-10-27 09:23:20 +08:00
morluto 212479aa02 refactor(environment): reuse recorded query parser 2026-10-27 09:23:19 +08:00
morluto e2da92f5d2 fix(javascript): unify runtime module declarations 2026-10-27 09:23:15 +08:00
morluto 01484bc95c fix(setup): unify macOS version eligibility 2026-10-27 09:23:13 +08:00
morluto a52914649a fix(native): use owned address grammar for coordinates 2026-10-27 09:19:56 +08:00
morluto 4266d32751 fix(cli): retain resources from both cleanup failures 2026-10-27 09:19:54 +08:00
morluto 329325049c refactor(cli): retain typed analysis outcomes through delivery 2026-10-27 09:16:02 +08:00
morluto 0e1500dc8d fix(javascript): qualify renderer endpoint observations 2026-10-27 09:15:24 +08:00
morluto 9cad06db10 fix(managed): retain qualified native candidates 2026-10-27 09:15:24 +08:00
morluto 9c9c64edfa refactor(views): centralize paging contracts 2026-10-27 09:07:50 +08:00
morluto 5cf7133f82 refactor(javascript)!: consolidate renderer and route ownership
Remove the derived package renderer property from new application graphs. Use renderer_declarations for source fields and package loads edges for the selected candidate; previously retained Evidence remains readable.
2026-10-27 09:05:24 +08:00
morluto 39179db68d refactor(artifacts): unify inventory integrity policy 2026-10-27 09:05:18 +08:00
morluto 6d7e627783 fix(cli): preserve literal evidence in Markdown output 2026-10-27 09:04:11 +08:00
morluto bf7721080f refactor(evidence): centralize value flow metadata schema 2026-10-27 09:02:32 +08:00
morluto 5cd61aac8e fix(artifacts): preserve cancellation during inventory cleanup 2026-10-27 08:59:57 +08:00
morluto 72cc2d30a3 fix(browser): preserve request and cleanup failures 2026-10-27 08:58:27 +08:00
morluto 339b82e0c8 fix(cutter): preserve bridge directory traversal 2026-10-27 08:58:27 +08:00
morluto b2df588b4a fix(gpu): retain AMD target declaration evidence 2026-10-27 08:55:43 +08:00
morluto aa253bd13f fix(electron): scope IPC pairing to application ownership 2026-10-27 08:55:34 +08:00
morluto 781eb1b28a fix(browser): validate basic credential usernames 2026-10-27 08:52:22 +08:00
morluto 4932e5615b fix(update): preserve Bun global directory identity 2026-10-27 08:52:19 +08:00
gensokyo-devandAce d109a39105 feat(cli): validate browser scenarios offline (#7343)
Add validate-browser-scenario for offline schema and semantic checks of inline JSON, local files and stdin. Return compact validity/action/secret counts without reading secret values or discovering, launching, attaching to or navigating a browser.

Execution and validation share CLI input admission and the canonical domain schema. Preserve existing capture lifecycle, diagnostics, cancellation and caller-relative executable paths.

Integrates #7149 with attribution. Fixes #5488. Validation includes 24 focused tests, static/build/docs checks, and the preserved real PocketBase scenario with its backend stopped and secret variables unset. Verification and resource/token measurements are recorded in docs/verification/browser-scenario-validation-2026-10-27.md.

Co-authored-by: Ace <[email protected]>
2026-10-27 08:47:36 +08:00
morluto 06642a48fb fix(hopper): preserve selected home and cache paths 2026-10-27 08:47:16 +08:00
morluto e3044645c7 fix(managed): retain local signature comparison coverage 2026-10-27 08:46:31 +08:00
morluto ad92e0f9c8 refactor(ghidra): consolidate function containment lookup 2026-10-27 08:46:27 +08:00
morluto 838f5f44d2 fix(reference): preserve incomplete resolution uncertainty 2026-10-27 08:40:36 +08:00
morluto 54fbfacfb1 fix(macho): preserve leading spaces in export identities 2026-10-27 08:34:42 +08:00
morluto 0781c3e99c fix(reference): validate Git metadata path traversal 2026-10-27 08:34:42 +08:00
morluto 87d023dcc8 fix(flutter): honor cancellation after cleanup retry 2026-10-27 08:34:42 +08:00
morluto f347713e24 refactor(session): share provider replay attribution 2026-10-27 08:32:13 +08:00
morluto 6b3a081f36 fix(flutter): retain snapshot cleanup ownership 2026-10-27 08:29:29 +08:00
morluto abc1351506 fix(artifacts): distinguish incomplete PyInstaller probes 2026-10-27 08:27:08 +08:00
morluto 0ddde829b2 fix(session): preserve failed target restoration 2026-10-27 08:21:41 +08:00
morluto 3431541073 fix(views): honor cancellation before admission 2026-10-27 08:18:40 +08:00
morluto e7f29f8b8f fix(zip): validate admitted source throughout reads 2026-10-27 08:18:40 +08:00
morluto cb0c73246d refactor(artifacts): reuse admitted sources for extraction 2026-10-27 08:18:04 +08:00
gensokyo-devandEdgar Arakelyan 3fcbabe593 feat(browser): reuse saved response values across scenario steps (#7267)
Save typed response fields and reuse generated IDs or authentication values across browser scenario requests, UI observations and navigation through the shared CLI/MCP workflow.

Preserve exact numbers, retained Evidence, explicit source/coverage limits and prospective page-value semantics. Bound response decoding, retained spellings and request serialization before allocation, and protect marked response values across source records, follow-up text and planned screenshots.

Integrates Edgar Arakelyan's #7162, including follow-ups through 9f5191ab0. Final local validation: 560 feature-branch tests and 561 current-main integration tests, static/build/docs checks and real PocketBase CLI/MCP privacy workflows. Whole-task comparison and verification limits are recorded in docs/verification/browser-saved-values-2026-10-26.md.

Co-authored-by: Edgar Arakelyan <[email protected]>
2026-10-27 08:15:52 +08:00
morluto 60822e0702 fix(doctor): preserve Homebrew application paths 2026-10-27 08:11:18 +08:00
morluto ee654e98a6 refactor(artifacts): retain PyInstaller carrier dialect 2026-10-27 08:10:55 +08:00
morluto 5b8e415483 refactor(snapshot): centralize resource cache eligibility 2026-10-27 08:10:48 +08:00
morluto 5d25aa4f52 refactor(artifacts): retain admitted Godot pack location 2026-10-27 08:06:23 +08:00
morluto 69b328eec8 test(browser): verify out-of-order response correlation 2026-10-27 08:04:42 +08:00
morluto 8c8a2752c0 refactor(artifacts): retain admitted PyInstaller cookie facts 2026-10-27 08:02:51 +08:00
morluto 9222526fe2 fix(electron): retain selected scenario paths in evidence 2026-10-27 08:02:45 +08:00
morluto 68533bc0a3 refactor(evidence): share subject architecture declarations 2026-10-27 07:57:37 +08:00
morluto 2ad599dace fix(snapshot): export only target-bound observations 2026-10-27 07:55:16 +08:00
morluto 7fa54e2d62 fix(process): preserve command completion and input ownership 2026-10-27 07:55:16 +08:00
morluto 8a47cbbcce fix(artifacts): deduplicate keyed archive selector choices 2026-10-27 07:54:09 +08:00
morluto b8f58fd7ca refactor(mcp): bind summary delivery to tool contracts 2026-10-27 07:54:01 +08:00
morluto eb24da4481 fix(session): retain unknown cleanup across mixed failures 2026-10-27 07:53:54 +08:00
morluto 25a08ed639 refactor(ida): reuse bounded registration reader 2026-10-27 07:45:45 +08:00
morluto 11b025ef97 fix(session): retain cleanup ownership during failed opens 2026-10-27 07:45:39 +08:00
morluto d1202c539d fix(web): preserve Next route filename patterns 2026-10-27 07:44:04 +08:00
morluto 5261340397 fix(evidence): retain analysis view environment 2026-10-27 07:44:04 +08:00
morluto ecd22c42ac fix(firmware): retain completed command failures 2026-10-27 07:44:04 +08:00
morluto 84a54b6183 fix(asar): preserve header filename identity 2026-10-27 07:44:04 +08:00
morluto 046c4ce353 fix(javascript): preserve native export facts in comparisons 2026-10-27 07:40:55 +08:00
morluto c74059d89f fix(javascript): preserve unknown Next package ownership 2026-10-27 07:40:45 +08:00
morluto 6a9911ea77 fix(session): track retained bundle cleanup dependencies 2026-10-27 07:40:40 +08:00
morluto e80fb638be fix(web): retain source-map declaration provenance 2026-10-27 07:35:13 +08:00
morluto 59a70adefd fix(artifacts): preserve source and coverage facts 2026-10-27 07:35:13 +08:00
morluto 95d9d51f72 fix(process): retain failures through finalization 2026-10-27 07:35:13 +08:00
morluto 381004b664 fix(decompile): preserve provider cleanup through export finalization 2026-10-27 07:34:22 +08:00
morluto af9bc3ab50 fix(ci): validate static evidence through receipt owner 2026-10-27 07:29:57 +08:00
morluto 87e2cc26d8 fix(environment): align comparison collection identity 2026-10-27 07:28:49 +08:00
morluto 29ebd67405 fix(native): retain cleanup failures across capability fallback 2026-10-27 07:25:23 +08:00
morluto 0e578d43c8 refactor(native): retire legacy provider output wrappers 2026-10-27 07:25:08 +08:00
morluto 8706068b57 fix(contracts): validate provider boundary facts consistently
Count only canonical inventory rows in binary overview, reuse the owned Objective-C coverage schemas, and share firmware input issue projection.
2026-10-27 07:19:46 +08:00
morluto 57d0ed45f7 fix(process): retain inherited pipes on output overflow 2026-10-27 07:17:10 +08:00
morluto 0dea08fb07 fix(web): interpret encoded Next route paths 2026-10-27 07:17:10 +08:00
morluto 087acf26e8 fix(evidence): own cached snapshot data 2026-10-27 07:17:10 +08:00
morluto 08f99dbaf2 fix(setup): preserve and validate selected JEB endpoints 2026-10-27 07:17:10 +08:00
morluto dbe2c97af3 refactor(ownership): consolidate snapshot and comparison facts
Retain authenticated immutable snapshot payloads while keeping mutable exports independent. Derive artifact metadata comparisons once and reuse the owning native trace limits.
2026-10-27 07:13:32 +08:00
morluto 3052a067a3 fix(apple): derive NIB hierarchy from observed relationships
Replace overlapping traversals with one bounded relationship owner. Preserve superview direction, treat conflicting or unsupported registry placement as unknown, and retain source facts and coverage.
2026-10-27 07:09:25 +08:00
morluto db0908a732 refactor(artifacts): consolidate projection and PCK interpretation
Keep historical inventory summary variants with their projection owner and share embedded PCK trailer observations while preserving each reader’s admission policy.
2026-10-27 07:09:05 +08:00
morluto 077de92594 fix(setup): preserve selected Hopper loader arguments 2026-10-27 07:03:11 +08:00
morluto 2dd2ffcd45 fix(artifacts): bind operations to admitted sources 2026-10-27 07:03:11 +08:00
morluto ace4dbf36e fix(contracts): align live target classification with admitted facts
Share exact live target variants across open and session responses, preserving historical Evidence and snapshot admission. Consolidate equivalent ELF metadata aliases at their owner.
2026-10-27 06:53:47 +08:00
morluto fc7f042c8c refactor(lifecycle): require cleanup for offline providers
Require resource-owning provider ports to expose cleanup and migrate test adapters to delegate or explicitly close their own resources.
2026-10-27 06:49:07 +08:00
morluto b529bd84d7 refactor(contracts): preserve named output schema types
Keep exact readonly schema maps and constrain contract factories to their owned keys. Verify named catalog lookups retain each schema type.
2026-10-27 06:48:55 +08:00
morluto 248133d784 fix(analysis): interpret provider and ELF inputs once
Pass parsed MIPS program declarations to shared-load analysis and validate IDA string address selectors before enumeration, including empty inventories.
2026-10-27 06:48:48 +08:00
morluto 030fa886f9 fix(setup): verify published configuration content during uninstall
Require publication readback in the owning check so in-place edits are detected and preserved with the original backup.
2026-10-27 06:43:53 +08:00
morluto 82fd223638 refactor(native): consolidate provider-neutral analysis contracts
Move shared function, dossier, inventory, reference and output semantics from the legacy Hopper module to native domain owners. Migrate provider, adapter, test and verifier consumers directly.
2026-10-27 06:43:53 +08:00
morluto a6488a96a9 fix(javascript): preserve renderer path anchors 2026-10-27 06:43:07 +08:00
morluto d0e695b42a fix(hopper): bind relative launcher paths once 2026-10-27 06:43:07 +08:00
morluto 90475ec9e5 fix(artifacts): retain selected keyed archive paths 2026-10-27 06:43:07 +08:00
morluto d60b2cab65 docs(ida): document migration from legacy attached registrations
Describe the native plugin setup, identity and capability differences, verification, and rollback. Link the migration from the packaged skill source.
2026-10-27 06:38:51 +08:00
morluto ed6668b5bc fix(evidence): validate process captures before bundle export
Reuse the read-side capture validation before publication so exported bundles can be imported. Preserve historical and foreign record identity and existing destination files on failure.
2026-10-27 06:36:31 +08:00
morluto 50717c39b6 refactor(contracts): consolidate provider and search ownership
Resolve IDA compatibility facts in one place and migrate capability, session, and verifier consumers. Move native search fields to the domain and reuse residual unknown fields for filters.
2026-10-27 06:36:24 +08:00
morluto 567ea4b1e8 refactor(ownership)!: consolidate legacy aliases
Migrate schema, installer, ASN.1, and tooling consumers to their owning definitions. Remove the redundant CI task entry and the deprecated Cutter command-local JSON flag.

BREAKING CHANGE: Replace Cutter --json=true or --json=false with --json-output=true or --json-output=false. Bare --json still controls CLI result formatting.
2026-10-27 06:31:23 +08:00
morluto 7c8eb63fcc fix(javascript): retain package entrypoint provenance 2026-10-27 06:28:15 +08:00
morluto c27560e434 fix(artifacts): classify selected package names 2026-10-27 06:28:15 +08:00
morluto 3515b26221 refactor(ownership)!: remove redundant aliases
Use canonical owners for literal matches, tool families, MCP schema presentation and IDA protocol selection; remove unused web-bundle reexports. Remove the duplicate CLI command name and keep the canonical compare workflow.

BREAKING CHANGE: rea compare-bundles has been removed. Use rea compare instead. The MCP compare_bundles tool is unchanged.
2026-10-27 06:27:10 +08:00
morluto c4cdb7658b fix(jeb)!: preserve engine refusal diagnostics
Parse JEB failure envelopes at the provider boundary and retain the original response, recovery facts, and selected inputs. Do not infer an unsupported target from undocumented error codes; preserve completed primary observations when metadata requests fail.

BREAKING CHANGE: JEB engine refusals now report execution_failure rather than unsupported_target. Consumers should inspect the retained upstream diagnostics for the engine's reason and recovery facts.
2026-10-27 06:22:10 +08:00
morluto 7f65617064 fix(artifacts): resolve historical retained summaries
Authenticate exact retained parents against current and documented historical summary projections, including caller-selected display paths. Keep source facts, Evidence commitments and unsupported-projection rejection intact.
2026-10-27 06:21:50 +08:00
akushonkamenandgensokyo-dev c6893d1ac6 fix(browser): preserve external defaults during CDP attachment (#7188)
Attach to external browsers without implicit default-context overrides, and own temporary focus only on the selected page. Preserve unrelated page media and exact page inventory through CLI/MCP. Remove bootstrap-page retries; retain late/failed cleanup ownership and verified SDK notices.

Assisted-by: Kogasa (gensokyo-skills:kogasa-surprise-testing)
Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 06:16:14 +08:00
morluto 779d548c4e fix(artifacts): preserve selected ASAR companion paths 2026-10-27 06:12:41 +08:00
morluto e891926534 fix(artifacts): compare Node SEA member declarations
Compare each retained member's exact runtime key and role without treating archive order as semantic identity. Keep one-sided legacy declaration gaps unknown, preserve proven changes with unavailable content, and retain original Evidence.
2026-10-27 06:06:27 +08:00
morluto 60834e391c fix(artifacts)!: compare ASAR storage declarations
Record packed and unpacked ASAR file declarations at the reader boundary and compare known storage changes without treating historical omissions as packed. Preserve known differences when bytes are unavailable and retain existing integrity precedence.

BREAKING CHANGE: ASAR file occurrences may now contain unpacked: false. Consumers that validate only true must accept an optional boolean; absent historical fields remain unknown.
2026-10-27 05:59:40 +08:00
morluto 83b2d16ee9 fix(javascript): distinguish HTML script loads from data 2026-10-27 05:57:26 +08:00
morluto 8694dc30d9 fix(hopper): discover linked application bundles 2026-10-27 05:57:26 +08:00
morluto 67b9181010 fix(ida): separate function identity from source span
Normalize function address and name without requiring an unused upstream size. Preserve complete upstream observations and the explicit unknown body coverage across IDA protocol profiles.
2026-10-27 05:52:15 +08:00
morluto 81adb8977a fix(ghidra): honor current directory in PATH discovery 2026-10-27 05:49:17 +08:00
morluto e1ec737d9b refactor(artifacts): share extraction admission and reader construction
Reuse completed embedded-format observations only after validating the admitted file identity and state, and centralize reader construction across inventory and extraction. Preserve early refusal, selected-path checks, ZIP ownership, and each operation's traversal policy. A source changed between preflight and inventory now fails integrity validation.
2026-10-27 05:46:25 +08:00
morluto 3a6e4f2cb1 fix(managed): report graph method page coverage 2026-10-27 05:42:50 +08:00
morluto 19f9011511 fix(setup): honor VS Code user data overrides 2026-10-27 05:42:50 +08:00
morluto 52414282b9 fix(xrefs): trust provider address validation
After an invalid address-format result, resolve the caller's exact symbol instead of reclassifying address-like names with a separate heuristic.
2026-10-27 05:37:55 +08:00
morluto 4191974010 fix(environment): share retained response declarations
Preserve status independently of malformed content and use one declaration reader for route grouping, state extraction and manifest eligibility. Verify the partial facts through CLI and MCP views.
2026-10-27 05:37:47 +08:00
morluto 5f91616727 fix(hopper): confirm private display probe cleanup 2026-10-27 05:36:09 +08:00
morluto b6e58c22d4 fix(evidence): retain source and stream ownership 2026-10-27 05:36:09 +08:00
morluto 4803c4f9c2 fix(setup): preserve selected settings and Java paths 2026-10-27 05:36:09 +08:00
morluto 47fa4fbad6 fix(views): bind Mach-O rows to selected facets
Derive each facet's row schema from the Mach-O producer and validate it against the requested page. Preserve the existing wire shape and historical defaults.
2026-10-27 05:33:10 +08:00
morluto 06c8e14b34 fix(native): retain lipo field declarations
Distinguish omitted slice fields from declarations that cannot be interpreted, and preserve their source in native results and artifact limitations. Keep structural fallback and capacity failures explicit.
2026-10-27 05:33:01 +08:00
morluto ca3fd7baf9 fix(javascript): preserve artifact failures through cleanup 2026-10-27 05:23:53 +08:00
morluto 8b7ee48a46 fix(kuna): bind cache exports to their producing inputs 2026-10-27 05:23:53 +08:00
morluto 906f161dc6 fix(environment): share legacy recorded-time interpretation
Use one owner for exact recorded timestamps and documented native-Date fallback in state and probe replay. Retain the source and disclose native precision and host-timezone dependence in state limitations.

Validated historical chronology, timezone and unknown-duration regressions against prior behavior.
2026-10-27 05:19:43 +08:00
morluto 63220edcc3 fix(environment)!: withhold clock writes without an anchor
Keep missing or ambiguous scenario request durations unknown, retain learned clock rules, and withhold plans that cannot generate an observed clock. Refuse such writes in older imported states before changing state or generators.

BREAKING CHANGE: The write-plan reason can now be unknown-clock; strict clients must accept the new output value.

Validated state, CLI and advertised MCP workflows, documentation, and focused clock and cleanup regressions.
2026-10-27 05:19:35 +08:00
morluto 19b2972dfb fix(environment): separate request order from completion
Retain valid request starts independently of duration and require observed completion for interval-based state and write inferences. Bound indexed interference checks across captured writes while preserving ordinal fallback and unmodified Evidence.

Validated state, comparison, CLI and MCP workflows with known, unknown, overlapping and redacted timing controls; check:fast passed.
2026-10-27 05:08:14 +08:00
morluto 3233992733 fix(browser): redact startup cleanup diagnostics 2026-10-27 04:59:27 +08:00
morluto 855eb703af perf(setup): wait directly for prewarm completion 2026-10-27 04:59:27 +08:00
morluto d815367a11 fix(analysis): preserve failure and cleanup outcomes 2026-10-27 04:59:27 +08:00
Chip Liandgensokyo-dev 4767970105 fix(artifacts): explain recovery for existing DMG attachments (#7221)
Preserve producer-supported recovery guidance after an existing-image DMG attachment refusal, without borrowing or detaching existing mounts. Keep diagnostics, root provenance and unknown coverage; centralize guidance ownership and run the real mounted-image regression in macOS CI.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 04:58:43 +08:00
吴佳浩Alben 9e6dd8e372 docs(desktop): name the get_evidence_bundle tool in the MCP section (#7266)
The collection-paging paragraph says complete Evidence stays accessible through
`get_evidence`, but no tool by that name exists. The session family registers
`get_evidence_bundle`, which is the only name the catalog, the contracts and the
CLI equivalents use.

Every other page already uses the full name, so this was the only place a reader
or agent would look for a tool that cannot be called.
2026-10-27 04:56:17 +08:00
Saim Shafiqueandgensokyo-dev 0d1a454e25 fix(ghidra): admit newer 12.x releases as compatible builds (#6924)
Admit same-major Ghidra releases at or above the verified minor through the existing compatible/unverified policy. Preserve the observed version, verified12.1.4 pin, installation-declared Java floor and separate NativeAOT verification gate.

367 targeted tests/static/docs, all10 real Java bridge-source compilation, and actual Linux12.2/JDK25 CLI/MCP queries and cleanup pass. JDK21 remains refused for12.2. Exact-main controls reproduce all3 unrelated CI assertions; canceled shards and an apt-blocked binary-layout lane remain unverified.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 03:49:12 +08:00
morluto dd7a2da5bb fix(environment): keep invalid recorded dates unknown
Distinguish invalid supported timestamp spellings from unrecognized legacy formats at the recorded-date owner. Probe replay retains ordinal order for invalid dates without changing the existing legacy fallback.

Validated date parsing, state ordering and comparison workflows; the prior implementation reorders the invalid-date regression.
2026-10-27 03:29:11 +08:00
morluto 4e86bd0c1c fix(asar): disclose unverified block integrity
Retain a limitation when ASAR block integrity fields are present. Whole-file hash verification does not establish block verification or Electron runtime acceptance.

Validated inventory and extraction workflows, including partial and malformed block declarations.
2026-10-27 03:29:05 +08:00
morluto 4bbd87953f fix(environment): align recorded probe chronology
Use the shared recorded timestamp interpretation for replay ordering, including exact fractions and UTC interpretation of supported zone-less forms. Preserve native-Date fallback for unsupported historical spellings.

Validated environment comparison, state ordering and CLI tests; five new cases reproduce prior drift.
2026-10-27 03:25:06 +08:00
morluto 1008d5e302 fix(asar): retain unsupported integrity declarations
Carry reported algorithms and hashes into listing limitations when the declaration cannot be compared, retaining the existing verification and extraction policies. Bound escaped text before allocation.

Validated ASAR inventory, extraction, cleanup and MCP workflows; prior code omits the declaration details.
2026-10-27 03:25:06 +08:00
morluto 3a65ef0e4c fix(browser): redact scenario cleanup diagnostics 2026-10-27 03:23:50 +08:00
morluto f1535a1753 fix(artifacts): retain archive streams and source receipts 2026-10-27 03:23:50 +08:00
morluto ca75643dbc fix(setup): preserve registration choices and own prewarm 2026-10-27 03:23:50 +08:00
morluto 3ca1cc5466 fix(filesystem): complete plist and limits probes
Read bounded plist format probes and Linux resource-limit reports through positive short reads before classifying their contents. Preserve explicit EOF, report capacity, physical failures and descriptor cleanup ownership.

Validated 66 focused tests and check:fast; nine new fault-injected cases fail against the previous implementation. Linux procfs was not verified on a real Linux host.
2026-10-27 03:18:56 +08:00
morluto 615fbbbdd7 refactor(mcp): consolidate evidence tool execution
Share provider availability, admission, logging and Evidence delivery across browser, Electron and runtime tools. Reuse retained summary delivery for Python and BEAM selected views while preserving preflight and complete parent Evidence.

Validated 47 focused MCP and retained-view acceptance tests and check:fast.
2026-10-27 03:14:24 +08:00
morluto a7004c7df1 fix(filesystem): finish executable and project span reads
Reuse the positional range owner for target metadata, Hopper Mach-O selection and Kuna spans. Preserve physical failures, completed span evidence and cleanup ownership across cancellation and short reads.

Validated 147 focused file and lifecycle tests; ten new cases reproduced failures against the prior implementation.
2026-10-27 03:14:14 +08:00
morluto f68064e46c fix(evidence): exclude sensitive publication identities 2026-10-27 03:12:22 +08:00
morluto 5da50ab3f4 fix(artifacts): retain reader work through cleanup 2026-10-27 03:12:22 +08:00
SII-YDDandgensokyo-dev d4c511ae6e fix(javascript): honor effective symbolic descriptor values (#7222)
Resolve ordered descriptor values at the shared JavaScript fact owner and preserve uncertain intrinsic writes instead of stale exports. Normalize ordinary method values and reuse canonical primitive, prototype, ambient identity and ordering facts across consumers.

384 selected tests, format/static/docs checks, all final CI jobs and reviews pass. Actual Node controls cover 35 bundles; one possibly repeated factory explicitly stays unknown. Shipped Obsidian selected-source complete Evidence matches base/fixed CLI and MCP, with coverage and resource measurements in the PR.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-27 03:08:00 +08:00
morluto d54f5b07b4 fix(artifacts): complete positional reads across short results
Continue reading Mach-O and Electron ranges after positive short descriptor reads, while preserving explicit EOF, cancellation, file identity and cleanup semantics. Advance fuse scanning and hashing by the bytes actually read.

Validated focused filesystem, Mach-O, dyld, Electron and MCP workflows: 117 tests passed, two Windows-only tests skipped; check:fast passed.
2026-10-27 03:07:24 +08:00
morluto 64f053ab63 chore: remove unused internal exports 2026-10-27 03:02:38 +08:00
morluto 347494f3ab fix(captures): preserve cleanup ownership and sensitive evidence 2026-10-27 03:02:38 +08:00
morluto 7a237aa721 refactor(views): share immutable result readers
Use the common analysis-view reader for Rust and native inventory validation, preserving historical defaults and original Evidence while retaining schema-specific validation.

Validated 123 focused view and service tests and check:fast.
2026-10-27 03:02:09 +08:00
morluto bab49aaf7c refactor(artifacts): unify stable read failure ownership
Centralize completed file observations and cleanup error projection across stable-file providers while preserving each provider’s failure classification and exact cleanup leases. Cover BEAM finalization cancellation and devicetree cleanup retries.

Validated 223 focused lifecycle and MCP tests and check:fast.
2026-10-27 03:02:05 +08:00
morluto 99ff4344c0 fix(browser): centralize CDP network event facts
Parse shared request and response fields at the CDP boundary while preserving capture, session and runtime admission policies. Treat empty request IDs as unknown so unrelated events cannot be joined, and retain redirect occurrences and partial response evidence.

Validate 221 focused tests, fast checks, and real Chrome network and runtime verifiers.
2026-10-27 02:57:58 +08:00
morluto df6db781dd refactor(pyinstaller): centralize CArchive member roles
Derive member roles at the table-of-contents boundary and share declaration and Python-module interpretations across validation, projection, metadata, header reconstruction and nested PYZ traversal. Retain source type codes and generic-file behavior for other printable types.

Validation: 217 focused archive, CLI and MCP tests passed, including mixed-role byte and metadata checks. Typecheck and lint passed.
2026-10-27 02:52:25 +08:00
morluto afc79add7e fix(providers): bind signal and capture configuration per operation 2026-10-27 02:47:25 +08:00
morluto 416f16e2ed fix(managed): unify metadata row and coded-index ownership
Share Field scalar facts and use one coded-index tag registry for widths and decoding. Preserve reserved constructor tags, generic-instantiation restrictions, heap failure order and selected-field signature admission.

Derive native import member kind from the validated MemberForwarded coordinate independently of name lookup, retaining known field or method identity when its display name is unreadable.

Validation: 368 focused source, CLI and MCP tests passed; five lost-kind regressions reproduced on the previous commit. Heap-width, coded-width, reserved-tag and selection boundaries are covered. Typecheck and lint passed.
2026-10-27 02:46:26 +08:00
morluto 741f2de751 test(ci): align source preservation and catalog assertions 2026-10-27 02:35:54 +08:00
morluto b4b5c37ab3 fix(web): retain admitted provenance through incomplete traces 2026-10-27 02:35:54 +08:00
morluto f6478c056f fix(providers): keep each inspection on one environment snapshot 2026-10-27 02:35:54 +08:00
morluto 1f5c5c31c1 refactor(managed): centralize method implementation flag facts
Have the MethodDef row owner derive code type, managed kind and the P/Invoke flag for both body decoding and native-boundary inventory. Remove duplicate masks and unreachable fallbacks while preserving raw flags, zero-RVA precedence and ImplMap-specific declaration policy.

Validation: 280 focused source, CLI and MCP tests passed, including cross-workflow flag combinations and declaration/body policy boundaries. Typecheck and lint passed.
2026-10-27 02:34:59 +08:00
morluto 8ced814b96 fix(browser): unify script and context attribution facts
Centralize CDP script/context declarations and frame-claim interpretation across web capture, Electron, V8, active runtime and storage seeding. Preserve each workflow's admission, provenance and retention policies while removing superseded helpers and schemas.

Malformed or conflicting frame claims now leave passive scripts unattributed. Reused context IDs replace future frame authority without rebinding earlier scripts, and source readers reject empty script IDs.

Validation: 153 focused tests and check:fast passed; 13 regression failures reproduced on the prior commit. Real Chrome script export and runtime CLI/MCP verifiers passed, including correctly reported uncertain cleanup after intentional target closure. Electron regression coverage used simulated CDP.
2026-10-27 02:30:04 +08:00
morluto ff568afa34 refactor(artifacts): retain Node SEA admission facts through inventory
Pass validated blob location and decoded metadata with their admitted descriptor from classification to the reader. Keep root cleanup ownership, freshness checks, format validation order and direct-reader decoding intact, then release borrowed facts after preparation.

Validation: 147 focused source, CLI and MCP tests passed, including real Node blob production; check:fast passed. Optional injected-ELF Docker verification was unavailable because the Docker daemon is not running.
2026-10-27 02:20:00 +08:00
morluto 55f72b5d53 fix(workers): preserve failure receipts and their cleanup owners 2026-10-27 02:16:08 +08:00
morluto 82af5b5f52 fix(web): retain completed file identities across acquisition failures 2026-10-27 02:16:08 +08:00
morluto 620690c923 refactor(firmware): unify extraction problem interpretation
Derive dependency and generic-error facts once per owning task, chunk or multifile stage. Reuse those facts for failure classification and dependency aggregation, preserving unnamed identities, severity precedence and raw diagnostics.

Validation: 70 focused tests passed; 41 platform-guarded tests skipped on macOS. Typecheck and lint passed. Real Unblob/Linux provider behavior was not run.
2026-10-27 02:14:45 +08:00
morluto d06ca092fb refactor(python): consolidate bytecode identity across readers
Share CPython magic framing, version and header facts while keeping standalone marshal coverage and PyInstaller reconstruction eligibility distinct. Preserve legacy headers, opaque unknowns and source bytes.

Validated 272 focused tests across source, CLI and MCP workflows, a 38-test reader recheck, and check:fast.
2026-10-27 02:09:52 +08:00
morluto 669e617eec fix(sqlite): preserve completed member facts on acquisition failure 2026-10-27 02:02:27 +08:00
morluto e813c4c344 fix(pwntools): separate reply admission from debugger enrichment 2026-10-27 02:02:27 +08:00
morluto d77cf61866 fix(evm): retain admitted evidence through reply finalization 2026-10-27 02:02:27 +08:00
morluto 3b4c910fff fix(browser): unify CDP frame and document identity facts
Parse each frame event using its declared protocol fields and retain loader and ancestry only across same-document updates. This removes alias-based attribution, invalidates malformed committed frame facts, and prevents stale WebMCP tools surviving a same-URL document replacement.

Migrate Electron, screenshot, capture, timeline, and execution consumers to the shared facts owner and retire the old helper exports. Validated 428 focused tests, test discovery, typecheck/lint, and real Chrome CLI/MCP network capture; Electron and WebMCP regressions use simulated CDP.
2026-10-27 02:00:58 +08:00
morluto 624ebb2a1e refactor(elf): consolidate bounded string-table interpretation 2026-10-27 01:46:08 +08:00
morluto e405d685bc refactor(macho): centralize dylib command and string facts 2026-10-27 01:38:20 +08:00
gensokyo-devandHarsH 6d5532a204 feat(web): page retained bundle endpoint observations and inferences (#7259)
Page retained web-bundle endpoint observations and inferences through shared CLI/MCP projections, preserving source identities, scoped unknowns, coverage and complete Evidence access.

Based on HarsH’s original implementation in #7213 (6b1d5d42). Real Chromium/CLI/SDK verification and whole-task cost limits are recorded in docs/verification/web-bundle-paging-2026-10-26.md.

Explicit user authorization permits leaving human-readiness declarations unchecked and bypassing reproduced main failures (ADB listing fixture, package catalog expectation, untouched APK verifier formatting). No human-review attestation is made.

Co-authored-by: HarsH <[email protected]>
2026-10-27 01:37:39 +08:00
morluto c09fa01b37 refactor(managed): centralize MemberRef row facts 2026-10-27 01:29:43 +08:00
morluto 939009f6f9 fix(artifacts): preserve completed caller reads through finalization
Retain file identity after Rust, web artifact, shared selected-input and historical capture reads complete before close or cancellation fails. Preserve descriptor-set snapshots in diagnostics alongside sanitized capture observations.

Classify canonical physical capture failures before cleanup composition; source permission errors and bare syscall failures keep their meaning through late cancellation and retry. Keep explicit sensitive-value redaction on retained facts.

Validation: 247 focused cases passed, two Linux-only cases skipped; build, typecheck, lint and formatting passed. Real descriptors with controlled finalization faults establish reader ownership and facts. Worker reply and multi-file database completion semantics remain separate audit work.
2026-10-27 01:27:03 +08:00
morluto 31e8492faf refactor(artifacts): centralize completed snapshot observations
Normalize completed stable-file path, digest and length in one shared observation owner. Migrate thirteen identical provider projections while preserving their selected paths, schema checks and cleanup composition.

Keep specialized metadata and worker reply observations at their existing owners. Validation: shared real-descriptor coverage and provider lifecycle tests passed; build, typecheck, lint and formatting passed.
2026-10-27 01:27:03 +08:00
morluto 1ce9f317be refactor(pyinstaller): centralize PYZ member role ownership 2026-10-27 01:21:11 +08:00
morluto 662ec2e450 fix(verifiers): preserve source Evidence through shared admission 2026-10-27 01:11:51 +08:00
morluto f6805e29c3 refactor(pe): centralize resource tree facts across readers 2026-10-27 01:02:21 +08:00
morluto 9d2c087d83 fix(readers): preserve completed snapshots through cleanup retries
Retain exact completed file path, digest and length in Python pyc and Erlang BEAM failure observations. Translate Python close failures at the provider boundary and bind them to the retained descriptor cleanup leases so later successful retries resolve prior errors.

Exercise actual services and file handles with completed reads, cancellation during finalization and physical read failure followed by cancellation. Assert no fabricated snapshot on early failure and resolution of every prior cleanup report.

Validation: six focused descriptor regressions plus existing filesystem, parser and MCP coverage passed; build and static checks passed. Authored format fixtures establish portable reader behavior, not CPython/Erlang runtime execution.
2026-10-27 01:01:19 +08:00
morluto 74d5cab372 fix(native): account export and version text in UTF-8 bytes
Count retained UTF-8 text rather than UTF-16 code units, including exact-byte base64 spellings. Bound the decoded version-name map independently from output expansion, releasing replaced entries from its live storage charge.

Add real service/provider boundary controls for accepted and over-budget symbol names, version names and unused version metadata. Existing per-string bounds remain the allocation owner.

Validation: native parser, filesystem and CLI/MCP views passed; build, typecheck, lint and formatting passed. No serialized-report size cap, OOM reproduction or performance improvement is claimed.
2026-10-27 01:01:10 +08:00
morluto 3d74c480e0 fix(verifiers): consolidate Ghidra MCP result admission 2026-10-27 00:49:27 +08:00
morluto 60b55be7e7 fix(native): bound PE export names before intermediate retention
Charge PE alias names when storing them, before target interpretation can suppress output rows. Validate unused-slot names as bytes without retaining or decoding strings. Keep row and forwarder accounting separate so names are charged once.

Preserve alias ordering, malformed unused-name issues and ordinal-only suppression. Add production service/provider retention regressions using compact shared-pointer fixtures.

Validation: 43 focused parser, filesystem, CLI and stdio MCP tests; fresh build, typecheck, lint and formatting passed. Three bounded Node 24.22.1 measurement pairs showed median process RSS high-water 154000 to 93168 KiB; timing and sampled family memory have cache/startup/sampling limits. No Windows loader acceptance or OOM reproduction claim.
2026-10-27 00:40:35 +08:00
morluto 0973649cec refactor(captures): consolidate recorded exchange body facts 2026-10-27 00:38:06 +08:00
morluto c2b0c955cd fix(workers): reject malformed UTF-8 in JSON result files 2026-10-27 00:28:42 +08:00
morluto 1d32eb3aa4 fix(providers): keep operation environments consistent through launch
Capture one environment snapshot per admitted WABT, JADX, firmware and Wakaru operation. Use it for tool selection, session identity and child launches while preserving configuration updates between operations.

Regressions reproduce changed JVM options under an old session key, mixed engine/limiter selection and environment drift between subprocesses. Keep selected-wrapper and cleanup coverage in a shared fixture with separate scenarios.

Validation: 115 distinct focused tests passed across the final five-file selection, including seven selected-command cases after refactoring. Fresh build, typecheck, lint and formatting passed. Tests use real subprocess fixtures; no real JADX/WABT/Binwalk/Wakaru engine or native Windows verification is claimed.
2026-10-27 00:25:43 +08:00
morluto 2cdc8cb92e refactor(managed): centralize TypeDef row facts across consumers 2026-10-27 00:21:00 +08:00
morluto 8423c5c6d0 refactor(macho): consolidate prefix interpretation across readers 2026-10-27 00:13:36 +08:00
gensokyo-dev 5508b2affd fix(analysis): retain source evidence through directory exports (#7250)
Retain authenticated provider source records independently of snapshot replay eligibility and return them explicitly to plain application callers, including late cancellation. CLI/MCP commit source records before delivering links; function dossiers share the canonical Evidence constructor. Keep directory replies compact and preserve successful retry verification.

Real Ghidra CLI/MCP investigations verify 652-function ls, historical report provenance, cross-session resume, unchanged source/project content and complete offline Evidence. Final full 14,338-function libcrypto comparison matches all metadata/pseudocode facts and independent fresh-import observations: 14,194 written, 143 external, one recorded deadline; 494.03 s, 445.63 CPU s, 1.584 GiB sampled family peak under 2-CPU/8-GiB guards, with no OOM or cleanup failure.

144 focused tests and static/docs/site checks pass; latest-main integration passes 289 cases plus typecheck/lint and actual CLI snapshot source retrieval. Final CI source/static/build/docs/quality/package checks pass. Four ADB shard failures also occur in main CI 40349559391; cancelled coverage remains unverified and author declarations stay unchecked under the user's explicit bypass authorization. No human-review attestation is made.
2026-10-26 23:56:03 +08:00
morluto 13fba271e6 refactor(plist): centralize binary layout and offset ownership 2026-10-26 23:51:33 +08:00
morluto d27e3f8e89 fix(native): preserve import names across dyld text formats
Parse literal import framing and retain ambiguous boundaries. Consult undefined symbol-table names only when needed to distinguish producer spacing, with import and export captures owned separately.

Validation: 59 native tests passed and real Apple tools on inert arm64 fixtures reproduced the old loss and verified the fix. Fresh build, typecheck and lint passed. Small warm-task median elapsed was unchanged; cold costs and agent tokens were not measured.
2026-10-26 23:50:10 +08:00
morluto ab44487ff8 fix(adb): preserve process names and pin fixture interpreters
Consume Toybox’s single NAME separator without stripping source whitespace. Keep MCP subprocess fixtures independent of ambient PATH and validate calls through the existing named-schema helper.

Validation: focused ADB provider/parser and MCP tests passed; no real Android device was used.
2026-10-26 23:50:10 +08:00
YingNingandgensokyo-dev 4da7e46e9c fix(provider-selection): name whether a rejection came from availability or target support (#7220)
Distinguish local provider readiness failures from target-support refusals in shared CLI/MCP diagnostics, preserving original codes and evidence. Avoid claiming configured providers are unconfigured.

120 focused tests, static/docs checks and real ELF CLI/MCP verification pass. Hosted CI has the same four ADB failures as exact main d9908fd7a; three canceled shards remain unverified. Merge uses the user's explicit authorization to bypass proven main failures. Fresh Codex and Greptile reviews are clear.

Fixes #7214

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-26 23:49:11 +08:00
morluto a5ad164283 fix(browser): unify worker target admission across capture workflows 2026-10-26 23:44:08 +08:00
morluto cadd5b75b3 refactor(elf): consolidate header and section-name interpretation 2026-10-26 23:40:04 +08:00
morluto 81add3d23d refactor(pyinstaller): centralize PYZ header and version facts 2026-10-26 23:33:54 +08:00
morluto d9908fd7a4 refactor(ghidra): consolidate function and inventory admission 2026-10-26 23:27:43 +08:00
morluto b45a83368c fix(ci): preserve lint diagnostics without source locations 2026-10-26 23:21:57 +08:00
morluto 65819e8cc5 fix(pcap): capture provider environment once 2026-10-26 23:21:57 +08:00
morluto a7aad91320 fix(firmware): preserve report metadata before semantic validation 2026-10-26 23:21:57 +08:00
Wenyu Chiou 625e32744e fix(javascript): ignore async exec stdio options (#7087)
Respect Node asynchronous exec/execFile method-default stdio instead of interpreting an ignored option. Remove the superseded callback-shape query while preserving caller input, Evidence, uncertainty, argv and fork controls. Independently validated on current main through actual Node pipe capture, matching real-app CLI/MCP facts, 81 targeted tests and static checking. Closes #7217.
2026-10-26 23:16:28 +08:00
morluto a84e0cfcfe refactor(verifiers): consolidate capture result admission and parity 2026-10-26 23:12:34 +08:00
morluto 99062feaa7 test: bind MCP validation and cleanup faults to selected inputs 2026-10-26 23:06:36 +08:00
morluto fef76a02fb fix(apple): preserve own artifact metadata through schema projection 2026-10-26 23:06:36 +08:00
morluto b7e76a57cd fix(adb): preserve selected environment through provider execution 2026-10-26 23:06:36 +08:00
morluto a30ffd27a6 refactor(dos): centralize MZ admission and load-image evidence 2026-10-26 23:02:53 +08:00
Dery Ferdikaandgensokyo-dev aa6c1d49fd fix(mcp)!: require allowed hosts for non-loopback HTTP binds (#7172)
Require operator-declared hostnames before serving MCP HTTP outside loopback, preserving Host/Origin gates. Parse hostname identities once, share typed startup recovery across CLI/MCP, and announce an admitted client URL. Generated AgentEnv bundles declare their client/service names and validate DNS/HTTP name identity before export.

Validated through real packaged HTTP requests, direct SDK connection, compiled export refusals, 184 focused tests, static and documentation checks on the refreshed main integration. Final CI and review evidence is recorded in the PR body.

BREAKING CHANGE: non-loopback deployments require MCP_ALLOWED_HOSTS or rea mcp --http --allowed-hosts; bundle names must be unchanged HTTP hostnames within the 63-octet DNS label bound.

Co-authored-by: gensokyo-dev <[email protected]>
2026-10-26 22:55:10 +08:00
morluto 0828917c79 refactor(verifiers): centralize named artifact output admission
Route six artifact verifiers through the canonical complete MCP output and error parsers. Remove duplicated JSON/schema interpretation while retaining Evidence authentication, provider provenance, independent CLI parsing and CLI/MCP parity checks. Validate malformed success/error envelopes at the shared boundary.

Validation: 11 boundary tests, Go compiler verifier (30 cases), and synthetic IL2CPP/Flutter verifier workflows passed; typecheck/lint passed. PCAP readiness passed with stub tools, but capture inspection is unsupported on macOS. Linux-only binary-layout and EVM verifier toolchains were unavailable.
2026-10-26 22:48:22 +08:00
morluto f02df45a46 fix(process): preserve selected Darwin helper environment through execution 2026-10-26 22:42:48 +08:00
morluto 921142efbc fix(hopper): own profile reads and retain completed coordinate evidence 2026-10-26 22:42:48 +08:00
morluto 5b983516ab fix(hopper): consolidate release metadata and archive identity ownership
Share release JSON decoding, vendor fields and package integrity checks across macOS setup and Linux publishing/cache reads. Reject malformed UTF-8 instead of repairing macOS metadata, retain established initial BOM tolerance, and preserve complete vendor rows through admission and cache retention. Keep platform channel, signature, installation and cleanup policies unchanged.

Validation: 134 focused tests passed with 21 platform skips; typecheck and lint passed. Linux-only signed-cache cases were updated but skipped on the macOS host. No live Hopper installation performed.
2026-10-26 22:38:53 +08:00
19447516a4 feat(ghidra): reuse existing projects through verified copies (#7236)
Reuse selected Ghidra projects through verified private read-only copies, with shared CLI/MCP configuration, committed project identity, import-SHA verification and explicit historical/unknown analysis semantics. Preserve exact cancellation and platform capability boundaries.

Actual Ghidra 12.1.4/JDK21 Linux CLI/MCP investigations matched fresh import on 652-function ls and 14,338-function libcrypto inventories and pseudocode; authenticated complete Evidence, mismatch/staleness refusal, saved historical reports and shared /tmp projects verified. 958 focused tests passed with four platform skips; build/static/docs/format passed. Real macOS/Windows reuse remains unverified; Windows reuse is unavailable. See PR verification for measured whole-task costs and final CI attribution.

Co-authored-by: akushonkamen <[email protected]>
Co-authored-by: morluto <[email protected]>
2026-10-26 22:31:13 +08:00
morluto 49816235f5 refactor(providers): consolidate IDA and JEB MCP result admission
Give the object-structured provider envelope one owner that retains original dictionary members. Remove duplicate schemas, text extraction and JSON-or-text decoding plus the downstream casts that repaired lossy record clones. Keep provider-specific error, truncation, wrapper and payload-selection policies in each adapter.

Validation: IDA/JEB compatibility tests, pinned SDK transport tests and provider regressions passed; check:fast passed. Real IDA/JEB applications were not exercised.
2026-10-26 22:30:58 +08:00
morluto 2b84efe0da fix(contracts): align CLI omission and native capability coverage 2026-10-26 22:22:27 +08:00
morluto 4a8205456c fix(lifecycle): preserve source failures and native workspace diagnostics 2026-10-26 22:22:27 +08:00
morluto 77468d5043 fix(providers): preserve launch selections and refresh obsolete Kuna exports 2026-10-26 22:22:27 +08:00
morluto eb06e263cb fix(plist): own dictionary decoding across Apple workflows
Preserve XML, OpenStep and binary dictionary keys at their format owners. Share validated binary reference facts with materialization while retaining scalar precision, UID identity and bounded expansion. Migrate archive, Interface Builder, native and app-bundle consumers, then remove obsolete key-omission accounting and schema copies.

Validated source regressions and compiled CLI/MCP workflows, including native plist fidelity and archive identity. Typecheck, lint, docs and test discovery pass. No performance benchmarks were required.
2026-10-26 22:20:00 +08:00
morluto 3b26d7f80b docs(security): add fallback reporting email 2026-10-26 22:18:00 +08:00
morluto cd68181c90 fix(providers): preserve report bytes and dictionary facts 2026-10-26 22:01:51 +08:00
pablodiazjorge 4557791a2e fix(contracts): advertise a v-mode portable Windows absolute-path pattern (#7152)
Use portable hex escapes for Windows absolute-path separators in the shared local path schema. Preserve host path semantics and caller spelling; validate Annex B/u/v compilation and Node win32 agreement. Closes #7151.
2026-10-26 20:56:47 +08:00
Nianze Wu 63417bf3f0 fix(contracts): publish portable browser request patterns (#7185)
Publish portable browser request-path and HTTP-token patterns at their canonical owner, preserving input spelling and existing policy. Independently reproduced and verified through actual full-profile stdio MCP catalog and domain/MCP regressions on latest main. Closes #7168.
2026-10-26 20:52:19 +08:00
Wenyu Chiou 1a91630b88 fix(setup): preserve Linux Hopper HTTP failure status (#7183)
Preserve observed failed-response HTTP status through Linux Hopper setup diagnostics without changing download rejection, retry, or installation policy. Independently validated on latest main through red/green regressions, actual TLS sockets, focused checks and CI. Closes #7182.
2026-10-26 20:45:06 +08:00
김준호 0211a07ec5 fix(session): report a missing Linux ps as provider unavailability in status (#7180)
Keep binary_session available when Linux owned-child probes lack procps ps. Preserve typed ownership-prerequisite failures in direct execution and report per-provider readiness in status. Independently validated on latest main through real stdio MCP plus focused regression, static and documentation checks. Closes #7164.
2026-10-26 20:35:09 +08:00
gensokyo-devandtijo95 e3066c1705 fix(deps): upgrade zod without narrowing timestamp inputs
Upgrade Zod to 4.6.6 and refresh locked license inventories. Preserve REA's established timestamp spellings through one shared UTC/offset grammar, including completion-verifier consumers. Size the stdin resource regression from the child's actual heap capacity.

Fixes #7173
Includes the dependency and inventory changes proposed in #7184.

Co-authored-by: tijo95 <[email protected]>
2026-10-26 20:13:12 +08:00
b675073b73 feat(mcp): scope advertised tools by family (#7228)
Scope MCP discovery, setup, doctor, status and recovery guidance by selected tool families using one contract inventory and shared catalog identity. Preserve default discovery, canonical validation and complete Evidence.

Fixes #3246. Builds on #3026. Real libcrypto workflow verifies all 5,367 exports and identical complete Evidence. Static/source/build/docs/Windows/package/Greptile checks pass; ten assertions reproduced identically on clean main and feature across Node 24/22, with cancelled coverage explicitly unverified. Merge uses the user-authorized bypass for baseline failures and unchecked human-readiness declarations, without attesting human review.

Co-authored-by: 0xLLVEL <[email protected]>
Co-authored-by: Codebuff <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
2026-10-26 19:50:12 +08:00
morluto e54bf1006e fix(environment): own JSON fields across capture, state and replay 2026-10-26 18:27:30 +08:00
morluto cc5a96933a test(mcp): validate selected tools without compiling the entire catalog 2026-10-26 18:26:33 +08:00
morluto dec4cf50cb fix(captures): preserve reply failures through descriptor finalization 2026-10-26 18:26:26 +08:00
morluto 68f2d67c56 fix(paths): preserve native selections through analysis and removal 2026-10-26 18:26:17 +08:00
morluto e7f986c994 fix(json): consolidate dictionary admission across analysis and verification 2026-10-26 18:14:50 +08:00
morluto c06dc2d356 fix(native): retain completed debugger evidence through reply cleanup 2026-10-26 18:12:01 +08:00
morluto f8161ad7b3 fix(setup): preserve selected home paths throughout skill installation 2026-10-26 18:11:54 +08:00
morluto 4ca3032e7f fix(json): preserve configuration and capture data at admission 2026-10-26 18:06:00 +08:00
gensokyo-devandAkshad Jogi 9085222ca1 feat(mcp): support compact output schema advertisements (#7218)
Add opt-in bounded output-schema advertisements while preserving the full default, canonical server validation and complete structured content. Verify real stdio discovery under a 1 MiB receive cap, all 5,367 libcrypto export coordinates, complete Evidence parity, whole-task serialization estimates and resource bounds.

Fixes #2512. Integrates #7054 by Akshad Jogi with original authorship retained.

Co-authored-by: Akshad Jogi <[email protected]>
2026-10-26 17:59:51 +08:00
morluto e596a48251 fix(sqlite): retain completed evidence through reply finalization 2026-10-26 17:56:47 +08:00
morluto f2b4468183 fix(paths): preserve native selections across launch and publication 2026-10-26 17:56:47 +08:00
morluto da526fc014 fix(providers): preserve reply bytes and structured JSON ownership
Share strict UTF-8 JSON admission across bounded worker reports. Preserve IDA/JEB structured dictionaries through negotiated SDK validation and adapter decoding, retaining inherited tool validation and protocol handling.

Validated 240 tests, including real SDK/HTTP exchanges and firmware file reads; 83 host-specific cases skipped. Typecheck, lint, and discovery passed. Real-provider execution and modern MCP protocol behavior remain unverified.
2026-10-26 17:52:32 +08:00
morluto 721dd3d1aa fix(javascript): preserve selected inputs and completed source evidence 2026-10-26 17:39:29 +08:00
morluto 3864c7d667 fix(config): preserve captured environments across provider launches 2026-10-26 17:39:23 +08:00
morluto ccdeda7a27 fix(inputs): centralize admission and preserve caller selections
Move shared request parsing into its application owner, migrate all consumers, and remove six duplicated admission blocks while preserving cancellation and validation policy.

Keep operator-selected JavaScript paths in verifier parent Evidence while retaining canonical comparison guards. Validated with 204 passing tests, 3 Linux-x64-only skips, typecheck, lint, and test discovery.
2026-10-26 17:35:18 +08:00
morluto 7d36d172ab fix(evidence): consolidate retained view and verifier ownership 2026-10-26 17:26:55 +08:00
morluto e2d4c0dabb fix(process): preserve environment snapshots and final cancellation 2026-10-26 17:26:16 +08:00
morluto eecadf35b2 fix(verification): unify client schema traversal and reference checks
Share ordered schema positions between Gemini literal checks, DeepSeek regex
checks, and catalog array-shape checks. Reuse the canonical keyword and local
reference owners; keep unreferenced instance literals opaque and unresolved
external or dynamic targets unknown.

Gemini and catalog checks now catch constraints in schemas reached through
references into examples. Preserve source paths, resource scopes, cycles and
regex occurrence counts. Align fixture first-error selection with the native
Gemini check and use consistent bracketed array locations in diagnostics.

Validation: 55 focused tests passed, including full/compact MCP catalogs;
typecheck, lint, discovery, and Node source-loader checks passed. The old
Gemini scanner reproduced the local-reference false negative. Installed
Gemini and DeepSeek clients were not run.
2026-10-26 17:15:58 +08:00
morluto 86ff3237e1 fix(paths): preserve selected command, output, and source identities 2026-10-26 17:14:02 +08:00
Kaoru0822andClaude Opus 5.5 18dc78fa43 revert(mcp): undo input schema fitting that broke main CI (#7135)
This reverts commit 7336a566ac (#7119).

After #7120 and the other merges of 2026-10-25 grew inspect_analysis_view's
complete input schema (71,762 bytes plus 3,003 bytes of examples), the 64 KiB
fitting from #7119 could no longer keep instance level 3 and fell back to
level 2. That summarized the inline Evidence source and the view selector
collections, so main CI failed in toolInputReferences, toolSchemaValidity,
analysisViewMcp, absoluteLocalPathSchema, javascriptFactsViewMcp and
godotPckMcp. #7119's own CI ran against bc143125e, before that growth.

Reverting restores the complete full-profile advertisement while the size
limit is redesigned against these contracts (#4081 stays open).

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-26 02:06:57 -07:00
morluto 6c35d74a7d refactor: centralize input validation and schema interpretation
Migrate twelve application service files to the existing provider input owner,
preserving schema causes, cancellation precedence, caller selection, and
retained Evidence. Keep flows with distinct error policies separate.

Replace the DeepSeek verifier's recursive object scan with schema-position
traversal using the canonical keyword and local-reference owners. Literal
pattern fields no longer cause false regex failures; patternProperties keys
are checked alongside actual pattern constraints in native regex modes.

Validation: 271 focused workflow/service tests and six verifier regressions
passed; static checks, discovery, and actual Node source-loader smoke passed.
The baseline scanner reproduced the new regressions. Installed DeepSeek client
execution was not run.
2026-10-26 17:05:05 +08:00
morluto 8a65787507 refactor: consolidate parsed image ownership across consumers
Retain validated DOS relocation records in their domain owner and consume
those facts in Ghidra load-image preparation. Preserve ordered duplicate
aliases, overlapping writes, and original/final byte evidence.

Share FAT header facts across generic, native, and Hopper readers without
merging their distinct admission policies. Replace managed method bodies'
two identical mapping lookups with one owned offset-and-extent result.

Validation: 660 focused tests passed across 19 suites; typecheck, lint, and
test discovery passed. Hopper/Ghidra checks used fixtures and simulated
provider observations; no real external provider execution was performed.
2026-10-26 16:56:50 +08:00
morluto a7f50e3386 refactor: consolidate ELF and CLR record interpretation
Share ELF note headers across note inspection, Flutter build IDs, Node SEA,
and recorded-crash source binding. Decode REL/RELA records once for MIPS
shared-load analysis and IL2CPP linking, removing superseded scalar helpers.

Share the CLR header prefix between desktop detection and managed PE parsing
while preserving their distinct read bounds and admission policies. Cover
those differences and ignored R_NONE fields with production-boundary tests.

Validation: 493 focused tests passed, two existing skips; static checks and
test discovery passed. Public managed/desktop CLI and ELF notes CLI/MCP
workflows exercised; no real external analysis providers were run.
2026-10-26 16:50:08 +08:00
morluto eb51eb6915 fix(process): preserve selected launch paths and completed command output 2026-10-26 16:46:53 +08:00
morluto 86e7cd9b48 fix(verification): keep runtime packaging and boundary fixtures complete 2026-10-26 16:46:53 +08:00
morluto 09acf217d9 fix(evidence): preserve source and authenticated observation identity 2026-10-26 16:46:45 +08:00
morluto 6336fe5bb5 refactor: consolidate binary analysis admission and format ownership
Reuse the existing provider input admission helper across twelve services,
preserving cancellation, schema errors, path policies, and Evidence handling.
Share ELF dynamic records across Dart, MIPS, and IL2CPP readers, and reuse
Mach-O segment and section records for Node SEA location.

Require canonical DOS ownership before GPU PE section discovery so relocation
bytes cannot masquerade as a PE pointer. Cover valid short DOS headers and
the malformed case through both inventory and the public CLI.
2026-10-26 16:44:21 +08:00
morluto 7adfcc4467 fix: unify executable format ownership across artifact readers
Centralize ELF section and Godot trailer declarations while preserving caller admission policies. Route six PE entrypoints through canonical DOS ownership so relocation data cannot establish a PE header, and update NativeAOT interpretation identity and verifier dependency coverage.
2026-10-26 16:32:49 +08:00
morluto 9341b116ef refactor: consolidate binary artifact interpretation and fixture ownership
Share exact ELF program-header facts across nine consumers while preserving their admission and precision policies. Centralize conformance path and digest binding, retain verifier-specific checks, and route fixture-owner changes to CI qualification.
2026-10-26 16:21:11 +08:00
morluto 23bc51d5c4 test(package): migrate skill metadata fixture to frontmatter 2026-10-26 16:15:08 +08:00
morluto 28222089f4 refactor(zip): share end-of-directory declarations 2026-10-26 16:14:58 +08:00
morluto 91bacc5c14 refactor(config): share bounded decimal setting validation 2026-10-26 16:14:49 +08:00
morluto 2411d60b5a fix(verification): unify complete MCP catalog checks 2026-10-26 16:11:09 +08:00
morluto 74f9870b7a refactor(macho): share FAT evidence interpretation 2026-10-26 16:10:57 +08:00
morluto 90199ff0ec refactor(elf): centralize symbol record decoding 2026-10-26 16:10:46 +08:00
morluto 3d565fa42a refactor(windows): share native artifact validation 2026-10-26 16:04:44 +08:00
morluto 729684af9a refactor(png): share IHDR interpretation 2026-10-26 16:04:33 +08:00
morluto 92bdb4443f refactor(pe): share CodeView range interpretation 2026-10-26 16:04:18 +08:00
morluto a7d71f47ee refactor(elf): centralize raw table declarations 2026-10-26 16:04:09 +08:00
morluto c994870f6b fix(inspector): route file locations through URL semantics 2026-10-26 16:02:14 +08:00
morluto 1a1121c61f fix(android): retain selected Java across workspace launches 2026-10-26 16:02:14 +08:00
morluto ce5373e42f test(providers): verify malformed HTTP acquisition recovery 2026-10-26 16:02:14 +08:00
morluto 38ed5a3142 fix(browser): invalidate ASAR headers on file state changes 2026-10-26 16:02:14 +08:00
morluto 258a1dd3b7 fix(skills): parse metadata only from YAML frontmatter 2026-10-26 15:49:58 +08:00
morluto 0f64f1f855 refactor(macho): share bounded header declarations 2026-10-26 15:49:52 +08:00
morluto f8c5a6cc10 fix(providers): reject malformed UTF-8 before MCP decoding 2026-10-26 15:41:03 +08:00
morluto c849a97d2a fix(setup): preserve explicit Codex home traversal 2026-10-26 15:41:03 +08:00
morluto 628087a2db fix(process): preserve platform-aware environment precedence 2026-10-26 15:41:03 +08:00
morluto 554816becc refactor(verification): centralize native client result discovery 2026-10-26 15:40:34 +08:00
morluto 981d806924 refactor(macho): centralize segment and section decoding 2026-10-26 15:40:10 +08:00
morluto f4cc6c85ef refactor(verification): share native client fixture assertions 2026-10-26 15:34:11 +08:00
morluto 0929751798 refactor(macho): reuse canonical header declarations 2026-10-26 15:34:04 +08:00
morluto 36515a5c9b refactor(cli): derive desktop limits from the input contract 2026-10-26 15:33:59 +08:00
morluto deed39f7c4 refactor(pe): share optional-header facts across readers 2026-10-26 15:27:35 +08:00
morluto 971b48f702 refactor(mcp): reuse desktop retained-summary handler 2026-10-26 15:27:29 +08:00
morluto b9ee8fe057 refactor(pe): centralize fixed COFF header decoding 2026-10-26 15:20:02 +08:00
morluto 99d4ea9c05 fix(captures): preserve relative redirect URL evidence 2026-10-26 15:15:00 +08:00
morluto 2012efe5fd fix(artifacts): retain source identity failures after relocation 2026-10-26 15:15:00 +08:00
morluto 0c147a4a70 fix(snapshot): preserve authenticated replay provenance 2026-10-26 15:15:00 +08:00
morluto f4987281fa fix(setup): forward supported tool and runtime selections 2026-10-26 15:15:00 +08:00
morluto 53779b59bf refactor(pe): reuse canonical section header facts 2026-10-26 15:14:10 +08:00
morluto 943ae604df refactor(reference): derive import lookup from reader inventory 2026-10-26 15:14:05 +08:00
morluto 44b716f2f2 fix(runtime): preserve exact selected target identities 2026-10-26 15:09:04 +08:00
morluto d9e12c957b refactor(firmware): centralize extraction depth ceiling 2026-10-26 15:08:56 +08:00
morluto 90b793e0f4 docs: scope performance measurements to concrete needs 2026-10-26 15:04:08 +08:00
morluto b3818bbba2 refactor(il2cpp): share generic container byte decoding 2026-10-26 15:00:41 +08:00
morluto 9e4702b7a7 fix(sqlite): preserve schema-owned input issue paths 2026-10-26 15:00:30 +08:00
morluto 23d56e1abd refactor(config): use canonical resource limit constants 2026-10-26 15:00:23 +08:00
morluto 85075fa979 refactor(asar): let listing own parsed member facts 2026-10-26 14:53:42 +08:00
morluto 7cd65278ea refactor(config): remove legacy provider timeout re-exports 2026-10-26 14:53:20 +08:00
morluto 7404847f64 fix(update): bound and own metadata probe lifetimes 2026-10-26 14:49:10 +08:00
morluto bf876efbaa fix(kuna): bind cached export reads to verified file state 2026-10-26 14:49:10 +08:00
morluto b654ac8b13 fix(setup): retain auxiliary tool selections in registrations 2026-10-26 14:49:10 +08:00
morluto a116d32cdc chore: sync main before publishing cleanup migrations 2026-10-26 14:48:30 +08:00
morluto 8fe3b17ea7 refactor(tooling): move completion ledger generation out of domain 2026-10-26 14:46:35 +08:00
morluto 42f3ed7119 refactor(tooling): move verifier host helpers out of runtime 2026-10-26 14:46:23 +08:00
morluto d3946a3f50 fix(apk): reuse canonical subject identity in retained views 2026-10-26 14:46:14 +08:00
morluto 975900f565 docs(setup): state the FreeBuff minimum release (#7066) 2026-10-26 14:45:43 +08:00
morluto 2be39ef47a refactor(model): let format parsers own tensor range validation 2026-10-26 14:33:35 +08:00
morluto f4768eb5d3 fix(wasm): reuse canonical subject identity admission 2026-10-26 14:33:27 +08:00
morluto 06655af306 refactor(evidence): centralize publication source collection 2026-10-26 14:25:50 +08:00
morluto 8982f40d00 refactor(godot): share PCK header facts across inspections 2026-10-26 14:25:44 +08:00
morluto d7d9457661 refactor(gpu): reuse canonical ELF note layout 2026-10-26 14:25:34 +08:00
morluto ed7b3a2a10 refactor(macho): share header declarations across native readers 2026-10-26 14:20:01 +08:00
morluto c11fb48c98 fix(electron): share wrapped member identity parsing 2026-10-26 14:19:55 +08:00
morluto 83a6cdb859 fix(paths): preserve native traversal and unset PATH semantics 2026-10-26 14:17:27 +08:00
morluto 1fe1f1f8d6 refactor(managed): retire redundant verification facade 2026-10-26 14:14:26 +08:00
morluto 5a332d856a refactor(browser): resolve Link metadata identity once 2026-10-26 14:14:22 +08:00
morluto 38ebe11a52 refactor(pe): centralize section header interpretation 2026-10-26 14:14:18 +08:00
morluto ba7ac7908d refactor(elf): carry parsed header facts into native consumers 2026-10-26 14:08:35 +08:00
morluto 9fa5a87c73 refactor(javascript): remove obsolete Electron classifier facade 2026-10-26 14:08:34 +08:00
morluto 6362ac6b72 refactor(web): reuse shared provider input admission 2026-10-26 14:08:30 +08:00
morluto fab78501c7 refactor(services): centralize direct provider input admission 2026-10-26 14:04:57 +08:00
morluto 5c4a6c467c refactor(pe): share optional header image and alignment facts 2026-10-26 14:04:45 +08:00
morluto 72fa15a509 refactor(snapshots): derive workflow entries from canonical schema 2026-10-26 14:04:39 +08:00
morluto 52976ac5cd fix(doctor): bound and cancel diagnostic subprocesses 2026-10-26 14:02:55 +08:00
morluto fa6112b29f fix(providers): preserve native traversal in installation paths 2026-10-26 14:02:55 +08:00
morluto 6819cc5b8d fix(setup): preserve explicit configuration independently of readiness 2026-10-26 14:02:55 +08:00
morluto f6d9f1b05c refactor(browser): reuse worker URL exclusion classification 2026-10-26 13:59:22 +08:00
morluto 5e581fd3b1 refactor(workflows): share source caveat grouping identity 2026-10-26 13:59:11 +08:00
morluto 7439d0d5d8 refactor(artifacts): reuse Mach-O framing for Node SEA discovery 2026-10-26 13:59:04 +08:00
morluto 071a637a9f refactor(cli): share managed comparison finalization 2026-10-26 13:53:43 +08:00
morluto 634e566c09 refactor(capabilities): remove inert client requirement facade 2026-10-26 13:53:35 +08:00
morluto 941838fdd9 refactor(elf): centralize fixed header type and flags decoding 2026-10-26 13:53:25 +08:00
morluto 991a240606 fix(cli): preserve script export evidence through shared finalization 2026-10-26 13:47:15 +08:00
morluto 7ccecbcb00 refactor(cdp): centralize execution context identity parsing 2026-10-26 13:47:04 +08:00
morluto 60daca427d refactor(reconstruction): share canonical original cases across evaluation 2026-10-26 13:46:57 +08:00
morluto 1173c0a9dc test(setup): align launch fixtures with runtime and host requirements 2026-10-26 03:20:13 +08:00
morluto db4d3abcda fix(setup): retain bounded startup diagnostics without losing failures 2026-10-26 02:33:31 +08:00
morluto 37a7c2d652 fix(doctor): retain host uncertainty and resolved Java selection 2026-10-26 02:33:31 +08:00
morluto 82fe820060 fix(setup): retain explicitly selected ILSpy paths 2026-10-26 02:33:31 +08:00
morluto 14dd18a7fd fix(setup): preserve native configuration path traversal 2026-10-26 02:33:31 +08:00
morluto d69a54d592 fix(setup): register explicit MCP runtimes and preserve launcher identity 2026-10-26 02:33:31 +08:00
b8ce3c74cd feat(native): make function matching allowance configurable (#7159)
Allow native matching representation budgets to be selected at runtime or launch while retaining the 96 MiB default and main shared-provenance accounting. Preserve actionable configuration recovery through the setting owner and verify complete CLI/MCP matches for 20k/50k synthetic inventories and real stripped LLVM 14/15 inventories.

Fixes #6406.

Based on #7112 by Kaoru0822; original authorship and co-author credit retained.

Co-authored-by: Kaoru0822 <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-26 02:22:32 +08:00
morluto a174892e3e fix(website): improve layout and clarify homepage copy 2026-10-26 01:33:31 +08:00
morluto ff6d96bce8 fix(website): surface RL environments and adjust homepage navigation 2026-10-26 00:51:30 +08:00
morluto a0ddb83e45 docs(environments): lead with agent prompts 2026-10-26 00:40:56 +08:00
morluto 14631f698d docs(website): showcase RL environment workflows 2026-10-26 00:33:55 +08:00
gensokyo-dev 4c8647a706 feat(native): page retained observations and source context (#7146)
* feat(native): page retained observations and source context

* docs(native): record complete observation workflow measurements

* fix(native): preserve context coverage and overflow recovery

* fix(benchmarks): finalize partially initialized observation probes

* docs(native): publish reviewed workflow verification
2026-10-26 00:32:01 +08:00
morluto 447907f280 docs(environments): explain building RL environments with REA 2026-10-26 00:16:52 +08:00
Kaoru0822andClaude Opus 5.5 5d42839099 revert(mcp): undo input schema fitting that broke main CI
This reverts commit 7336a566ac (#7119).

After #7120 and the other merges of 2026-10-25 grew inspect_analysis_view's
complete input schema (71,762 bytes plus 3,003 bytes of examples), the 64 KiB
fitting from #7119 could no longer keep instance level 3 and fell back to
level 2. That summarized the inline Evidence source and the view selector
collections, so main CI failed in toolInputReferences, toolSchemaValidity,
analysisViewMcp, absoluteLocalPathSchema, javascriptFactsViewMcp and
godotPckMcp. #7119's own CI ran against bc143125e, before that growth.

Reverting restores the complete full-profile advertisement while the size
limit is redesigned against these contracts (#4081 stays open).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Refs: #7135
2026-10-25 23:50:18 +08:00
gensokyo-dev 6381aa0b1d fix(ghidra): scope rejected-input diagnostics to their request (#7140)
Scope expected Ghidra input failures to the active request after the authenticated startup handshake. Preserve operation output, identity and log coordinates while retaining cumulative output with its session owner; lifecycle and unexpected failures keep full diagnostics.

Share remote input-code classification with domain error projection. Verify startup rejection, healthy continuation, cleanup, unknown errors, OOM diagnostics and real CLI/MCP workflows. The measured unknown-symbol reply falls from 13,170 to 2,209 bytes with unchanged successful facts and Evidence IDs.
2026-10-25 22:37:32 +08:00
gensokyo-dev f69c52a1cf feat(native): page retained load-image observations (#7134)
Add optional native load-image summary delivery and retained selected-row pages through shared CLI/MCP analysis views. Preserve source verification, provenance, unavailable collections, exact row identity and opt-in byte/check payloads.

Preserve direct caller paths during shared CLI summary publication and cover raw/DOL projection contracts through the actual SDK. Real Ghidra ELF CLI/MCP captures, retained and file-backed pages, focused regressions and static checks passed; the PR records existing main schema failures and the JavaScript resource-recovery CI uncertainty.
2026-10-25 21:50:42 +08:00
Kaoru0822andClaude Opus 5.5 25f0f9934d fix(javascript): close member-path cycles through self stores (#7131)
A write below a slot that stores a value read from the same slot, such
as `s.c = s.c.p; s.c.i = 1` on a parameter, revisits the binding with
one more segment after the stored key on every turn. The cycle closure
only recognized segments added at the front of the path (`node =
node[key]`), so the work-list never terminated and exhausted the owned
worker heap (CodeMirror 5 `mode/stylus/stylus.js`).

Recognize a contiguous segment inserted after a stable base, check that
repeating it after that base can never be pruned, and escape through it
once, as the self-alias rule already does. Front insertions keep their
existing order and result.

Fixes #7130

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:32:29 -07:00
Kaoru0822andClaude Opus 5.5 70b96b65d9 fix(javascript): stop recording replaced slot values as store receivers (#7128)
Reference-store identity queries resolved the written target as a value,
so once a step consumed the written key the walk continued into the value
read from that slot and recorded it, and everything reachable from it, as
an object the store mutates. Every value stored into one local object at
unknown keys then received an entry for every such store, and each new
store re-queued every earlier one. Ambient-write indexing grew cubically
in the number of such stores.

Receiver queries now drop items whose projection no longer ends at the
written key. Stored-value selection has one owner, which the resolver and
the store fixpoint share. The fixpoint re-queues a dependent only when a
changed entry can reach it with a selection that its receiver query keeps.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:29:23 -07:00
Kaoru0822andClaude Opus 5.5 5a22ae6bc8 fix(mcp)!: return a compact binary_session status by default (#7127)
* fix(mcp)!: return a compact binary_session status by default

binary_session {} with no target open returned about 66 KB, most of it
provider rejection diagnostics and candidate capability sets that the
skill's recovery flow re-reads on every retry. 6.8.0 grew it by 21%
because the shared regex capability limitation began repeating setting
bounds and step-by-step recovery for every search operation of every
provider (#6099, #6267, #6301, #7049) and IDA gained that limitation for
its two search operations (#4862).

The regex limitation now states the effective deadline and heap, their
sources and where to change them; the deadline and heap errors keep the
full recovery. binary_session gains detail: summary (default) or
complete. The summary keeps open state, target identity, the binding,
route capabilities, run, activity and health status, each candidate's
availability and target-support status, code and reason, and every
tool's availability, reason, remediation and modes, and lists the
fields it leaves out in omitted_fields. Complete detail returns the
previous shape. The CLI capabilities and providers commands keep
complete provider facts through the same application projection.

BREAKING CHANGE: binary_session {} no longer returns
analysis_provider_candidates[].availability.diagnostics,
target_support.diagnostics or capabilities, or tool_availability group
surface, effects and annotations. Pass {"detail": "complete"} to get
them.

Fixes #7109

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): key binary_session output fields by detail

The output schema accepted detail: "complete" with summary candidates or
tool groups, and a summary without omitted_fields, so detail did not
tell callers which fields existed. Each session kind is now crossed
with a detail-specific shape: a summary requires omitted_fields and
summary-only candidates and tool groups; complete requires diagnostics,
candidate capabilities and static tool flags and forbids omitted_fields.
Both the canonical schema and the SDK-validated advertised schema reject
mismatched shapes.

The verifier helper accepts summary candidates only for a validated MCP
summary; CLI provider output still requires candidate capabilities.
Regex limitation tests check values, sources and setting names instead
of whole sentences.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:29:03 -07:00
Kaoru0822andClaude Opus 5.5 e06be06530 fix(cli): report JSON Lines selection refusals as caller errors (#7124)
* fix(cli): report JSON Lines selection refusals as caller errors

A --format jsonl refusal because the selected value is not a record
collection is the caller's output selection, not unreadable analysis
output. Report it as invalid_request/invalid_input that names the
selection and its observed shape, keep the --format json /
--filter-output remediation, and drop the rea doctor advice.

AnalysisInputError gains an optional producer remediation, mirroring
the other refusal classes. The JSON Lines owner examines its documented
boundaries once for both admission and refusal facts.

docs/cli.md now states that columnar results such as
inspect-sqlite-database --table rows are not record collections.

Fixes #7110

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(cli): carry JSON Lines refusal facts as structured observations

JSON Lines refusals now put the location and shape of each refused value
in details.issues[].observed, and the message is built from those facts.
Tests assert the classification, issue path, observed facts, and the
shared remediation constant instead of fixed sentences.

The filtered analysis-view export check now uses a non-empty request
and compares the emitted rows with the unfiltered export.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:26:13 -07:00
Kaoru0822andClaude Opus 5.5 81afb043f7 fix(javascript): evaluate each short-circuit left operand once (#7126)
Logical branch selection evaluated the left operand to decide which
branches stay reachable, and value evaluation then evaluated the selected
left branch again. In a left-nested `a || b || c ...` chain every level
repeated that, so semantic analysis doubled per operand and a 24-operand
chain exhausted the per-source deadline.

The selection now carries the left operand's value with the branch, and
value evaluation reuses it. Provenance still walks the branch nodes.
Results are unchanged.

Fixes #7115

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:25:54 -07:00
Kaoru0822andClaude Opus 5.5 7336a566ac fix(mcp): fit every advertised input schema within the 64 KiB client limit (#7119)
* fix(mcp): fit every advertised input schema within the 64 KiB client limit

Claude Desktop drops a local connector tool whose compact-JSON input
schema exceeds 64 KiB. The full input profile advertised
compare_web_captures at 171,867 bytes and inspect_analysis_view at
71,632 bytes, because the self-contained projection inlines the
complete producer capture schemas once per side.

The full advertisement now fits the limit at its producing boundary.
A property whose schema repeats an earlier sibling's points at it, and
schemas below the deepest instance level that fits are summarized as
their types, size constraints and descriptions. Every rewrite widens the
advertisement through the existing relaxation rules for oneOf, not,
if/then/else, contains and unevaluated keywords, so canonical inputs
stay accepted and the canonical contract still validates every call.
Schemas within the limit are unchanged, and the compact profile is
still presented from the complete projection.

Numeric const and enum literals are also relaxed in the advertisement,
like boolean literals, since Gemini accepts only string enum members.

Fixes #4081

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(mcp): keep fitted input summaries widening and at the deepest fitting level

Array summaries took item types only from `items`, so a tuple such as
`{prefixItems: [{type: string}], items: {type: number}}` was advertised
as a number array that rejected `["a", 1]`. Item types now include tuple
positions from `prefixItems`, a draft-07 `items` array, and
`additionalItems`, and stay unconstrained when later elements are open.

A summary can also be longer than the schema it replaces (a nullable
array becomes an anyOf), so candidate size is not monotone in the
retained depth and stopping at the first overflow could skip a deeper
candidate that fits. A schema is now kept whole when its summary is not
smaller, and fitting searches from the deepest level down.

Property tests check that every summary accepts what its schema accepts
over every catalog input subschema and synthetic tuples, and that the
fitted schema is the deepest fitting candidate. The browser comparison
boundary test now expects a malformed `after` capture to be rejected
canonically, since `after` is advertised as the same schema as `before`;
the same malformation on `before` stays advertised-invalid.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:25:07 -07:00
Kaoru0822andClaude Opus 5.5 aa79f59478 fix(javascript): bind defaulted and destructured Webpack factory roles (#7117)
* fix(javascript): bind defaulted and destructured Webpack factory roles

A Webpack factory whose module parameter was defaulted (`e = {}`) or
destructured (`{exports: x}`) reported an exact empty export list with
complete coverage, because roles were taken only from plain identifiers.

Bind factory roles once, by position, in javascriptBundlerFactoryRoles.
Defaulted module/exports parameters keep their role (the convention always
supplies the argument), `{exports: alias}` binds the alias to
module.exports, and a repeated sloppy parameter name binds its last
argument. Other role patterns (rest, array, nested or computed keys, a
non-identifier loader) receive no role and count as an unknown finding,
so the file's analysis is partial instead of claiming no exports. The
export collector, the factory require name and the standalone bootstrap
externals all use these parsed roles.

Fixes #7113

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(javascript): keep factory receivers through unordered reads

A defaulted role parameter kept the unused default in the binding facts
passed to write ordering, so a receiver read inside a loop, nested block
or closure was unresolved and its export silently dropped while the
module stayed complete.

The role owner now removes defaults the calling convention never runs
before ordering. Separately, an export-shaped write through a role
binding whose read stays unordered now counts as an unknown finding
instead of being dropped, so an incomplete list is never reported as
complete.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(javascript): treat never-run factory parameter defaults as dead code

Removing unused defaults from binding facts let writes inside a default
expression reach the export collector: `(e = {}, t = (() => {
e.exports.ghost = 1; })())` reported `ghost` although Webpack supplies
both arguments. Loader calls in such defaults also produced require
references and async chunk keys.

The role owner now records the default of every role parameter, any
binding pattern included, as never run. The export collector, the
async-chunk walk and the static source traversal skip those subtrees,
so they yield no exports, references or chunk keys. Defaults of later,
non-role parameters still run and are still reported.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:23:23 -07:00
Kaoru0822andClaude Opus 5.5 d32d9f2902 fix(lldb): keep the bridge's no-target proof through interruption (#7111)
When cancellation or the deadline interrupted LLDB after it had published
its bridge result, the tracer never read that result, so an explicit
`target_process_created: false` (or `target_process_exit_observed: true`)
was lost. The run kept a `native-target:unknown` marker that no cleanup
retry could release, wedging the tracer for every later trace.

Read the published result once LLDB's process group is stopped, even for
an interrupted run, and apply the same target-gone proof in cleanup retry.
Cancellation or timeout stays the primary outcome; a created target, a
truncated result, or a missing PID alone stays unresolved.

Fixes #5385

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:21:26 -07:00
Kaoru0822andClaude Opus 5.5 cc2656be8d perf(native): charge function matching for the copies it makes (#7108)
* perf(native): charge matching for what it copies, not borrowed retained inventories

Native function matching deep-walked every retained list_procedures record
at about 2.8 KB per Ghidra-shaped row, although the session ledger lends
those immutable records without a copy, and charged each inventory's one
Evidence ID once per function. The report and Evidence copies of every
emitted member were not charged at all.

Charge each inventory row before parsing for the member it becomes,
including its report and Evidence copies, charge the shared inventory ID
once, and skip the walk only for borrowed immutable inventories and closure
records that matching never parses. Inline Evidence, bundle records and
selected observations keep their existing charges. Retained references now
fit about 22,000 rows per side instead of 10,000, and an oversized side is
refused before its rows are parsed.

Refs #6406

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(native): charge the envelope of borrowed matching inputs

Borrowed inventories skipped admission entirely, but matching copies their
limitations into the report and Evidence and digests their profile, so a
retained inventory with few rows and large limitations escaped the
allowance. Charge every envelope field and leave only the result payloads,
which row charging covers or matching never parses, uncharged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:21:09 -07:00
Kaoru0822andClaude Opus 5.5 58a5275aa2 fix(mcp): advertise reduced array elements with Gemini-compatible item types (#7107)
Reduced compact input schemas gave every array property an any-value item
schema, a six-member type list beside nested `items`. Gemini function
declarations accept `items` only beside the single `array` type, so every
request through a Gemini-backed client failed with
`properties[functions].items.items: field predicate failed: $type == Type.ARRAY`.

Reduced array properties now advertise the element types their canonical item
schemas accept. Unknown, tuple, and mixed array elements use the empty item
schema, and properties that may be arrays or another type list typed anyOf
branches. An inline `not: {}` keeps the empty schema. The compact catalog test
now rejects `items` beside a non-array type as well as untyped item unions.

Fixes #5201

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:20:36 -07:00
Kaoru0822andClaude Opus 5.5 0eb3919d69 fix(artifacts): admit raw UDRW disk images (#7106)
* fix(artifacts): admit raw UDRW disk images

Raw (UDRW, UDTO) disk images have no UDIF koly trailer, so target
admission and root inventory both refused them as unsupported binaries.
Recognize disk images in one domain owner (koly trailer, GPT, Apple
partition map, MBR, or an unpartitioned HFS+/HFSX volume header) that
both boundaries consume.

hdiutil reports "has no checksum" for these images; the native reader
now treats that status line as an explicit absent checksum, records the
nonzero verify command, attaches read-only, and reports that integrity
was not verified. Checksum mismatches and unrecognized images are still
refused.

Positional range reads used by these probes now fill until end of file
so short host reads cannot hide a signature.

Fixes #5687

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix(artifacts): read disk image signature windows at the recognizer

Target admission passed its first unfilled 4 KiB read to the raw-image
checks, so a short host read could hide a GPT, APM, MBR or HFS+
signature that inventory (which fills its prefix) still observed. The
recognizer now reads its own leading window through the caller's
filling positional read, and target admission fills its format-probe
prefix as well. The controlled short-read regression now covers target
admission alongside inventory.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:20:24 -07:00
Kaoru0822andClaude Opus 5.5 a8e5eaf1aa fix(macho): derive the runtime name of each Mach-O symbol (#7105)
inspect_macho reported only the symbol-table spelling (`_main`), while
LLDB, dlsym and observe_native_calls use the runtime spelling (`main`).
Passing a static name as a breakpoint silently selected a different
function, so results from the two tools could not be joined by name.

Keep `name` as the exact symbol-table fact and add a derived
`runtime_name` to every export and import row, produced by one shared
Mach-O symbol-name owner. Managed P/Invoke verification now uses the
same owner instead of its own underscore stripping.

Fixes #5298

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 05:19:54 -07:00
fc43e285ea feat(browser): retain compact scenario summaries and selected views (#7120)
Retain complete browser scenario Evidence while delivering compact summaries and selected step, event, transaction and text views through shared CLI/MCP workflows. Preserve initial CLI failures across cleanup retries and validate with real Chromium/TodoMVC.

Co-authored-by: Kaoru0822 <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-25 19:03:06 +08:00
morluto bc143125ed fix(release): reject missing manifest release boundaries 2026-10-25 17:25:18 +08:00
3243 changed files with 301205 additions and 276548 deletions

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
{
"name": "rea",
"interface": {
"displayName": "REA"
},
"plugins": [
{
"name": "rea",
"source": {
"source": "npm",
"package": "rea-agents",
"version": "6.8.0"
},
"policy": {
"installation": "AVAILABLE",
"authentication": "ON_INSTALL"
},
"category": "Developer Tools"
}
]
}
@@ -15,6 +15,11 @@ Follow the checkout's [performance priorities](../../../AGENTS.md#performance),
workflow, not additional permission to execute targets, publish, or merge.
Use the current contracts, provider prerequisites, and user authorization.
Reserve performance measurements for changes that target performance or have a
concrete regression concern. Routine cleanup uses correctness checks and does
not require this optimization workflow or synthetic benchmarks merely because
helper calls, imports, or representations change.
Read [the Kuna case study](references/kuna-case-study.md) when selecting a
reuse strategy or interpreting a benchmark. Its pinned observations illustrate
tradeoffs; they are not current-provider guarantees or universal speedups.
@@ -2,7 +2,7 @@
name: reverse-engineer-anything
description: Reverse engineer native, managed, Electron/JavaScript, packaged, firmware, and browser targets with REA, and build agent environments (AgentEnv bundles) of web applications from a live instance or a capture. 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: "49"
version: "55"
---
# REA
@@ -17,6 +17,9 @@ readiness or provider commands.
Installing this skill supplies instructions; it does not register the REA MCP
server, install analysis engines, or add tools to an already-running agent.
The exception is a Claude Code or Codex plugin install: the plugin bundles
this skill and registers its own `rea` server, outside the state that
`rea setup` and `rea doctor` manage.
If REA tools are available and their registration is not known to be stale,
proceed directly to the target. Do not run diagnostics or setup before every
@@ -37,42 +40,23 @@ repeat or known not to have started. If it may already have changed the
target, or it fails again, tell the user and ask them to restart the MCP
client. If REA could not start its connection, retry once, then tell the user
and ask them to restart the MCP client. Do not retry a startup failure that
returns the same unchanged result. Run `rea doctor` when REA could not start
returns the same unchanged result. For plugin installs, follow
[plugin recovery](references/connection-and-recovery.md#rea-installed-as-a-client-plugin).
For setup-owned registrations, run `rea doctor` when REA could not start
or tools stay missing after that restart. For `cleanup_incomplete`, a retryable
capacity limit, or `configuration_invalid`, follow the recovery guide's ladder
before asking for a restart. Read that guide before a second repair attempt.
1. Diagnose without changing REA or client configuration. `npx` may download
the package and write to npm's cache. For Codex, run
`npx -y rea-agents@latest doctor --client codex --json`. Substitute the current
supported client: `claude_code`, `claude_desktop`, `codex`, `cursor`,
`gemini_cli`, `windsurf`, `devin`, `opencode`, `antigravity`, `copilot_cli`,
`commandcode`, `vscode`, `grok_build`, `omp`, or `grok_bot`. `grok_bot` has no local
file registration: doctor reports the Grok Bot chat step, and setup does not
write `mcp.json`. If the client is unknown, use `doctor --json` and
inspect its registration results before choosing a setup scope.
2. Distinguish the reason. Missing, malformed, or stale registration needs a
scoped configuration repair. An aligned registration with no tools in the
active session needs a restart/reconnection; doctor cannot prove that the
current agent has connected. A missing provider affects only tasks requiring
that provider: static JavaScript inspection needs neither Hopper nor Ghidra,
and Android inspection has separate bring-your-own JADX/Java prerequisites.
3. For a configuration repair, prepare the read-only plan:
`npx -y rea-agents@latest setup --client codex --dry-run --json`.
Use the current client's ID, show its exact proposed paths, backups, and
changes, and obtain approval before setup writes configuration or installs
Hopper. Setup normally installs the matching bundled skill too; include that
replacement in the reviewed plan. After approval, apply the same scope with
`npx -y rea-agents@latest setup --client codex --yes`. Add `--install-hopper`
only if that separate installation was needed and explicitly approved.
4. Restart/reconnect the affected agent. Verify that REA tools actually appear
in the session, then resume the original investigation. If they remain
absent, inspect the client's MCP launch error rather than repeating setup.
Choose the installation owner before repairing registration. Plugin installs use
[plugin recovery](references/connection-and-recovery.md#rea-installed-as-a-client-plugin);
only setup-owned registrations use the guide's
[registration repair plan](references/connection-and-recovery.md#repair-registration-when-needed).
A plugin-only doctor result of `missing` does not call for `rea setup`.
REA setup never installs or upgrades Node.js, npm, Homebrew, Java, Ghidra, IDA,
JADX, Kuna, Binwalk, or Unblob. Use existing prerequisites; do not install unrelated
software to repair MCP registration. For an unsupported client, use manual stdio
registration with a version-pinned `rea-agents` package or continue through the CLI.
registration with an existing installation’s absolute runtime and entry script, or continue through the CLI.
A concrete CLI fallback for an operator-supplied JavaScript tree or ASAR is:
@@ -85,8 +69,11 @@ graph, limitations, and unknowns with the same care as an MCP result; the CLI
returns the Evidence record directly. This fallback does not establish that
MCP is configured. Native CLI tasks still require their selected engine.
Prefer an existing `rea` CLI. When none is installed and REA package acquisition
is within the authorized scope, use `npx -y rea-agents@latest` in its place.
Configuration repair starts with a read-only setup plan; show paths, backups and
is within the authorized scope, use `npx -y rea-agents@latest` in its place from a
trusted directory outside the target project, with absolute target paths. Managed
setup binds the current installation directly; retain its runtime and package
cache entry, or restore that installation before repairing its registration.
For setup-owned registration, configuration repair starts with a read-only setup plan; show paths, backups and
skill replacement before applying authorized changes. Preserve existing approval
and target-execution boundaries.
@@ -107,6 +94,9 @@ explicit path or endpoint and do not need it.
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).
- Bun `--compile` executable: `open_binary`, then `inspect_artifact`; the Bun
module graph is the application layer. Extract stored modules and analyze the
JavaScript. See [Bun standalone executables](https://github.com/morluto/rea/blob/main/docs/bun-standalone.md).
- 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
@@ -119,6 +109,8 @@ explicit path or endpoint and do not need it.
`extract_firmware` when extraction is requested, with a caller-selected new
absolute output directory. These tools use caller-supplied Binwalk/Unblob on
Linux; see the [firmware guide](https://github.com/morluto/rea/blob/main/docs/firmware-analysis.md).
- ESP32-family app or bootloader image (`0xE9` magic): `inspect_artifact`
without a provider; see the ESP section of `references/native-and-artifacts.md`.
- .NET NativeAOT PE/ELF: native Ghidra analysis. Native code can yield pseudocode;
consult the NativeAOT workflow in `references/native-and-artifacts.md` for
optional metadata recovery and its supported host/layout boundary.
@@ -158,7 +150,9 @@ explicit path or endpoint and do not need it.
and field names/types before choosing fields for `inspect_packet_capture`.
Query/page the relevant records; registrations do not establish observed traffic.
- Recorded packet captures: `inspect_packet_capture` with selected TShark fields,
display filters and decode-as rules. Requires Linux, util-linux prlimit and `REA_TSHARK_COMMAND`; see
display filters and decode-as rules. Requires Linux, util-linux prlimit and
TShark 4.x on an absolute `PATH` entry or via the optional absolute
`REA_TSHARK_COMMAND` override; see
[capture guide](https://github.com/morluto/rea/blob/main/docs/packet-captures.md).
Packet limits count input packets before filtering. Output defaults to 50 matching
frames; use `match_offset` / `match_limit` for later pages, or explicit null
@@ -344,6 +338,11 @@ leaves its database open. The modern headless profile creates and closes an
owned private database without saving. Installation and registration reuse
[mrexodia/ida-pro-mcp](https://github.com/mrexodia/ida-pro-mcp); see the
[IDA provider guide](https://github.com/morluto/rea/blob/main/docs/ida-provider.md).
For migration to the separate native IDA MCP plugin, follow the guide's
[legacy attached migration](https://github.com/morluto/rea/blob/main/docs/ida-provider.md#migrate-a-legacy-attached-registration).
Replace the upstream registration explicitly; modern mrexodia tools are not the
native profile. Native attachment preserves the database but does not provide
direct callers; check session availability and the guide's verification limits.
Proceed directly to `analyze_function`, pseudocode, or function/string searches
after opening; IDA does not supply `binary_overview`. Consult session availability
when composing broader workflows. Modern direct callers and unsupported dossier
@@ -374,12 +373,16 @@ native target whose analysis tool operates on the active target. Do not call an
unadvertised tool; inspect `binary_session` with `{}` and its
`result.tool_availability` for availability reasons and remediation. Expand each
group's `names` into entries, inheriting the inventory-level client requirements
unless the group overrides them. In its closed effect and annotation vocabularies,
listed flags are true and omitted known flags are false. The grouped name union
is the complete tool inventory; use `tools/list` for canonical tool schemas.
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.
unless the group overrides them. The grouped name union is the complete tool
inventory; use `tools/list` for canonical tool schemas. The default summary keeps
each provider candidate's availability and target-support status, code and
reason; `omitted_fields` lists what it leaves out. Request `{"detail": "complete"}`
only when you need provider diagnostics, candidate capability sets, or tool
surface, effect and annotation flags; in those closed flag vocabularies, listed
flags are true and omitted known flags are false. 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)
@@ -13,6 +13,27 @@ own APK path and explicit selectors; do not open a native session first.
Choose an `overload_index` from the class inventory when methods are ambiguous
instead of guessing.
For JNI implementations, discover `inspect_android_jni_bindings`. Select raw
DEX class/method identities and optional descriptors, ABI or logical library
paths. Prefer `detail: "summary"`; complete Evidence remains retained and
`android-jni` views page declarations, libraries, candidates or binding rows
with exact fields. Global native-pair ambiguity survives class selection.
Preserve slot/relocation provenance and source coverage: matched means observed
candidate presence; partial scans do not establish uniqueness or absence.
This reads DEX/ELF bytes without loading the APK into the decompiler or executing
target code. Runtime registration and loading remain unknown. See the
[JNI guide](https://github.com/morluto/rea/blob/main/docs/android-analysis.md#link-native-declarations-to-jni-candidates).
For an R8/ProGuard release build with its `mapping.txt`, pass the absolute
`mapping_path` to `inspect_android_class` or `inspect_android_method`. Prefer
`detail: "summary"` to receive normalized symbols or the selected body without
duplicate raw class metadata. Complete Evidence stays retained under the linked
parent ID and can be exported; CLI summary delivery requires `--evidence_output`.
Omitted or complete detail preserves the full inline response. Keep
selecting by observed names; the separate `mapping` block reports each symbol
as `mapped`, `ambiguous` or `unmapped` after checking DEX types and prototypes.
REA does not verify that the mapping belongs to the APK build.
The provider requires a separately supplied headless JADX MCP JAR 0.7.1 and
Java 17 or newer. `REA_JADX_MCP_JAR` selects the absolute JAR path; `JAVA_HOME`
can select Java. Use `rea doctor --provider jadx --json` to check the JADX
@@ -17,12 +17,12 @@ does not establish which server an approval wildcard covers. See
| Observation | Meaning and next step |
| --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| No REA tools in the active session | Inspect registration with `rea doctor --client codex --json`. A skill installation alone does not register MCP. |
| No REA tools in the active session | If REA was installed as a client plugin, follow the plugin section below. Otherwise inspect registration with `rea doctor --client codex --json`. A skill installation alone does not register MCP. |
| Missing, malformed or stale registration | Prepare a scoped setup plan; apply only authorized changes with backups. |
| Aligned registration, but no connected tools | Restart/reconnect the client. Doctor checks registration; it cannot establish the current agent's connection. Inspect the client's launch error if reconnection fails. |
| MCP connection dropped or REA could not start | If the connection drops, retry that call once only when it is safe to repeat or known not to have started. If it may already have changed the target, or the same failure returns, tell the user REA's connection failed and ask them to restart the MCP client. If REA could not start its connection, retry once, then tell the user and ask them to restart the MCP client. Do not retry a startup failure that returns the same unchanged result. Run `rea doctor` when REA could not start or tools stay missing after restart. Doctor cannot restore a live connection by itself. |
| `MCP tool call requires approval, but approval policy is never` | Codex rejected the call before REA executed it. Do not install an engine or repeat setup to solve this client-policy decision. See the approval section below. |
| REA returns `provider_unavailable` or an unavailable tool entry | Read that operation's provider diagnostics or `binary_session.result.tool_availability`. Expand each group's tool names and inherit the shared client requirements unless overridden. Use the operation's availability, reason, and remediation; a complete tool catalog does not imply every operation is available. |
| REA returns `provider_unavailable` or an unavailable tool entry | Read that operation's provider diagnostics or `binary_session.result.tool_availability`. Expand each group's tool names and inherit the shared client requirements unless overridden. Use the operation's availability, reason, and remediation; a complete tool catalog does not imply every operation is available. Request `{"detail": "complete"}` only for provider diagnostics. |
| `rea` is missing in a child shell, or Node is incompatible | Inspect the actual shell PATH and launcher/runtime. A prefix installation may be absent from a login shell's PATH; this does not establish a broken MCP registration. |
If the client cannot launch its shell/sandbox helper or read the installed skill,
@@ -116,6 +116,32 @@ is not a recommendation to change it. Do not invent a setting. Host memory and
- `invalid_request`: correct the reported fields from the current schema. Do
not repeat the unchanged call.
## REA installed as a client plugin
A Claude Code or Codex plugin owns its `rea` server and this skill. Doctor's
`--client` and `--skill` checks and `rea setup` read and write only
setup-owned state, so for a plugin-only install they report `missing`, and
applying setup would add a second `rea` server. If this skill was loaded from
a plugin, or the client lists a `rea` plugin, do not prepare a setup plan for
missing tools. Instead:
- Check that the plugin is installed and enabled with the client's own
listing: `claude plugin list` and `/mcp` in Claude Code, `codex plugin list`
in Codex.
- Restart or reconnect the client, then read its launch error for the `rea`
server if tools are still absent. The plugin starts its bundled runtime; a missing build or version mismatch
requires a reinstall, or a fresh build when developing from source.
- Check analysis engines through the connected server's
`binary_session.result.tool_availability`. `rea doctor --provider <id> --json`
from a shell reports that shell's environment, which can differ from the
environment the client gave the plugin server. If you still run it through
the package runner, use the version pinned in the plugin manifest's server
entry (`rea-agents@<version>`), not `@latest`, so it matches the server the
plugin starts.
Use the setup repair below only when the user wants a setup-owned registration
instead of the plugin, and remove or disable the plugin first.
## Repair registration when needed
For Codex:
@@ -130,7 +156,10 @@ Use the current supported client's ID: `claude_code`, `claude_desktop`, `codex`,
`copilot_cli`, `commandcode`, `qwen_code`, `vscode`, `trae`, `grok_build`, `omp`, `pi`,
`hermes`, `qoder`, `droid`, `zcode`, `dsh`, `freebuff`, or `grok_bot`. If unknown, inspect `doctor --json` before choosing a
scope. `grok_bot` uses a chat registration step rather than local `mcp.json`.
For unsupported clients, use version-pinned manual stdio registration or CLI.
For unsupported clients, use manual stdio registration with the selected
installation’s absolute runtime and entry script, or continue through the CLI.
Acquire packages from a trusted directory outside the target project. Keep a
package-runner installation and its runtime available while registrations use it.
Show the plan's exact paths, backups, changes and bundled-skill replacement.
Obtain approval for writes when that concrete scope is not already authorized,
@@ -23,6 +23,14 @@ again if a hint names a gap, then writes the bundle with
- Map the application first with `inspect_web_page` (and `capture_web_screenshot`
when layout matters): the login form's locators, and the API calls behind the
pages that list and edit the entities the user asked about.
- `inspect_web_page` cannot sign in. To see pages behind sign-in, run a short
`capture_browser_scenario` that signs in and opens them, with
`"capture": {"after_each_step": ["accessibility"]}` (`"dom"` for markup).
Read a step's tree with `inspect_analysis_view`, `view: {kind:
"browser-scenario", collection: "text", step_index, artifact:
"accessibility", offset: 0, limit: 2048}`, paging with `offset`. Capture
options are only `after_each_step`, `at_end`, `events`, `network` and
`limits`.
## Record a session an environment can learn writes from
@@ -80,62 +88,123 @@ shape, with the application's own locators, paths and headers:
"path": "/api/folders",
"expected_status": [200]
},
{
"step_id": "new-folder-1",
"action": "click",
"timeout_ms": 15000,
"locator": { "kind": "role", "role": "button", "name": "New folder" }
},
{
"step_id": "folder-title-1",
"action": "fill",
"timeout_ms": 15000,
"locator": { "kind": "css", "selector": "input[name=title]" },
"value": { "source": "literal", "value": "Scratch folder 1" }
},
{
"step_id": "create-folder-1",
"action": "click",
"timeout_ms": 15000,
"locator": { "kind": "role", "role": "button", "name": "Create" },
"save_response": {
"method": "POST",
"path": "/api/folders",
"save": [{ "name": "folder_1", "json_pointer": "/id" }]
}
},
{
"step_id": "read-folder-1",
"action": "request",
"timeout_ms": 15000,
"method": "POST",
"path": "/api/folders",
"json": { "title": "Scratch folder 1" },
"headers": [
{
"name": "X-CSRFToken",
"value": { "source": "cookie", "name": "csrftoken" }
}
],
"expected_status": [200, 201]
"method": "GET",
"path": "/api/folders/{saved:folder_1}",
"expected_status": [200]
}
]
}
```
Give every step a `timeout_ms`. A step without one waits until the scenario
is cancelled, so a locator that never matches hangs the capture, and the
client with it. Match `wait_for` locators to exactly one element.
Give each step that accepts `timeout_ms` a deadline. Without one, a step waits
until it completes or the scenario is cancelled, so a locator that never
matches hangs the capture and the client with it. The `wait_for_timeout` pause
instead uses `duration_ms` and does not accept `timeout_ms`. Match `wait_for`
locators to exactly one element.
1. Sign in through the UI: `fill` the user and password fields (the password
as a secret reference), submit, then `wait_for` an element only a signed-in
user sees.
2. Read with `request` steps: each collection the environment needs, twice
before any write, so fields that change on their own show up; one item of
each.
3. Use `request` steps only when the API lets the caller choose each scratch
object's ID or a prior read already established it. Request paths are fixed
strings; no action substitutes a value from an earlier response. For
server-assigned IDs, create through the UI and open the new object's detail
view to record its read, edit and delete through UI actions. If that journey
cannot be scripted, leave the write unserved and report the limitation;
never guess an ID or create objects with no supported cleanup path.
before any write, so fields that change on their own show up; then each
object a list shows by id, up to ten per collection. An object known only
from a list that leaves out fields its own read shows cannot be read by id
or updated in the environment.
3. Write the way the application's UI does: fill its forms and click its
buttons, so each request carries the fields the UI sends, including ones
the server would otherwise derive. Give the click or key press that submits
a create `save_response` to keep the new object's ID, then `goto` its page
(`/items/{saved:item_1}`) or read it with a `request` step. Never guess an
ID, and never create a probe object to learn the next one. Write with
`request` steps instead only when the UI cannot reach the operation (an
API-only resource, or a UI that does not call the JSON API), or when coverage
withholds the UI-shaped write as `unexplained-change` or `contradicted`;
that counts as one of the two re-recordings. A `request` step write that
coverage withholds that way usually lacks fields the UI sends: record it
through the UI instead. If a journey cannot be scripted, leave the write
unserved and report the limitation.
Record two numbered scratch objects per write type,
with varied free text. After each write, and before the next one, read the
object back by id and then its list: create 1, read 1, list, create 2,
read 2, list; never several writes before their reads.
4. Leave more than a second between a create and its first edit
(`wait_for_timeout` with `duration_ms: 1100`).
5. Update both objects and read each back; delete both and read each back
(expect 404) and the list.
4. Leave more than a second between two creates and between a create and its
first edit (`wait_for_timeout` with `duration_ms: 1100`), so lists sorted
by creation time show them in order.
5. Update both objects and read each back, changing the fields a person
would change (a name, an email address, a status, a due date) rather than
only a description: a served update accepts only the members a recorded
update stored. Run an action that turns something on or off (star,
bookmark, archive) twice in a row on one object, reading it back after
each: the second call shows whether it sets or flips the field, and the
environment serves the action only once a call has shown it. Delete both
and read each back (expect 404, or the object marked deleted) and the list.
6. Vary what the two creates send, however you write them: the first every
field the application takes, the second only what a person must give (its
title or name), with the other fields left out or empty. A served create
requires each member both creates filled in and lets a caller leave out one
a create left out or sent empty, so an agent that names only a title is not
refused for fields it had no reason to set.
About `request` steps:
- `path` is on the start URL's origin; the page must be on that origin.
- Header values are literals, declared secrets, a cookie the browser holds
(`{source: "cookie", name}`), or a local storage entry
(`{source: "local_storage", key, json_pointer}`), with an optional
`prefix` such as `"Bearer "`. Copy the headers the application's own
requests send (a CSRF header, a bearer token). Values read from the page
are redacted from records made after they are read, not from the login
response that returned them, and values shorter than 8 characters are not
redacted at all.
(`{source: "cookie", name}`), a local storage entry
(`{source: "local_storage", key, json_pointer}`), a saved value
(`{source: "saved", name}`), or Basic credentials
(`{source: "basic_credentials", parts: [username, password]}`, sent as the
base64 of `username:password` and redacted), with an optional `prefix` such as
`"Bearer "` or `"Basic "`. Each credential part is a literal, secret, saved
value, cookie or local storage entry, so a header the frontend builds from a
login token (the username and the token) can be copied too; the password is
a secret or saved value, never a literal. Copy the
headers the application's own requests send (a CSRF header such as
`X-CSRFToken` from the `csrftoken` cookie, a bearer token). Values read from the page are redacted from records made after they
are read, not from the login response that returned them, and values
shorter than 8 characters are not redacted at all.
- `save: [{name, json_pointer, secret}]` keeps a string or number from the
step's JSON response, such as the created object's `/id`, for later steps;
`secret: true` redacts it, as for a token the API returns, so mark every
saved token, key or session value secret. This also protects the selected
source response before its body or headers are retained. Compressed or
unknown-size UI responses cannot supply saved values. On a `click` or `press`,
`save_response: {method, path, save}` keeps values from the response to the
new request observed while the step waits (`{*}` in `path` matches one segment).
Matching does not prove UI causality: choose a path distinct from polling;
multiple observed matches fail as ambiguous. The step
fails unless a 2xx JSON response arrives before its `timeout_ms`. Later
steps send a saved value as `{saved:name}` in a request `path` (and its
query) or a `goto` URL; in the `json` body, where a string that is only
`{saved:name}` keeps the saved JSON type; or as `{source: "saved", name}` in
a header or credential part.
- Reading a page value makes later bodies costlier to keep: after a CSRF
token, bodies over about 47 KiB are kept as `unavailable`. When the API
returns larger responses, raise `capture.limits`
@@ -172,20 +241,22 @@ Re-record a withheld write at most twice, and only for a recording gap. Stop at
once when the reason is application behaviour, and report the write as
withheld with its hint:
| Reason | What to do |
| --------------------- | --------------------------------------------------------------------------------------------- |
| `no-state-target` | Re-record: read the collection or item the write changes. |
| `no-observation` | Re-record: read the entity back by id after the write; read it first for an update or delete. |
| `unconfirmed` | Re-record: read the entity and its list after the write. |
| `incomplete-entities` | Re-record: read the entity through every view that lists it. |
| `unexplained-change` | Re-record once with a second, different call of the same write. |
| `no-call` | Re-record once with a write that succeeds. |
| `side-effect` | Stop: the application changes other entities. |
| `contradicted` | Stop: a later read disagrees with the modelled effect. |
| `body-unusable` | Stop: the body is not a JSON object. |
| Reason | What to do |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `no-state-target` | Check the path template and recorded views; record missing reads. The route form may not be supported as a mutation target. |
| `no-observation` | Re-record: read the entity back by id after the write; read it first for an update or delete. |
| `unconfirmed` | Re-record: read the entity and its list after the write. |
| `incomplete-entities` | Re-record: read the entity through every view that lists it. |
| `unexplained-change` | Re-record once with a second, different call of the same write. |
| `no-call` | Re-record once with a write that succeeds. |
| `side-effect` | Stop: the application changes other entities. |
| `contradicted` | Stop: a later read disagrees with the modelled effect. |
| `body-unusable` | Re-record a UI write once with `request` steps (its body was not exposed); else stop. |
Use new scratch names on each attempt; the first attempt's objects may still
exist.
Use new scratch names on each attempt, and delete what an earlier attempt
created before recording again (through the UI, or a `request` step with the
id that capture shows): the environment starts from what the recording first
reads, so a leftover object becomes seeded data that write tasks then find.
New browser scenario captures include request times, so a fully timed capture
can learn a write clock and serve updates that stamp modification times. Older
captures or ones missing a request start keep record order and learn no clock.
@@ -46,7 +46,10 @@ Use comparisons with complete, compatible page sets when claiming equivalence
or absence:
- `compare_artifacts` compares inventory pages by occurrence path, content,
metadata, and graph relations.
metadata, and graph relations. Name each side as
`{kind: "retained-evidence", evidence_id}` (an `inspect_artifact` result,
its nested inventory or its summary) or
`{kind: "evidence-file", path, evidence_id?}` instead of resending Evidence.
- `compare_functions` compares explicit function Evidence, not fuzzy
whole-binary matches. It rejects an `analyze_function` summary reply; pass
the summary's `parent_evidence_id` as a `retained-evidence` reference or
@@ -78,6 +78,15 @@ classification, and unavailable sources never establish route reachability or
the complete application route denominator. See the
[route inventory guide](https://github.com/morluto/rea/blob/main/docs/javascript-route-inventory.md).
For captured endpoint observations and inference facts, `analyze_web_bundle`
also accepts `view: {kind: "web-bundle", collection: "endpoints", limit: 32}`
with `detail: "summary"`. Read later `endpoints`, `inferences`, or `summary`
pages from the retained parent. Filter before requesting detail; retain
`source_index` together with parent ID and collection, and request `location`
or `basis` when tracing sources. Page exhaustion does not mean producer
completeness: check `completeness`, structured `source_unknowns`, and limitations.
Endpoint candidates remain inferences rather than confirmed network behavior.
## Read a module without repeating analysis
Use the actual returned parent ID, on the same connection, as `source.evidence_id`.
@@ -13,6 +13,13 @@ 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.
For a matching representation refusal, inspect `details.limit` and raise
`native.matching_representation_bytes` with `update_analysis_settings` before
retrying the unchanged MCP request. CLI launch seed:
`REA_NATIVE_MATCHING_REPRESENTATION_BYTES`. The default is 96 MiB; the policy
range is 1 byte to 1 GiB and does not bound process RSS. Keep the complete
inventories: splitting them changes global name/body uniqueness.
## Apple app resources
Use `open_bundle_resources` with the selected app path, then `inspect_plist`,
@@ -316,26 +323,43 @@ run, use `observe_native_calls` with explicit breakpoints and a bounded
`duration_ms`/`max_events`. It launches a new process under LLDB, so the target
runs and may change files or use the network. Hardened-runtime targets need the
`get-task-allow` entitlement.
Function breakpoints use exact LLDB runtime names: a Darwin C `_main` static symbol
may be `main` at runtime. REA does not translate names. Set `module` to the image
Function breakpoints use exact LLDB runtime names: pass an `inspect_macho` export
or import `runtime_name` (`main`), not its symbol-table `name` (`_main`). REA does
not translate breakpoint names. Set `module` to the image
file name when selecting that image only; otherwise loaded system images also
match. Inspect retained locations and module paths before attributing a call.
Use `binary_session` with no arguments to check the open target, selected
provider, and alignment. Its default `result.tool_availability` carries a
complete inventory grouped by shared facts. Expand each group's `names` and
inherit the inventory-level client requirements unless a group overrides them;
availability, reasons, remediation, modes, and flags remain inline. The
`effects` and `annotations` arrays name true flags from fixed vocabularies, so an
omitted known flag is false. `tools/list` remains the canonical source for full
tool schemas when target or provider state changes.
provider, and alignment. Its default summary `result.tool_availability` carries
the complete tool inventory grouped by current status. Expand each group's
`names` and inherit the inventory-level client requirements unless a group
overrides them; availability, reasons, remediation, and modes remain inline.
Provider candidates keep availability and target-support status, code, and
reason. `omitted_fields` names what the summary leaves out; `{"detail":
"complete"}` adds provider diagnostics, candidate capability sets, and tool
surface, `effects`, and `annotations`. Those arrays name true flags from fixed
vocabularies, so an omitted known flag is false. `tools/list` remains the
canonical source for full tool schemas when target or provider state changes.
Provider capability groups carry provider identity and ordered limitations.
Prepend each set's `shared_limitations` to a group's `limitations` to recover the
operation's full ordered list. Candidate capabilities describe possible
providers. Top-level session capabilities describe the current route, and
operation's full ordered list. Candidate capabilities, returned with complete
detail, describe possible providers. Top-level session capabilities describe the current route, and
`analysis_provider_binding` identifies the selected provider.
## Reuse caller-selected Ghidra analysis
When the caller supplies an expanded project, configure `REA_GHIDRA_PROJECT_PATH`
(the `.gpr` marker) and optionally `REA_GHIDRA_PROGRAM_NAME` (one root program),
then restart/reconnect before `open_binary`. CLI uses the same configuration.
REA opens only a fingerprint-bound owned copy with `-process -noanalysis -readOnly`;
original project files are not opened by the engine or saved. Database edits,
import overrides and repair scripts are unavailable in this mode. Treat original
analysis completeness/settings as unknown and prior edits as caller-project state.
The program's recorded import digest must match the target; changed project content
requires reopening for a fresh profile. See the
[setup and preparation guide](https://github.com/morluto/rea/blob/main/docs/installation.md#reuse-an-existing-ghidra-project).
## Ghidra startup deadline recovery
`provider_timeout` during the first Ghidra query can cover import, auto-analysis,
@@ -399,6 +423,21 @@ encoded in bounded batches.
The 25000 ms Cutter request deadline and the 256-candidate discovery budget
still have no runtime override.
## Selected native facts and call graphs
For a large `get_call_graph`, or repeated `procedure_address`,
`procedure_callees`, `procedure_callers` and `resolve_containing_procedure`
queries, select `detail: "summary"` when the first 64 recorded observations
suffice. Read further `native-observation` pages from the returned parent Evidence
ID. Graph message IDs index that page's exact-text dictionary; keep level,
source index, failed nodes, and partial/unknown relationship coverage.
Read referenced source context through `native-context` facets `overview`,
`analysis-profile`, `limitations` and `result-limitations`. Reuse inspected
context/profile values only for the same digest; until caveats are read,
interpretation beyond the returned facts remains unknown. Complete Evidence
remains retained and exportable. Small complete replies can cost fewer tokens
than additional context/page calls; count the completed task and discovery.
## Static memory and original file bytes
For Ghidra, `read_bytes` reads initialized analysis memory, including loader
@@ -426,6 +465,14 @@ loaded bytes, file mappings, relocations and the entry against the immutable
snapshot. Keep `mismatch` and `unsupported` explicit. Verified import covers the
reported static image, not runtime DOS or PC-98 hardware behavior.
For a large load-image report, select `detail: "summary"` and query its
`parent_evidence_id` with `inspect_analysis_view` kind `native-load-image`.
Choose a collection such as `relocations` or `mappings`, select only needed
fields, and page with offset/limit. Original indices preserve same-address
alternatives. Null collections remain unrecorded or inapplicable; paging does
not upgrade unsupported verification. CLI requires `--evidence_output` for
summary delivery so complete source Evidence remains accessible.
For Ghidra decompilation, `procedure_pseudo_code` also accepts `procedure: "file-offset:0x..."`; CLI `rea decompile <path> --file-offset=0x... --provider ghidra` resolves the source byte offset internally. An unresolved 0x-prefixed numeric procedure selector also falls back to a unique file mapping. Existing symbols and analysis addresses win; multiple mappings fail as ambiguous. Preserve the returned file-offset and address locations and raw selection observations. ELF virtual addresses are distinct from file offsets; never assume an arbitrary offset plus image base is an analysis address.
Complete function body ranges use inclusive ends and can contain gaps. Do not
@@ -469,6 +516,11 @@ names), coverage and per-collection counts. Page rows with
`view: {kind: "managed-members", collection: "call_edges", offset: 0, limit: 64}`
over `types`, `exported_types`, `fields`, `methods`, `member_refs`, `call_edges`,
`field_accesses` or `user_strings`.
Use exact `names` and `declaring_types` filters before paging supported
collections. For a compact method lookup, request `fields: ["name",
"declaring_type", "signature"]`; omit `body` to avoid anchors. Identity tokens,
original `source_index`, module/MVID and source coverage remain. Check
`unresolved_filter_rows` before interpreting an empty match as absence.
### .NET NativeAOT
@@ -556,6 +608,7 @@ discovery are unsupported. Windows Ghidra P0 admits raw images only for `6502`.
### Function annotations in Ghidra
Fresh-import sessions admit annotations; existing-project reuse is read-only.
Use `annotate_native_function` for one function name and/or entry comments, with at least one explicit change. Review its annotation readback and refreshed dossier inline. Changes are atomic and session-scoped; empty comments clear them, omitted fields preserve them. Later MCP calls observe edits until close. CLI `annotate-native-function` returns the updated analysis before discarding the session. Original executable bytes are unchanged; edits invalidate immutable snapshots. Windows P0 does not admit database mutations. For naming only, `set_address_name` / `set_addresses_names` also work with Ghidra: they name function entries or data addresses (primary labels) and return compact per-address success booleans instead of a dossier.
## Offline PE resource inventory
@@ -604,3 +657,58 @@ 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).
UnityFS AssetBundle containers (`.bundle`, `.ab`, YooAsset packages and other
byte-identified files) list `CAB-*` SerializedFiles and `.resS` members with
header and node facts; none/LZ4/LZ4HC member blocks stream on demand. Bundles
declaring asset-bundle encryption keep header facts with unknown directory
coverage; LZMA member bytes retain named occurrences with unavailable hashes.
Virtual member offsets are not physical carrier locations. Format 6–8 readers
cache one decoded block and support retained filtered/paged views. No
decryption or SerializedFile object decoding is provided. See
[UnityFS](https://github.com/morluto/rea/blob/main/docs/unityfs.md).
U-Boot legacy uImages use the same inspection/extraction workflows. Prefer a
retained summary and selected inventory views for header facts or component
IDs. Header addresses/CPU/OS are declarations; payloads remain as stored.
Multi-file components retain their aligned physical ranges; the full payload
is also materialized. Unknown name text retains its original 32 bytes. See
[U-Boot uImage](https://github.com/morluto/rea/blob/main/docs/uimage.md).
## ESP images
For an ESP32-family app or bootloader image, `open_binary` then
`inspect_artifact` with `detail: "summary"`. `root_format_metadata` holds the
observed `header` and `descriptor` (its `kind` is the app or bootloader role)
and the derived `chip`, `checksum`, `appended_sha256` and
`undescribed_trailing` ranges. Segment rows (`segment-NN.bin`) carry
`load_addr`, `classification` (`mapped`, `loaded`, `not-loaded` or `unknown`,
per ESP-IDF `should_map`/`should_load`; RAM ranges are not checked) and
`source_location`; select them with `inspect_analysis_view` and
`logical_paths`. Signature blocks are `unverified`; `public_key_sha256`
matches eFuse key digests.
Unknown `source_coverage` means truncation or undescribed trailing bytes, such
as the flash segments of a `--ram-only-header` image; do not infer absence
from it. Erased flash is described. Integrity mismatches are facts, not
refusals. ESP8266 images are refused, and flash-encrypted images are not
recognized. Segments are not disassembled, and RISC-V or Xtensa segments
cannot be opened as raw-binary. See
[ESP images](https://github.com/morluto/rea/blob/main/docs/esp-image.md).
## Bun standalone executables
A `bun build --compile` executable stores its module graph in Mach-O
`__BUN,__bun`, a PE or ELF `.bun` section, or an appended trailer.
`open_binary` then `inspect_artifact` reports root format `bun-standalone` with
the carrier, structural layout, module count, entry point, raw flags and
compile exec-argv; each module keeps its `/$bunfs/...` source name, loader,
encoding, sizes and SHA-256, with sourcemap, bytecode and module-info regions as
separate children. Use summary root metadata `entry_point_logical_path` as the
exact inventory `logical_paths` selector, then read the selected content node by
its artifact ID; the reader owns virtual-name normalization and indexed fallback. `extract-artifact` writes stored contents through the safe
output tree; route extracted JavaScript to `analyze_javascript_application`.
Layout labels describe record shapes, not a detected compiler version; unknown
or ambiguous layouts are unsupported. Bytecode is retained, not decoded, and the
executable is never run. See
[Bun standalone executables](https://github.com/morluto/rea/blob/main/docs/bun-standalone.md).
@@ -86,6 +86,8 @@ Page-declared WebMCP tools are untrusted inventory and are never invoked by REA.
browser and profile. Check `browser.cleanup` for the outcome.
Request only the DOM, accessibility, or network details needed for the question.
The default final capture contains the URL; step outcomes are reported separately.
For multi-step flows with trees or events, select `detail: "summary"` and page
exact steps, transactions, text slices or events with `inspect_analysis_view` kind `browser-scenario`.
Add a wait action for the expected page state before capturing it. Report that
REA performed the declared actions.
+21
View File
@@ -0,0 +1,21 @@
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "rea",
"description": "Reverse engineer anything with agents, from app behavior down to native binaries.",
"owner": {
"name": "morluto",
"url": "https://github.com/morluto"
},
"plugins": [
{
"name": "rea",
"description": "Reverse engineer anything with agents, from app behavior down to native binaries.",
"source": {
"source": "npm",
"package": "rea-agents",
"version": "6.8.0"
},
"category": "development"
}
]
}
+29
View File
@@ -0,0 +1,29 @@
{
"name": "rea",
"version": "6.8.0",
"description": "Reverse engineer anything with agents, from app behavior down to native binaries.",
"author": {
"name": "morluto",
"url": "https://github.com/morluto"
},
"homepage": "https://rea.tools/",
"repository": "https://github.com/morluto/rea",
"license": "MIT",
"keywords": [
"reverse-engineering",
"binary-analysis",
"decompiler",
"mcp-server"
],
"skills": "./skills",
"mcpServers": {
"rea": {
"command": "node",
"args": [
"${CLAUDE_PLUGIN_ROOT}/scripts/plugin-mcp-launcher.mjs",
"6.8.0"
]
}
},
"icon": "./assets/rea-plugin.png"
}
+13
View File
@@ -0,0 +1,13 @@
{
"mcpServers": {
"rea": {
"command": "node",
"args": [
"./scripts/plugin-mcp-launcher.mjs",
"6.8.0"
],
"cwd": ".",
"startup_timeout_sec": 30
}
}
}
+40
View File
@@ -0,0 +1,40 @@
{
"name": "rea",
"version": "6.8.0",
"description": "Reverse engineer anything with agents, from app behavior down to native binaries.",
"author": {
"name": "morluto",
"url": "https://github.com/morluto"
},
"homepage": "https://rea.tools/",
"repository": "https://github.com/morluto/rea",
"license": "MIT",
"keywords": [
"reverse-engineering",
"binary-analysis",
"decompiler",
"mcp-server"
],
"skills": "./skills",
"mcpServers": "./.codex-plugin/mcp.json",
"interface": {
"displayName": "REA",
"shortDescription": "Reverse engineer anything",
"longDescription": "Reverse engineer anything with agents, from app behavior down to native binaries.",
"developerName": "morluto",
"category": "Developer Tools",
"capabilities": [
"Interactive",
"Read",
"Write"
],
"websiteURL": "https://rea.tools/",
"defaultPrompt": [
"Use REA to explain how this binary implements a feature.",
"Use REA to compare two versions of this application.",
"Use REA to recover the sources from this JavaScript bundle."
],
"composerIcon": "./assets/rea-plugin.png",
"logo": "./assets/rea-plugin.png"
}
}
+12
View File
@@ -0,0 +1,12 @@
# Review changes to security-sensitive automation and dependency inputs.
/.github/CODEOWNERS @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/.github/dependabot.yml @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/.github/workflows/ @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/.github/actions/ @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/package.json @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/package-lock.json @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/scripts/verify-tools/skills/package.json @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/scripts/verify-tools/skills/package-lock.json @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/scripts/fixtures/http3-lab-requirements.txt @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/website/requirements.txt @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
/third_party/ @morluto @kaoru0822-kitauji @N0zoM1z0 @gensokyo-dev
+33
View File
@@ -0,0 +1,33 @@
version: 2
updates:
- package-ecosystem: npm
directories:
- /
- /scripts/verify-tools/skills
schedule:
interval: weekly
cooldown:
default-days: 7
open-pull-requests-limit: 5
groups:
npm-minor-and-patch:
update-types:
- minor
- patch
- package-ecosystem: pip
directory: /website
schedule:
interval: weekly
open-pull-requests-limit: 5
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
groups:
actions-minor-and-patch:
update-types:
- minor
- patch
+40 -24
View File
@@ -144,6 +144,9 @@ jobs:
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: .nvmrc
- name: Validate source architecture before dependency installation
if: needs.changes.outputs.code == 'true'
run: node scripts/verify/architecture-guards.mjs
- name: Cache npm package downloads
id: npm-cache
uses: ./.github/actions/npm-cache
@@ -317,7 +320,7 @@ jobs:
id: npm-cache
uses: ./.github/actions/npm-cache
- run: npm ci
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: rea-test-runtime
path: .
@@ -426,7 +429,7 @@ jobs:
- name: Download previous timing report
if: steps.history.outputs.run-id != ''
continue-on-error: true
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: ${{ steps.history.outputs.artifact-name }}
run-id: ${{ steps.history.outputs.run-id }}
@@ -493,7 +496,7 @@ jobs:
uses: ./.github/actions/npm-cache
- if: needs.changes.outputs.code == 'true' && success()
run: npm ci
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
if: >-
!cancelled() && needs.changes.outputs.code == 'true' &&
(needs.test-shard.result == 'success' || needs.test-shard.result == 'failure' ||
@@ -692,11 +695,11 @@ jobs:
assert.equal(process.arch, process.env.EXPECTED_CI_ARCHITECTURE);
console.log(JSON.stringify({ platform: process.platform, architecture: process.arch, node: process.version }));"
- run: npm ci
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: rea-build-cache
path: .turbo/cache/
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: windows-native-controls
path: native/windows/build/
@@ -736,7 +739,7 @@ jobs:
id: npm-cache
uses: ./.github/actions/npm-cache
- run: npm ci
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: rea-build-cache
path: .turbo/cache/
@@ -753,6 +756,14 @@ jobs:
- name: Run native Apple and process boundary regressions
run: >-
npm run test:focused --
tests/boundary/providers/hopper/hopperMacLaunchArguments.test.ts
tests/acceptance/providers/hopperStartupRecovery.test.ts
tests/boundary/providers/hopper/hopperClient.helperFailure.test.ts
tests/boundary/providers/hopper/bridgeBootstrapCleanup.test.ts
tests/boundary/providers/hopper/bridgeTargetLease.integration.test.ts
tests/acceptance/artifactDmgAttachmentRecoveryCli.test.ts
tests/boundary/providers/native/nativeDmgArtifactReader.test.ts
tests/process-global/dmgCancellationReason.test.ts
tests/boundary/filesystem/installScript.test.ts
tests/boundary/filesystem/nibNativeHierarchy.test.ts
tests/boundary/filesystem/interfaceBuilderBundle.test.ts
@@ -765,6 +776,7 @@ jobs:
tests/boundary/providers/native/nativeSignatureTargetBinding.test.ts
tests/boundary/cli/nativeSignatureCli.test.ts
tests/boundary/cli/nativeMachoArm64_32Cli.test.ts
tests/boundary/cli/nativeMachoEncryptionCli.test.ts
tests/boundary/mcp/nativeSignatureTargetBindingMcp.test.ts
src/process/capture/FilesystemSnapshot.test.ts
tests/process-global/filesystemSnapshotFallbackCancellation.test.ts
@@ -827,11 +839,11 @@ jobs:
GOMAXPROCS: "2"
GOMEMLIMIT: "3GiB"
run: npm run typecheck -- --checkers 2
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: rea-build-cache
path: .turbo/cache/
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: windows-native-controls
path: native/windows/build/
@@ -852,6 +864,24 @@ jobs:
# The matching native artifact establishes real Job Object and private
# runtime boundaries for these fixtures. Ghidra and Java are not needed;
# real engine claims remain in the separate controlled-provider workflow.
# Run native proofs before the broad curated suite so an unrelated
# fixture failure cannot hide the real control and recovery checks.
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: windows-process-boundary-fixture
path: .cache/windows-process-boundary/
# Passing the fixture adds the breakaway, caller/child token, environment
# semantics and ancestor reparse observations, which the lane skips
# entirely when it is absent.
- run: >-
npm run verify:windows-native -- .
"${{ github.workspace }}\.cache\windows-process-boundary\process-boundary.exe"
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: windows-native-inspection-fixture
path: .cache/windows-native-inspection-fixture/
- name: Verify native inspection failure ownership and recovery
run: node scripts/verify-windows-native-inspection.mjs
- name: Run curated Windows capability tests
run: >-
npx vitest run --coverage.enabled=false
@@ -868,6 +898,7 @@ jobs:
tests/boundary/providers/native/artifactProvider.extractionCompleteness.test.ts
tests/boundary/filesystem/setupUnavailableProvider.test.ts
tests/boundary/filesystem/windowsNpxRegistration.test.ts
tests/boundary/filesystem/claudeDesktopSkillUninstallWindows.test.ts
tests/boundary/filesystem/clientConfigurationEnvironment.test.ts
tests/boundary/filesystem/clientConfigurationLayeredEnvironment.test.ts
tests/acceptance/setup/registrationRuntimeEnvironmentCli.test.ts
@@ -879,6 +910,7 @@ jobs:
tests/boundary/process/packageNpmInvocation.test.ts
tests/boundary/process/packedBridgeVerification.test.ts
tests/boundary/process/windowsOutputCapture.test.ts
tests/boundary/process/windowsExecutableSelection.test.ts
tests/acceptance/webModuleCli.test.ts
tests/acceptance/webSourceLocationCli.test.ts
tests/boundary/cli/referenceSourceImportStatus.test.ts
@@ -903,22 +935,6 @@ jobs:
tests/process-global/runnerCancellation.test.ts
tests/process-global/windowsOwnedCommand.test.ts
tests/conformance/providers/ghidra/realGhidraWindowsWorkflow.test.ts
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: windows-process-boundary-fixture
path: .cache/windows-process-boundary/
# Passing the fixture adds the breakaway, caller/child token, environment
# semantics and ancestor reparse observations, which the lane skips
# entirely when it is absent.
- run: >-
npm run verify:windows-native -- .
"${{ github.workspace }}\.cache\windows-process-boundary\process-boundary.exe"
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: windows-native-inspection-fixture
path: .cache/windows-native-inspection-fixture/
- name: Verify native inspection failure ownership and recovery
run: node scripts/verify-windows-native-inspection.mjs
- name: Verify real Node Inspector discovery and observation
timeout-minutes: 10
env:
+1 -1
View File
@@ -61,7 +61,7 @@ jobs:
uses: ./.github/actions/npm-cache
- run: npm ci
- if: matrix.platform == 'Windows'
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: cutter-windows-native
path: native/windows/build/
+2 -2
View File
@@ -69,12 +69,12 @@ jobs:
with:
node-version-file: .nvmrc
- run: npm ci
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: real-ghidra-windows-native
path: native/windows/build/
- run: npm run verify:windows-native:artifact
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: real-ghidra-windows-process-boundary
path: .cache/windows-process-boundary/
+2 -2
View File
@@ -52,14 +52,14 @@ jobs:
path: .cache/release-source
persist-credentials: false
- name: Download original qualified package
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: verified-release-package
run-id: ${{ steps.release.outputs.run_id }}
github-token: ${{ github.token }}
path: .cache/verified-package
- name: Restore original verifier runtime
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: rea-test-runtime
run-id: ${{ steps.release.outputs.run_id }}
+1 -1
View File
@@ -422,7 +422,7 @@ jobs:
package-manager-cache: false
registry-url: https://registry.npmjs.org
- name: Download the original qualified package
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: verified-release-package
path: .cache/verified-package/
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
id: npm-cache
uses: ./.github/actions/npm-cache
- run: npm ci
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: rea-test-runtime
path: .
+1 -1
View File
@@ -103,7 +103,7 @@ jobs:
node-version-file: .nvmrc
- name: Download the verified website
if: inputs.target == 'both'
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: github-pages
path: ${{ runner.temp }}/website-archive
+1 -1
View File
@@ -50,7 +50,7 @@ Thumbs.db
# Local reference sources and analysis artifacts
/_reference/
/experiments/analysis-efficiency/results/
/experiments/analysis-efficiency/
# Generated website download
/website/public/examples/notes-example.zip
+4 -1
View File
@@ -10,7 +10,10 @@
"node_modules/**",
"CHANGELOG.md",
"package-lock.json",
".claude-plugin/plugin.json",
".codex-plugin/plugin.json",
"_reference/**",
"third_party/**"
"third_party/**",
".codex-plugin/mcp.json"
]
}
+6 -3
View File
@@ -53,9 +53,12 @@ Optimize in this order:
3. CPU and memory. Avoid unnecessary work and copies; bound concurrency,
retained state and serialization growth.
For changes affecting these costs, measure representative completed tasks and
compare equivalent workflows before and after where available. Report token
usage, elapsed time, CPU time and peak process-family memory. Separate cold
Reserve performance measurements for changes that target performance or have a
concrete regression concern. Routine cleanup uses correctness checks; changes
to helper calls, imports, or representations alone do not require synthetic
benchmarks. When measurement is warranted, measure representative completed
tasks and compare equivalent workflows before and after where available. Report
token usage, elapsed time, CPU time and peak process-family memory. Separate cold
and warm runs, label estimates, and state unmeasured costs. Fewer bytes alone
do not establish fewer tokens or faster analysis.
+2 -2
View File
@@ -2683,7 +2683,7 @@ Read the [6.1 to 6.2 migration guide](docs/migration-6.2.md) before upgrading. R
* enforce conventional pull request titles ([3a21f16](https://github.com/morluto/rea/commit/3a21f16c1832430765083636511a8c12dbccf2dd))
* verify installed package with Linux Hopper ([4f97f69](https://github.com/morluto/rea/commit/4f97f699e4d5471557d1ce0ff91e144065d06a61))
## [0.3.0](https://github.com/morluto/rea/compare/rea-agents-0.2.1...rea-agents-0.3.0) (2026-07-12)
## [0.3.0](https://github.com/morluto/rea/compare/rea-0.2.1...rea-agents-0.3.0) (2026-07-12)
### Features
@@ -2736,7 +2736,7 @@ Read the [6.1 to 6.2 migration guide](docs/migration-6.2.md) before upgrading. R
* redesign and localize README ([051b6db](https://github.com/morluto/rea/commit/051b6db65687fd14826b6462cd623feb2504f123))
* redesign and localize README ([910eda6](https://github.com/morluto/rea/commit/910eda6f323ba1151b0771fe5de6c60a91e3d46d))
## [0.2.0](https://github.com/morluto/rea/compare/rea-0.1.0...rea-0.2.0) (2026-07-12)
## [0.2.0](https://github.com/morluto/rea/releases/tag/rea-0.2.0) (2026-07-12)
### Features
+15 -1
View File
@@ -232,6 +232,8 @@ Use the development toolchain pinned in `.nvmrc` and
`package.json#packageManager`. Run `nvm use` before installing dependencies;
installed-package runtime support is documented in
[installation](docs/installation.md#start-setup).
Use Node.js and npm for source builds and verifier scripts; the installed
package's Bun runtime support does not extend to those development scripts.
```bash
npm ci
@@ -246,6 +248,15 @@ catalogs, documentation projections, or managed verification evidence. Turbo
caches deterministic builds and static checks across Git worktrees. After a package, lockfile, or managed-skill version change, run
`npm run metadata:generate` before building.
Dependabot proposes updates for the npm lockfiles, website Python requirements,
and GitHub Actions. Review dependency changes and run the checks relevant to
their consumers. For dependencies maintained outside Dependabot, including
`third_party/` and the HTTP/3 lab's pinned requirements, the maintainer should
review upstream security advisories when updating or using them. Preserve source
and version provenance, update license notices when needed, and report which
verification was actually repeated. The lab requirements describe a recorded
environment; a dependency update does not verify the revised environment.
Repository invariants live in [AGENTS.md](AGENTS.md). Keep provider-specific
protocols in adapters and shared CLI/MCP workflows in the application layer.
@@ -272,7 +283,10 @@ The general source suite (`npm run test:fast`, `npm run test:changed`, and
On a Windows checkout, some source tests fail because fixtures use POSIX paths,
`#!/bin/sh` tool stubs, or POSIX rename semantics. Compare failures against the
base revision, or run the suite on Linux or WSL, before attributing them to a
change. See [testing](docs/testing.md#developer-commands) for command scopes
change. The embedded-artifact parent-swap tests exercise the selected-path
replacement when the rename succeeds; if Windows refuses it while the admitted
file is open, they instead verify the refusal and cleanup. See
[testing](docs/testing.md#developer-commands) for command scopes
and lane selection.
`git submodule update --init --recursive` fails at the pinned Unblob submodule
+63 -10
View File
@@ -20,7 +20,7 @@
**[Website](https://rea.tools/) · [Guides](https://rea.tools/guides/) · [Showcases](https://rea.tools/showcase/)**
[Quick start](#quick-start) · [How REA works](#how-rea-works) · [What you can analyze](#what-you-can-analyze) · [Showcases](#showcases) · [FAQ](#faq) · [Documentation](#documentation)
[Quick start](#quick-start) · [How REA works](#how-rea-works) · [What you can analyze](#what-you-can-analyze) · [Showcases](#showcases) · [Build RL environments](#build-rl-environments) · [FAQ](#faq) · [Documentation](#documentation)
<code>npx rea-agents setup</code>
@@ -62,7 +62,7 @@ See a feature in an app that you want in your own product? Ask your agent to inv
REA connects your agent to tools for inspecting native binaries, JavaScript and Electron apps, .NET assemblies, and websites. You can also use the same tools from your terminal. Analysis runs locally, and results include the evidence and limitations behind each conclusion.
Setup registers REA with your agent and installs matching workflow instructions. Native analysis can use an existing Hopper, Ghidra, or IDA installation; setup can optionally install Hopper with approval. Static JavaScript analysis needs no native analysis engine.
Setup registers REA with your agent and installs matching workflow instructions. Native analysis can use an existing Hopper, Ghidra, IDA or Kuna installation; setup can optionally install Hopper with approval. Static JavaScript analysis needs no native analysis engine.
> **[Visit the REA website](https://rea.tools/)** for setup instructions, illustrated guides, and real case studies.
@@ -83,12 +83,15 @@ npx rea-agents setup
Choose your agents, review the proposed changes, and approve them. Setup adds
REA's MCP server and matching workflow instructions, with backups of existing
configuration. Restart your agent afterward.
configuration. Restart your agent afterward. Setup records the selected runtime and REA
entry script directly. If acquired through a package runner, keep its cache entry
available. Run package acquisition from a trusted directory outside the target
project. Installation and recovery details are in the setup guide below.
Setup supports Claude Code, Codex, Cursor, Gemini CLI, Grok Build and
[other agents](docs/installation.md#supported-agents). See
[installation and setup](docs/installation.md) for provider configuration and
manual MCP registration.
manual MCP registration and Claude Code/Codex plugin installation.
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
@@ -96,6 +99,12 @@ 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.
Complete output schemas are advertised by default. If your client caps the
complete `tools/list` frame, set `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` to
bound each advertised output schema, or `off` to omit output schemas entirely.
Both settings keep canonical server-side validation and complete structured
results. See "Output schemas" in the MCP contracts guide.
### Ask your agent
```text
@@ -183,7 +192,7 @@ Additional tools and host support depend on the target:
| Target | What REA returns | Requirements and guide |
| ----------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| Desktop installations | Runtime candidates, supporting files, component markers and next probes | Built-in bounded directory/header inspection; [desktop applications](docs/desktop-applications.md) |
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](docs/native-investigation.md) |
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra, IDA or Kuna; [native analysis](docs/native-investigation.md) |
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
| Go binaries | Embedded compiler version, modules, replacements and build settings | Built-in static ELF/PE/thin Mach-O inspection; no Go installation required |
| GPU code objects | CUDA/HIP targets, selected kernel parameters and resources, retained PTX text | Built-in static ELF/PE/fatbin/CUBIN/PTX inspection; [GPU code objects](docs/gpu-code-objects.md) |
@@ -276,11 +285,53 @@ historical compiler output.
[Read the case study](https://rea.tools/showcase/th04/) ·
[Reconstruction repository](https://github.com/N0zoM1z0/th04)
### Build RL environments with REA
Record a web app session, turn its API into tools, and export an environment an AI agent can use. Run it with AgentEnv, then add tasks and reward checks for RL training or evaluation.
[Read the guide](https://rea.tools/guides/rl-environments/) ·
[Watch the video](https://x.com/reatools/status/2112574822584918075?s=20)
If you've used REA on something interesting, we'd love to see it. Share your
case in an [issue](https://github.com/morluto/rea/issues) or a
[pull request](https://github.com/morluto/rea/pulls), including the target,
your question, how REA helped, and what you found.
## Build RL environments
Give an AI agent a local environment to practice tasks such as finding an issue or creating a folder, without running the original app. Use it for reinforcement learning (RL) or to test how well an agent completes tasks.
REA turns recorded API requests and responses into tools the agent can call. The environment uses the recorded data and supports changes only when the recording confirms their effects.
With REA set up in your agent, replace the example URL and folder tasks below with your own:
```text
Use REA to build an RL environment from my test web app at
http://127.0.0.1:3000.
Cover listing, creating, renaming, and deleting folders. You may create and
remove test folders. Leave existing data unchanged.
Save it in a folder named my-env. Check which operations work and tell me
how to run it.
```
<details>
<summary>Use the command line instead</summary>
Use these commands if you already have a file containing the app’s recorded browser requests and responses. Running the result also requires AgentEnv and Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA exports a runnable environment with a basic test to check that it starts and responds. Use it with your RL framework to define task goals, add reward checks, and run training.
[Build an environment](https://rea.tools/guides/rl-environments/) ·
[Environment reference](docs/agent-environments.md) ·
[Watch the demo on X](https://x.com/reatools/status/2112574822584918075?s=20)
## FAQ
<details>
@@ -293,11 +344,13 @@ Any agent that supports local MCP servers. Setup configures the
</details>
<details>
<summary><strong>Do I need Hopper, Ghidra or IDA?</strong></summary>
<summary><strong>Do I need a native analysis engine?</strong></summary>
Deep native analysis uses one of them. Static JavaScript and .NET inspection
work without a native analysis engine. Setup can install Hopper after approval;
Ghidra and IDA use your existing installations. See [provider setup](docs/installation.md#hopper).
Deep native analysis uses Hopper, Ghidra, IDA or Kuna, depending on the target
and operation. Static JavaScript and .NET inspection work without a native
analysis engine. Setup can install Hopper after approval; Ghidra, IDA and Kuna
use your existing installations. See [provider setup](docs/installation.md#hopper)
for the options and their supported targets.
</details>
@@ -377,7 +430,7 @@ Report vulnerabilities through [SECURITY.md](SECURITY.md).
## Star history
🎉 **300,000 GitHub stars — thank you!**
🎉 **400,000 GitHub stars — thank you!**
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
+1 -1
View File
@@ -10,7 +10,7 @@ Do not disclose vulnerabilities, proof-of-concept exploits, credentials,
private binaries, Hopper documents, or private Ghidra projects in a public
issue.
Use **Report a vulnerability** in the repository's **Security** tab to submit the report privately. Do not open a public issue to request a private contact channel.
Use **Report a vulnerability** in the repository's **Security** tab as the preferred way to submit the report privately. If GitHub private reporting is unavailable to you, email [[email protected]](mailto:[email protected]). Do not open a public issue to request a private contact channel.
Include the affected REA version, operating system/distribution, selected
provider and version, impact, reproduction conditions, and any suggested
+10
View File
@@ -0,0 +1,10 @@
# Plugin icon
`rea-plugin.png` is a square adaptation of the left panel of REA's GitHub
social preview, retrieved on 2026-10-28:
https://repository-images.githubusercontent.com/1209966933/1a3fef9a-be4b-41f4-8830-a94c0e8288cc
The image was adapted with imagegen, preserving the cyan REA lettering,
pixel typography, orange rule, and taglines. Both plugin manifests reference
this shared asset; only the PNG is included in the npm package.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

+244 -8
View File
@@ -1,5 +1,9 @@
import com.atxx.jhmcp.*;
import com.google.gson.*;
import com.android.tools.smali.dexlib2.Opcodes;
import com.android.tools.smali.dexlib2.dexbacked.DexBackedDexFile;
import com.android.tools.smali.dexlib2.dexbacked.DexBackedClassDef;
import com.android.tools.smali.dexlib2.dexbacked.DexBackedMethod;
import io.modelcontextprotocol.kotlin.sdk.server.*;
import io.modelcontextprotocol.kotlin.sdk.types.*;
import jadx.api.*;
@@ -9,14 +13,22 @@ import jadx.api.plugins.input.data.ICodeReader;
import jadx.api.plugins.input.data.IMethodRef;
import jadx.api.plugins.input.insns.InsnIndexType;
import jadx.api.plugins.input.insns.Opcode;
import jadx.core.codegen.TypeGen;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.nodes.*;
import jadx.core.xmlgen.BinaryXMLParser;
import java.io.PrintStream;
import java.io.StringReader;
import java.io.InputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import kotlin.Unit;
import kotlin.ResultKt;
import kotlin.coroutines.Continuation;
@@ -178,6 +190,205 @@ class ReaJadxBridge {
manifestSnapshot = null;
}
// One bounded DEX at a time, beside the already admitted analysis JVM. The
// response allowance accounts for worst-case JSON escaping before retention.
private static final int NATIVE_DEX_BYTES = 64 * 1024 * 1024;
private static final long NATIVE_TOTAL_DEX_BYTES = 256L * 1024 * 1024;
// This JSON is escaped again inside an 8 MiB MCP frame.
private static final long NATIVE_JSON_BYTES = 4L * 1024 * 1024;
/** The bundled decoder allocates its declared UTF-16 length before validating bytes. */
private static final class NativeDex extends DexBackedDexFile {
private OptionalIndexedSection<String> boundedStrings;
NativeDex(byte[] bytes) { super(Opcodes.getDefault(), bytes); }
@Override public OptionalIndexedSection<String> getStringSection() {
if (boundedStrings == null) {
var source = super.getStringSection();
boundedStrings = new OptionalIndexedSection<>() {
@Override public int size() { return source.size(); }
@Override public int getOffset(int index) { return source.getOffset(index); }
@Override public String getOptional(int index) { return index == -1 ? null : get(index); }
@Override public String get(int index) {
int offset = getBuffer().readSmallUint(source.getOffset(index));
int units = getDataBuffer().readerAt(offset).readSmallUleb128();
if (units > NATIVE_JSON_BYTES / 6
|| units > getDataBuffer().getBuf().length - offset)
throw new IllegalArgumentException("DEX string exceeds the native decoding allowance");
return source.get(index);
}
};
}
return boundedStrings;
}
}
private static void checkNativeInterrupted() {
if (Thread.currentThread().isInterrupted())
throw new java.util.concurrent.CancellationException("Native declaration inventory interrupted");
}
private static final class NativeInventory {
final List<Map<String, Object>> methods = new ArrayList<>();
final List<String> unknowns = new ArrayList<>();
long retainedBytes = 1024;
int dexEntries;
int examinedDexEntries;
int examinedClasses;
int examinedMethods;
boolean partial;
boolean diagnosticLimit;
void unknown(String reason) {
partial = true;
long bytes = 64L + reason.length() * 6L;
if (unknowns.size() < 16 && retainedBytes + bytes <= NATIVE_JSON_BYTES - 4096) {
unknowns.add(reason);
retainedBytes += bytes;
} else if (!diagnosticLimit) {
diagnosticLimit = true;
unknowns.add("Additional native-inventory limitations exceed the retained diagnostic allowance.");
}
}
boolean retain(Map<String, Object> method, long bytes) {
if (retainedBytes + bytes > NATIVE_JSON_BYTES - 4096) {
unknown("Native declarations exceed the 4 MiB retained JSON allowance; remaining declarations are unknown.");
return false;
}
retainedBytes += bytes;
methods.add(method);
return true;
}
Map<String, Object> result() {
return Map.of("scope", "apk-root-dex-declarations", "methods", List.copyOf(methods),
"coverage", Map.of("status", partial ? "partial" : "complete",
"dex_entries", dexEntries, "examined_dex_entries", examinedDexEntries,
"examined_classes", examinedClasses, "examined_methods", examinedMethods),
"unknowns", List.copyOf(unknowns));
}
}
/** Match Android's standard root multidex carriers, without a basename guess. */
private static boolean nativeDexEntry(String name) {
return name.equals("classes.dex") || name.matches("classes[0-9]+\\.dex");
}
private static byte[] readNativeDex(ZipFile archive, ZipEntry entry) throws IOException {
long size = entry.getSize();
if (size < 0 || size > NATIVE_DEX_BYTES)
throw new IllegalArgumentException("DEX exceeds the 64 MiB single-member read allowance");
byte[] bytes = new byte[(int) size];
CRC32 crc = new CRC32();
try (InputStream input = archive.getInputStream(entry)) {
int offset = 0;
while (offset < bytes.length) {
checkNativeInterrupted();
int read = input.read(bytes, offset, Math.min(65536, bytes.length - offset));
if (read < 0) throw new IOException("DEX is shorter than its ZIP declaration");
if (read == 0) continue;
crc.update(bytes, offset, read);
offset += read;
}
if (input.read() != -1) throw new IOException("DEX exceeds its ZIP declaration");
}
if (entry.getCrc() < 0 || entry.getCrc() != crc.getValue())
throw new IOException("DEX does not match its ZIP CRC32 declaration");
return bytes;
}
/** Raw DEX ownership precedes JADX's duplicate-class selection and aliases. */
static Map<String, Object> nativeDeclarations(Path apk) {
NativeInventory inventory = new NativeInventory();
try (ZipFile archive = new ZipFile(apk.toFile())) {
Map<String, Integer> names = new HashMap<>();
var directory = archive.entries();
while (directory.hasMoreElements()) {
checkNativeInterrupted();
ZipEntry entry = directory.nextElement();
if (!entry.isDirectory() && nativeDexEntry(entry.getName())) {
inventory.dexEntries++;
names.merge(entry.getName(), 1, Integer::sum);
}
}
long totalBytes = 0;
int entryIndex = -1;
directory = archive.entries();
while (directory.hasMoreElements()) {
checkNativeInterrupted();
ZipEntry entry = directory.nextElement();
entryIndex++;
String path = entry.getName();
if (entry.isDirectory() || !nativeDexEntry(path)) continue;
if (names.get(path) != 1) {
inventory.unknown("Duplicate root DEX entry name cannot be selected uniquely by the ZIP reader: " + path);
continue;
}
if (entry.getSize() < 0 || entry.getSize() > NATIVE_DEX_BYTES
|| entry.getSize() > NATIVE_TOTAL_DEX_BYTES - totalBytes) {
inventory.unknown("Root DEX member exceeds the 64 MiB member or 256 MiB total read allowance: " + path);
continue;
}
totalBytes += entry.getSize();
try {
DexBackedDexFile dex = new NativeDex(readNativeDex(archive, entry));
var classes = dex.getClassSection();
for (int classIndex = 0; classIndex < classes.size(); classIndex++) {
checkNativeInterrupted();
DexBackedClassDef cls = classes.get(classIndex);
String type = cls.getType();
if (!type.startsWith("L") || !type.endsWith(";"))
throw new IllegalArgumentException("Class definition has no reference type");
String className = type.substring(1, type.length() - 1).replace('/', '.');
// Passing false retains duplicate encoded method references too.
for (Iterable<? extends DexBackedMethod> group : List.of(
cls.getDirectMethods(false), cls.getVirtualMethods(false))) {
for (DexBackedMethod method : group) {
checkNativeInterrupted();
inventory.examinedMethods++;
if ((method.getAccessFlags() & 0x100) == 0) continue;
String methodName = method.getName();
String returnType = method.getReturnType();
long characters = 2L + returnType.length();
for (CharSequence parameter : method.getParameterTypes()) {
characters += parameter.length();
if (characters * 6L > NATIVE_JSON_BYTES) break;
}
long bytes = 512L + 6L * (className.length() + methodName.length()
+ path.length() + characters);
if (inventory.retainedBytes + bytes > NATIVE_JSON_BYTES - 4096) {
inventory.unknown("Native declarations exceed the 4 MiB retained JSON allowance; remaining declarations are unknown.");
return inventory.result();
}
StringBuilder descriptor = new StringBuilder((int) characters).append('(');
for (CharSequence parameter : method.getParameterTypes()) descriptor.append(parameter);
descriptor.append(')').append(returnType);
Map<String, Object> row = Map.of("source_index", inventory.methods.size(),
"class_name", className, "method_name", methodName, "descriptor", descriptor.toString(),
"dex_entry", path, "dex_entry_index", entryIndex, "class_index", classIndex,
"method_index", method.getMethodIndex());
if (!inventory.retain(row, bytes)) return inventory.result();
}
}
inventory.examinedClasses++;
}
inventory.examinedDexEntries++;
} catch (IOException | RuntimeException failure) {
if (failure instanceof java.util.concurrent.CancellationException) throw (RuntimeException) failure;
inventory.unknown("Root DEX native declarations could not be fully read from " + path + ": "
+ failure.getClass().getSimpleName()
+ (failure.getMessage() == null ? "" : " (" + failure.getMessage() + ")"));
}
}
} catch (IOException failure) {
// A failed archive close must fail the operation so the provider retires
// its owned JVM; do not cache a result with lost file-resource ownership.
throw new IllegalArgumentException("APK ZIP native declaration inventory could not finish its reader", failure);
}
return inventory.result();
}
/** Original archive identity, never a deobfuscated basename or name suffix. */
private ManifestSnapshot manifest(JadxSession current) {
if (manifestSession != current || manifestSnapshot == null) {
@@ -190,10 +401,7 @@ class ReaJadxBridge {
selected = resource;
}
if (selected == null) throw new IllegalArgumentException("Root AndroidManifest.xml not found");
var content = selected.loadContent();
if (content == null || content.getDataType() != jadx.core.xmlgen.ResContainer.DataType.TEXT)
throw new IllegalArgumentException("Root AndroidManifest.xml did not decode as text");
String xml = content.getText().getCodeStr();
String xml = manifestText(selected);
ManifestSnapshot snapshot = new ManifestSnapshot(xml, manifestSummary(xml));
manifestSnapshot = snapshot;
manifestSession = current;
@@ -201,6 +409,23 @@ class ReaJadxBridge {
return manifestSnapshot;
}
/** Decode with resource names but without JADX's class alias substitution. */
static String manifestText(ResourceFile resource) {
var decompiler = resource.getDecompiler();
// BinaryXMLParser resolves android:name against its root's class identities
// and replaces raw '$' and relative names with Java-style aliases. A fresh
// root owns no classes, while its resource-name table preserves reference
// rendering from the loaded target.
RootNode root = new RootNode(decompiler.getArgs());
root.getConstValues().setResourcesNames(decompiler.getRoot().getConstValues().getResourcesNames());
try {
return ResourcesLoader.decodeStream(resource,
(size, input) -> new BinaryXMLParser(root).parse(input).getCodeStr());
} catch (jadx.core.utils.exceptions.JadxException failure) {
throw new IllegalArgumentException("Root AndroidManifest.xml did not decode as text", failure);
}
}
/** One parsed XML owner supplies namespace-aware values alongside the exact decoded text. */
static Map<String, Object> manifestSummary(String xml) {
Element root;
@@ -270,7 +495,7 @@ class ReaJadxBridge {
.map(Object::toString).collect(Collectors.joining(", "))
+ "): " + method.getReturnType().toString();
return new MethodSnapshot(name, rawName, shortId, List.copyOf(bodyAbsenceMarkers), Map.of(
"name", name, "signature", signature,
"name", name, "raw_name", rawName, "signature", signature,
"dex_descriptor", descriptor,
"is_constructor", method.isConstructor(), "def_pos", 0));
}).toList();
@@ -280,8 +505,11 @@ class ReaJadxBridge {
List<Map<String, Object>> valuedFields = new ArrayList<>();
boolean anyValue = false;
for (FieldNode field : orderedFields) {
// Raw DEX identity for mapping lookups; the display type can carry generics.
Map<String, Object> entry = Map.of("name", field.getAlias(),
"type", field.getType().toString(), "def_pos", 0);
"raw_name", field.getFieldInfo().getName(),
"type", field.getType().toString(),
"dex_type", TypeGen.signature(field.getFieldInfo().getType()), "def_pos", 0);
fields.add(entry);
Map<String, Object> value = dexStaticValue(field);
if (value == null) valuedFields.add(entry);
@@ -293,10 +521,11 @@ class ReaJadxBridge {
}
}
List<String> inner = node.getInnerClasses().stream().map(ClassNode::getFullName).toList();
List<String> innerRaw = node.getInnerClasses().stream().map(ClassNode::getRawName).toList();
Map<String, Object> summary = Map.of(
"full_name", cls.getFullName(), "raw_name", cls.getRawName(), "name", cls.getName(),
"method_count", methods.size(), "field_count", fields.size(),
"inner_class_count", inner.size(), "inner_classes", inner,
"inner_class_count", inner.size(), "inner_classes", inner, "inner_class_raw_names", innerRaw,
"methods", methods.stream().map(MethodSnapshot::summary).toList(), "fields", List.copyOf(fields));
// DEX static values are opt-in, so method and reference lookups keep the member-only reply.
Map<String, Object> summaryWithValues = summary;
@@ -470,6 +699,8 @@ class ReaJadxBridge {
"available_processors", Runtime.getRuntime().availableProcessors(),
"java_version", System.getProperty("java.version"),
"metadata_scope", "parsed_members"));
if (name.equals("rea_native_declarations"))
return json(nativeDeclarations(Path.of(string(args, "path"))));
JadxSession current = session();
if (name.equals("get_app_info")) return json(manifest(current).summary());
if (name.equals("get_android_manifest"))
@@ -581,7 +812,7 @@ class ReaJadxBridge {
SessionHolder holder = new SessionHolder(defaults);
ServerCapabilities capabilities = new ServerCapabilities(
new ServerCapabilities.Tools(null), null, null, null, null, null, null, Map.of());
Server server = new Server(new Implementation("rea-jadx-bridge", "7", null, null, null),
Server server = new Server(new Implementation("rea-jadx-bridge", "9", null, null, null),
new ServerOptions(capabilities), "", ignored -> Unit.INSTANCE);
SessionToolsKt.registerSessionTools(server, holder);
ClassToolsKt.registerClassTools(server, holder);
@@ -601,6 +832,11 @@ class ReaJadxBridge {
new ToolSchema(null, new kotlinx.serialization.json.JsonObject(Map.of()), List.of(), null),
"Observed worker JVM and metadata scope", null, null, null, null, null, null);
server.addTool(diagnostics, (connection, request, continuation) -> bridge.handle("rea_jvm_status", request.getArguments()));
registerBridgeTool(server, bridge, "rea_native_declarations",
new ToolSchema(null, new kotlinx.serialization.json.JsonObject(Map.of("path",
new kotlinx.serialization.json.JsonObject(Map.of("type",
kotlinx.serialization.json.JsonElementKt.JsonPrimitive("string"))))), List.of("path"), null),
"Original ACC_NATIVE declarations from the admitted APK's standard root DEX members, without loading or decompiling the APK.");
for (String name : List.of("get_app_info", "get_android_manifest")) {
String description = name.equals("get_app_info")
? "Namespace-aware summary of the exact root AndroidManifest.xml resource."
+53 -35
View File
@@ -434,6 +434,8 @@ public final class ReaGhidraBridge extends HeadlessScript {
"Ghidra auto-analysis did not complete for this Program"
);
}
if (descriptor.existingProject && isMutatingOperation(request.method))
throw new RequestFailure("method_unavailable", "Existing Ghidra project sessions are read-only");
return switch (request.method) {
case "read_binary_inventory_summary" -> binaryInventorySummary(request.params);
case "inspect_native_load_image" -> inspectNativeLoadImage(request.params);
@@ -486,6 +488,10 @@ public final class ReaGhidraBridge extends HeadlessScript {
};
}
private static boolean isMutatingOperation(String method) {
return method.equals("annotate_native_function") || method.equals("set_address_name") || method.equals("set_addresses_names");
}
private JsonObject sessionInfo(SessionDescriptor descriptor) throws Exception {
boolean timedOut = analysisTimeoutOccurred();
JsonObject provider = new JsonObject();
@@ -511,14 +517,16 @@ public final class ReaGhidraBridge extends HeadlessScript {
result.addProperty("run_id", descriptor.runId);
result.addProperty("profile_digest", descriptor.profileDigest);
result.add("provider", provider);
boolean readOnly = !descriptor.transport.equals("unix-socket");
boolean readOnly = descriptor.existingProject || !descriptor.transport.equals("unix-socket");
result.addProperty("read_only", readOnly);
result.addProperty("analysis_complete", !timedOut);
if (descriptor.existingProject) {
result.add("analysis_complete", JsonNull.INSTANCE);
result.addProperty("existing_project", true);
} else result.addProperty("analysis_complete", !timedOut);
result.addProperty("analysis_timed_out", timedOut);
result.add("capabilities", GSON.toJsonTree(
java.util.Arrays.stream(CAPABILITIES)
.filter(value -> !readOnly || !(value.equals("annotate_native_function")
|| value.equals("set_address_name") || value.equals("set_addresses_names")))
.filter(value -> !readOnly || !isMutatingOperation(value))
.toArray(String[]::new)
));
result.add("target", target);
@@ -1305,7 +1313,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
flow.addProperty("computed", false);
if (instruction == null) {
result.addProperty("status", !currentProgram.getMemory().contains(address) ? "outside-memory" : currentProgram.getListing().getInstructionContaining(address) != null
? "not-instruction-boundary" : currentProgram.getListing().getDefinedDataContaining(address) != null ? "data" : "undecodable");
? "not-instruction-boundary" : currentProgram.getListing().getDefinedDataContaining(address) != null ? "data" : "not-in-listing");
for (String key : List.of("bytes", "length", "mnemonic", "raw_disassembly")) result.add(key, JsonNull.INSTANCE);
} else {
result.addProperty("status", "decoded");
@@ -1377,6 +1385,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
result.add("incoming_references", incomingReferences);
}
List<String> limitations = new ArrayList<>(List.of("Operand components are Ghidra Listing decoder tokens; effective memory base/index/displacement roles and per-instruction context mode are unavailable. The mode field is the program language variant."));
if (result.get("status").getAsString().equals("not-in-listing")) limitations.add("No listed instruction or defined data covers this in-memory address. REA did not attempt a decode; the memory may be uninitialized or contain valid instructions.");
if (flow.get("kind").getAsString().equals("terminal")) limitations.add("No RETURN operation was observed in the provider's instruction p-code; terminal classification remains generic.");
result.add("limitations", GSON.toJsonTree(limitations));
return result;
@@ -2091,10 +2100,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
requireKeys(params, Set.of("document", "address"));
requireDocument(params);
Address query = requireAddress(params, "address");
Function function = currentProgram.getFunctionManager().getFunctionAt(query);
if (function == null && query.isMemoryAddress()) {
function = currentProgram.getFunctionManager().getFunctionContaining(query);
}
Function function = functionAtOrContaining(query);
JsonObject result = new JsonObject();
result.addProperty("query_address", canonicalAddress(query));
if (function != null) {
@@ -2110,10 +2116,9 @@ public final class ReaGhidraBridge extends HeadlessScript {
}
private JsonArray search(JsonObject params, boolean procedureSearch) throws Exception {
requireKeys(
params,
Set.of("pattern", "mode", "case_sensitive", "document")
);
Set<String> keys = new HashSet<>(Set.of("pattern", "mode", "case_sensitive", "document"));
if (params.has("literal_ascii_candidate")) keys.add("literal_ascii_candidate");
requireKeys(params, keys);
requireDocument(params);
String expression = requireString(params, "pattern");
String mode = requireString(params, "mode");
@@ -2124,9 +2129,18 @@ public final class ReaGhidraBridge extends HeadlessScript {
List<InventoryItem> inventory = procedureSearch
? procedures().stream().map(FunctionEntry::item).toList()
: strings();
ValueMatcher matcher = mode.equals("literal")
? literalMatcher(expression, caseSensitive)
: regexMatcher(expression, caseSensitive);
ValueMatcher matcher;
if (mode.equals("literal") && !caseSensitive) {
if (!params.has("literal_ascii_candidate"))
throw new RequestFailure("invalid_request", "Insensitive literal search requires an ASCII candidate");
matcher = literalCandidateMatcher(optionalString(params, "literal_ascii_candidate"));
} else {
if (params.has("literal_ascii_candidate"))
throw new RequestFailure("invalid_request", "ASCII candidate applies only to insensitive literals");
matcher = mode.equals("literal")
? literalMatcher(expression)
: regexMatcher(expression, caseSensitive);
}
JsonArray items = new JsonArray();
for (InventoryItem item : inventory) {
monitor.checkCancelled();
@@ -2283,6 +2297,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
return function;
}
/** Exact entries include externals; containment applies only to memory addresses. */
private Function functionAtOrContaining(Address address) {
Function function = currentProgram.getFunctionManager().getFunctionAt(address);
return function == null && address.isMemoryAddress()
@@ -2987,7 +3002,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
if (!currentProgram.getLanguageID().getIdAsString().startsWith("AARCH64:")) {
return null;
}
Function function = containingFunction(jumpTable.getSwitchAddress());
Function function = functionAtOrContaining(jumpTable.getSwitchAddress());
if (function == null) return null;
List<Instruction> instructions = new ArrayList<>();
@@ -3487,7 +3502,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
private boolean unrepresentedCaller(Reference reference, Set<Function> callers) {
if (!reference.getReferenceType().isCall()) return false;
Function caller = containingFunction(reference.getFromAddress());
Function caller = functionAtOrContaining(reference.getFromAddress());
return caller == null || !callers.contains(caller);
}
@@ -3634,7 +3649,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
void observe(Reference reference) {
if (!reference.getReferenceType().isCall()) return;
// Reference identity follows the same containing-function owner as referenceEdge.
Function target = containingFunction(reference.getToAddress());
Function target = functionAtOrContaining(reference.getToAddress());
if (returnedCallees != null && (target == null || !returnedCallees.contains(target)))
unrepresented++;
if (target == null) unresolved(reference.getFromAddress(),
@@ -3804,8 +3819,8 @@ public final class ReaGhidraBridge extends HeadlessScript {
JsonObject result = new JsonObject();
result.addProperty("source_address", canonicalAddress(reference.getFromAddress()));
result.addProperty("target_address", canonicalAddress(reference.getToAddress()));
Function source = containingFunction(reference.getFromAddress());
Function target = containingFunction(reference.getToAddress());
Function source = functionAtOrContaining(reference.getFromAddress());
Function target = functionAtOrContaining(reference.getToAddress());
result.add(
"source_procedure",
source == null ? JsonNull.INSTANCE : procedureIdentity(source)
@@ -3840,14 +3855,6 @@ public final class ReaGhidraBridge extends HeadlessScript {
return result;
}
private Function containingFunction(Address address) {
Function result = currentProgram.getFunctionManager().getFunctionAt(address);
if (result == null && address.isMemoryAddress()) {
result = currentProgram.getFunctionManager().getFunctionContaining(address);
}
return result;
}
private static String procedureName(Function function) {
Symbol symbol = function.getSymbol();
return symbol == null ? function.getName() : symbol.getName(true);
@@ -4699,11 +4706,18 @@ public final class ReaGhidraBridge extends HeadlessScript {
return source.name().toLowerCase(Locale.ROOT);
}
private static ValueMatcher literalMatcher(String pattern, boolean caseSensitive) {
String needle = caseSensitive ? pattern : pattern.toLowerCase(Locale.ROOT);
private static ValueMatcher literalMatcher(String pattern) {
return value -> value.contains(pattern);
}
// REA's host owns Unicode simple folding. Keep all non-ASCII source values
// for its final predicate, and filter ASCII-only values without Java regexes.
private static ValueMatcher literalCandidateMatcher(String asciiPattern) {
if (asciiPattern != null && asciiPattern.chars().anyMatch(character -> character > 127))
throw new RequestFailure("invalid_request", "ASCII candidate contains a non-ASCII character");
return value -> {
String candidate = caseSensitive ? value : value.toLowerCase(Locale.ROOT);
return candidate.contains(needle);
if (value.chars().anyMatch(character -> character > 127)) return true;
return asciiPattern != null && value.toLowerCase(Locale.ROOT).contains(asciiPattern);
};
}
@@ -4752,6 +4766,8 @@ public final class ReaGhidraBridge extends HeadlessScript {
keys.add("analysis_extensions");
if (parsed.isJsonObject() && parsed.getAsJsonObject().has("decompile_timeout_seconds"))
keys.add("decompile_timeout_seconds");
if (parsed.isJsonObject() && parsed.getAsJsonObject().has("existing_project"))
keys.add("existing_project");
JsonObject object = requireObject(parsed, keys);
int decompileTimeout = 0;
if (object.has("decompile_timeout_seconds")) {
@@ -4768,7 +4784,8 @@ public final class ReaGhidraBridge extends HeadlessScript {
requireString(object, "provider_version"),
requireString(object, "profile_digest"),
object.has("analysis_extensions") ? object.getAsJsonArray("analysis_extensions") : new JsonArray(),
decompileTimeout
decompileTimeout,
object.has("existing_project") && requireBoolean(object, "existing_project")
);
}
@@ -4985,7 +5002,8 @@ public final class ReaGhidraBridge extends HeadlessScript {
String providerVersion,
String profileDigest,
JsonArray analysisExtensions,
int decompileTimeoutSeconds
int decompileTimeoutSeconds,
boolean existingProject
) {}
private record Request(int id, String method, JsonObject params, Integer decompileTimeoutSeconds) {}
+161 -5
View File
@@ -22,6 +22,9 @@ HOPPER_SYMBOL_NAME_UTF16_UNITS = 1024
# that does not fit is null, not an older descriptor path.
# 536870887 is Node's 536870888-character string ceiling minus the framing LF.
# The ceiling is the encoded payload; JSON expansion is measured before it.
# Encoded JSON allowance, in bytes, shared by one instruction list, one
# native-caller list, and one caller-scan page. This release has no runtime override.
CALLER_SCAN_ALLOWANCE_BYTES = 512 * 1024
_BRIDGE_MAX_REQUEST_BYTES_SETTING = "REA_BRIDGE_MAX_REQUEST_BYTES"
DEFAULT_BRIDGE_MAX_REQUEST_BYTES = 16 * 1024 * 1024
MINIMUM_BRIDGE_MAX_REQUEST_BYTES = 7464
@@ -232,6 +235,9 @@ EXHAUSTIVE_ANALYSIS_METHODS = frozenset(
"procedure_assembly",
"procedure_callees",
"procedure_callers",
"rea_caller_scan_page",
"rea_caller_scan_target",
"rea_caller_base",
"procedure_info",
"procedure_pseudo_code",
"procedure_references",
@@ -485,19 +491,30 @@ def _instruction_addresses(procedure):
return result
def _native_calls(procedure, direction):
def _iter_native_calls(procedure, direction):
references = procedure.getAllCallees() if direction == "outgoing" else procedure.getAllCallers()
kinds = {0: "none", 1: "unknown", 2: "direct", 3: "objective_c"}
calls = {}
unresolved = []
for reference in references:
source, target, kind = reference.fromAddress(), reference.toAddress(), reference.type()
if source in BAD_ADDRESSES:
yield None, None, None
continue
if target in BAD_ADDRESSES:
unresolved.append({"address": _hex(source), "reason": "Native CallReference has no resolved target (type %s)" % kind})
yield source, None, {"address": _hex(source), "reason": "Native CallReference has no resolved target (type %s)" % kind}
continue
calls[(source, target)] = {"classification": kinds.get(kind, "unknown"), "provider_type": kind, "provenance": "hopper-public-python-api:CallReference"}
yield source, target, {"classification": kinds.get(kind, "unknown"), "provider_type": kind, "provenance": "hopper-public-python-api:CallReference"}
def _native_calls(procedure, direction):
calls = {}
unresolved = []
for source, target, detail in _iter_native_calls(procedure, direction):
if detail is None:
continue
if target is None:
unresolved.append(detail)
else:
calls[(source, target)] = detail
return calls, sorted(unresolved, key=lambda item: int(item["address"], 16))
@@ -547,6 +564,136 @@ def _procedure_map(document):
return result
def _caller_target_data(procedure):
addresses = []
seen = set()
size = 0
for block in procedure.basicBlockIterator():
for address in _block_instruction_addresses(procedure, block):
if address in seen:
continue
encoded = _hex(address)
size += len(encoded) + 4
if size > CALLER_SCAN_ALLOWANCE_BYTES:
return {"target": _procedure_identity(procedure), "instructions": addresses, "instructions_complete": False}
addresses.append(encoded)
seen.add(address)
return {"target": _procedure_identity(procedure), "instructions": addresses, "instructions_complete": True}
def _caller_scan_target(document, params):
return _caller_target_data(_procedure(document, params.get("procedure")))
def _caller_base(document, params):
procedure = _procedure(document, params.get("procedure"))
callers = []
size = 0
complete = True
for item in procedure.getAllCallerProcedures():
address = _hex(item.getEntryPoint())
size += len(address) + 4
if size > CALLER_SCAN_ALLOWANCE_BYTES:
complete = False
break
callers.append(address)
return {
**_caller_target_data(procedure),
"callers": sorted(callers, key=lambda value: int(value, 16)),
"callers_complete": complete,
}
def _caller_scan_page(document, params):
"""Observe forward relationships in one bounded, stateless bridge request."""
start = params.get("start")
if isinstance(start, bool) or not isinstance(start, int) or start < 0:
raise InvalidRequestError("Caller scan start must be a non-negative integer")
segments = document.getSegmentsList()
counts = [segment.getProcedureCount() for segment in segments]
total = sum(counts)
end = min(start + 64, total)
if start > total:
raise InvalidRequestError("Caller scan start exceeds the procedure inventory")
items = []
item_bytes = 0
page_limit = CALLER_SCAN_ALLOWANCE_BYTES
oversized = False
identities = {}
containing = {}
def identity(procedure):
entry = procedure.getEntryPoint()
if entry not in identities:
identities[entry] = _procedure_identity(procedure)
return identities[entry]
def owner(address):
if address not in containing:
procedure, _ = _containing_procedure(document, address)
containing[address] = identity(procedure) if procedure is not None else None
return containing[address]
segment_start = 0
for segment, count in zip(segments, counts):
begin, stop = max(start - segment_start, 0), min(end - segment_start, count)
segment_start += count
for index in range(begin, max(begin, stop)):
candidate = segment.getProcedureAtIndex(index)
item = {"caller": identity(candidate), "callees": [], "references": []}
size = len(json.dumps(item, ensure_ascii=True).encode("utf-8")) + 1
remaining = page_limit - item_bytes
too_large = size > remaining
if not too_large:
for callee in candidate.getAllCalleeProcedures():
address = _hex(callee.getEntryPoint())
size += len(address) + 4
if size > remaining:
too_large = True
break
item["callees"].append(address)
if not too_large:
callee_entries = set(item["callees"])
for source, destination, call in _iter_native_calls(candidate, "outgoing"):
# Account for every native record, even when its target cannot
# be associated with an observed procedure.
size += 32
if size > remaining:
too_large = True
break
if destination is None:
continue
source_procedure = item["caller"] if _hex(source) == item["caller"]["address"] else owner(source)
target_address = _hex(destination)
if target_address in callee_entries:
target_entry = target_address
else:
target_procedure = owner(destination)
if target_procedure is None:
continue
target_entry = target_procedure["address"]
edge = {
"source_address": _hex(source), "target_address": _hex(destination),
"source_procedure": "caller" if source_procedure is not None and source_procedure["address"] == item["caller"]["address"] else source_procedure,
"target_procedure": target_entry,
"call": call,
}
size += len(json.dumps(edge, ensure_ascii=True).encode("utf-8")) + 1
if size > remaining:
too_large = True
break
item["references"].append(edge)
if too_large:
oversized = not items
break
items.append(item)
item_bytes += size
else:
continue
break
return {"start": start, "next": start + len(items), "total": total, "items": items, "oversized": oversized}
def _string_record(segment, address, display):
"""Read one native typed object, retaining its shortened display separately."""
length = segment.getObjectLength(address)
@@ -887,6 +1034,15 @@ def _dispatch(method, params):
if method in EXHAUSTIVE_ANALYSIS_METHODS:
_api().require_analysis_complete(document, method)
if method == "rea_caller_scan_target":
return _caller_scan_target(document, params)
if method == "rea_caller_base":
return _caller_base(document, params)
if method == "rea_caller_scan_page":
return _caller_scan_page(document, params)
if method == "analyze_function":
return _analyze_function(document, params)
if method == "read_function_instructions":
+5 -1
View File
@@ -53,7 +53,11 @@ export default defineConfig({
text: "Web network captures",
link: "/web-network-captures",
},
{ text: "Agent environments", link: "/agent-environments" },
{
text: "Build RL environments",
link: "/agent-environments-quickstart",
},
{ text: "Environment reference", link: "/agent-environments" },
{ text: "Electron observation", link: "/electron-observation" },
{ text: "Electron fuses", link: "/electron-fuses" },
{ text: "Process capture", link: "/process-capture" },
+4
View File
@@ -103,6 +103,10 @@ existing analysis families directly, for example
| `start_adb_activity` | **mutates device** | Starts an intent (`am start -a` with optional URI, component, and up to 16 typed extras); preserves the activity manager's verdict |
| `stop_adb_app` | **mutates device** | Force-stops every process of a package, ending a dynamic-analysis run |
Screen capture validates the PNG signature, IHDR framing, dimensions, and IHDR
checksum before publishing. It does not validate encoding fields or decode and
validate image contents; that limitation is retained in Evidence.
When `push_adb_file` receives an existing directory, adb places the local file
inside it under the local basename; Evidence reports that effective file path
while retaining the caller's directory path in the input parameters. The
+204
View File
@@ -0,0 +1,204 @@
# Build RL environments with REA
REA turns a recorded web app session into a runnable environment for training
and testing AI agents. An agent can practice tasks such as finding an issue,
creating a folder, or editing a record without running the original app.
REA builds the tools the agent calls, the local data those tools use, and a
test that checks the environment starts and responds. It supports changes
when the recording confirms their effects. You can then use the environment
with your RL framework to set task goals, check rewards, and run training.
## Before you start
Install [REA and its agent integration](installation.md). To record an app,
you also need a running test instance and a Chrome-family browser. Choose an
instance where the agent is allowed to create, edit, and delete data. REA
records the app you provide; you start it and prepare its test data.
To run the exported environment, install the
[AgentEnv framework](https://github.com/scaleapi/agentenv-framework#install)
and start Docker. REA's [compatibility check](testing.md#exported-environment-bundles)
uses AgentEnv version `0.9.1334` with Python 3.12.
There are two ways to build an environment: ask your agent to record the app,
or start from a recording you already have.
## 1. Record and build with your agent
Give your agent the app URL, the operations you need, your browser's executable
path, and an output directory. For an app with folders, adapt this prompt:
```text
Use REA to build an AgentEnv environment from my test web app at
http://127.0.0.1:3000. Cover listing, creating, renaming, and deleting folders.
You may create and remove test folders. Leave the existing data unchanged.
Sign in as admin using the password in APP_PASSWORD. Use the browser at
/absolute/path/to/chromium. Save the environment to
/absolute/path/to/my-env, which does not exist yet.
Record the session, check which operations the environment supports, and
export it. Report any unsupported operations and what is missing.
```
Replace the URL, account, paths, and folder operations with your own. Set
`APP_PASSWORD` in the environment that starts REA's MCP server so REA can use
it without putting the password in the prompt.
Your agent inspects the app, records a session, checks the result, and exports
a folder containing the runnable environment. It reports which operations
work and which need more evidence. The app is used during recording; the
exported environment runs from the saved data.
After your agent exports the folder, skip to
[run the environment](#3-run-the-environment). The next section is an
alternative for an existing recording.
## 2. Or build from a saved recording
A HAR file records a browser's network requests and responses. Export one
with API response bodies from your browser's network panel, or use a
recording you already have. To include create, edit, and delete operations,
record those actions and the reads that show their results.
Build the environment into a new or empty directory:
```sh
rea environment-build ./session.har ./my-env --name my-env --json
```
You can also pass capture Evidence JSON saved by REA's
`capture-browser-scenario` or `inspect-web-network-capture` commands. Here,
Evidence means REA's saved recording with its source information. The build
accepts HAR files and those JSON recordings. It reads local data and writes
the environment folder without contacting the app.
Add `--dry-run` to review the build report without writing the folder. For an
unreleased REA checkout, use `--package-tarball` with its packed package so
the exported environment runs the same implementation.
The build report tells you what the environment supports:
| Report field | What to check |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `state` | Whether the environment can answer from local state or uses recorded-response replay. |
| `coverage.reads` | Which read operations use state and which replay recorded answers. |
| `coverage.writes` | Which create, edit, and delete operations are supported. Each withheld operation includes a reason and a recording hint. |
| `warnings` | Recorded content or local paths to review before sharing the folder. |
A successful build means the folder was created. Check the report to confirm
it supports the operations your tasks need. `coverage: null` means the build
could not prepare state for this environment and it will use replay.
## 3. Run the environment
Whether your agent exported the folder or you built it from a HAR, run it
with AgentEnv:
```sh
agent-env run ./my-env
```
Use the folder path your agent reported if it differs. The first run builds
the container image, so it needs access to the image and package sources.
REA includes a basic test, called the smoke task. It checks the expected tool
count and, when a suitable read tool exists, calls it and checks its response
status. Passing this test shows the environment starts and responds in the
tested setup. It does not yet score an agent on an application task.
The folder contains the recording, a tool manifest describing the available
operations, a Dockerfile, environment configuration, and the test. The
[export reference](agent-environments.md#export-a-bundle) describes each file.
## 4. Add tasks and reward checks
Start with one task the exported tools support. Give it a clear goal and a
checkable result. For example, if folder creation is supported, ask your
agent:
```text
Use this exported environment to add an AgentEnv task that asks an agent
to create a folder named Practice. Check the saved environment state to
confirm the folder exists with that name, and use that check to score the
result. Reset the environment before each run so attempts start with the
same data. Use the AgentEnv task and verifier formats.
```
This asks your agent to help build the task and its grading check around the
environment REA generated. A retrieval task might check an answer against a
recorded value. A task that changes data should check the resulting state.
When state is available, the environment supports reset, load, and read-back
operations for repeatable runs.
Use the [AgentEnv documentation](https://www.agentenvframework.com/docs) for
task configuration, agent connections, scoring, and execution. Connect the
resulting tasks to your chosen RL training workflow.
## Improve an operation that is missing
For REA to support a change, the recording needs to show what happened before
and after it. When recording against your test app:
1. Read the list and an existing item before making changes. Repeat the
initial reads to show which values change independently.
2. Create a test item, read it back, and read the list before the next change.
Repeat with a second item and different text.
3. Edit each test item, then read the item and list again. Leave more than a
second between creation and the first edit to show time-dependent changes.
4. Delete the test items, then read them back and read the list to confirm
their removal.
Also record filters, searches, sorting, and paging if your tasks need them.
The agent should check that every recording step completed before using it.
The [recording workflow](https://github.com/morluto/rea/blob/main/.agents/skills/reverse-engineer-anything/references/environments.md)
has the detailed browser instructions, including timeouts and handling IDs
assigned by the app.
Use the report's hints to decide what to record next:
| Reason | Next step |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `unconfirmed` | Read the item and its list after the change. |
| `no-state-target` | Check the path template and recorded views; record missing reads. The route form may not be supported as a mutation target. |
| `no-observation` | Read back a created item. For an edit or delete, also read it before changing it. |
| `contradicted` or `side-effect` | Inspect the reported disagreement. The operation may need behavior REA cannot model yet. |
See the [full reason table](agent-environments.md#build-a-bundle-in-one-step)
for the other cases. Rebuild from the new recording and check the report
again. A new recording replaces the build input; combining separate recording
sessions is not supported.
## Compare with the original app
For a stronger check, record a separate sequence of calls against the real
app, starting from the same test data as the original recording. This is a
probe. Restore that starting data before each probe sequence, then compare
the saved probe recordings with the environment:
```sh
rea environment-compare ./my-env/envs/my-env/manifest.json \
--evidence ./my-env/envs/my-env/evidence.json \
--probe ./probe-create-edit-delete.json --probe ./probe-reads.json --json
```
Each probe file must be capture Evidence JSON from REA. The comparison runs
offline and reports differences in responses, unsupported calls, and missing
observations. It accounts for supported differences in IDs, times, and
modeled generated values. Agreement applies to the calls those probes check.
See the [comparison reference](agent-environments.md#measure-fidelity-against-the-application)
for the exact rules.
## Before sharing the environment
The exported folder includes retained response bodies and local source paths.
Standard authentication headers are excluded, but custom headers, query
values, and body tokens can remain. Review the content you plan to share.
Credential-name warnings point to values worth reviewing; they do not remove
those values or establish that the recording contains no credentials.
For direct MCP serving, replay behavior, state controls, and resource limits,
see the [environment reference](agent-environments.md). The
[implementation index](specs/agent-environments/README.md) links the contributing
PRs and their verification records.
+55 -22
View File
@@ -1,5 +1,12 @@
# Agent environments from recorded captures
For a first environment, start with the
[quickstart](agent-environments-quickstart.md): record an app or use a saved
session, build and run the environment, and add tasks and reward checks.
The [implementation index](specs/agent-environments/README.md) links
the contributing PRs and their verification records. This page is the detailed
command and behavior reference.
Use `rea environment-build` to turn one recorded capture into an agent
environment bundle in one offline step: a folder `agent-env run` builds and
runs, whose MCP server answers from what the capture observed. See
@@ -79,8 +86,9 @@ name it `.har`.
manifest's, unless the capture's origin is a loopback name or an IP literal:
the capture file then names it (`grafana.har` and `grafana.capture.json`
become `grafana`) and a `name-from-file` warning says so. A file name that
yields no portable label (kebab-case, at most 64 characters, not a Windows
device name) is refused; pass `--name`.
yields no portable label (kebab-case, at most 63 characters for a DNS service
label, not a Windows device name or a label interpreted as an IP address) is
refused; pass `--name`.
- `--package-tarball` works as for the export, and `--capture-timeout-ms`
as for `inspect-web-network-capture`.
- `--dry-run` runs every stage and prints the report with `status: "planned"`
@@ -166,7 +174,7 @@ what to record next; hints never change what is served:
| Reason | Hint |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `no-state-target` | The write's path names no collection or item the capture reads. Read the collection or item it changes. |
| `no-state-target` | The write could not be linked to a modelled target. Check the path template and recorded views; record missing reads. Some route forms may not be supported. |
| `no-call` | No recorded call of this tool was modelled, for example because every call failed. Record a successful call. |
| `body-unusable` | The retained request or response cannot be modelled. Record a successful call with a complete supported request and reproducible response. |
| `no-observation` | Nothing showed the entity or document this write changed. Read a created entity back by id right after the write; for an update or delete the state must already hold the entity, so read it before the write or record the create that made it. |
@@ -175,6 +183,7 @@ what to record next; hints never change what is served:
| `side-effect` | The write changed something besides its own entity, which the environment does not model. |
| `unconfirmed` | No later read showed the effect. Read the entity and its list after the write. |
| `incomplete-entities` | The write is confirmed, but the views that show its entity cannot render it in full. Read the written entity through every view that lists it. |
| `unknown-clock` | The learned rules generate timestamps, but the capture establishes no global served clock start. Record usable start times and completed durations for every request. |
The bundle ships `evidence.json`, the whole capture Evidence, response bodies
included. Inspection excludes the values of the standard authentication headers
@@ -196,7 +205,10 @@ attached and a transaction no record represents, and each transaction URL's
query once. Bodies larger than 4 MiB of UTF-8 text are not
scanned; `credential-scan-incomplete` counts them and lists up to 20 record or
event pointers, including base64 bodies whose decoded scan was cut. An empty name
warning does not establish that these bodies were checked. Names do not establish sensitivity,
warning does not establish that these bodies were checked. A browser scenario's
saved values (`save` and `save_response`) named like credentials but not marked
`secret: true` are recorded unredacted; `credential-named-saved-values` lists up
to 20 of them by parameter pointer. Names do not establish sensitivity,
so the build never refuses on them. Capture
Evidence also records the capture file's absolute path (`subject.local_path`,
@@ -394,7 +406,8 @@ 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. A query argument accepts
one string or an array of strings for repeated values; the array is matched
one string, a number or boolean sent as its JSON text, or an array of strings for
repeated values; the array is matched
against every occurrence in captured order. The raw recorded query remains the
replay evidence. The result reports
where the answer came from:
@@ -601,8 +614,9 @@ 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 accept an optional string or array of strings (for
repeated values in captured order); write methods accept an
query parameter names accept an optional string, number or boolean (a number or
boolean is sent as its JSON text) or array of strings (for repeated values in
captured order); 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
@@ -709,6 +723,8 @@ and `POST` tools the capture shows only reading (a lookup answering as a `GET`
did, an RPC tunnel naming read operations, a session renewal), stay served and
answer from their recordings with the reason `query-body`; they are not write
tools.
`HEAD`, `OPTIONS` and `TRACE` tools also replay their captured responses; their
state views report `method-replay` and coverage counts them as recorded reads.
A line establishes whole-collection membership only from the beginning:
`offset`, `start`, `_start` and `page` must be zero when present. Positive or
@@ -723,14 +739,14 @@ tools are not served, so no call claims a change it does not make; each one's
plan states why in its `reason`. A served write changes the live state, which
every MCP session and `data/get` then see:
| Effect | Call |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `create` | Adds an entity to the collection the path names, built from the observed entity with each ruled field taken from the call or generated, at the plan's `insert` position. A plan tied to its exemplar's collection writes only there. |
| `update` | Sets the sent members on the entity the path names, constants for members accepted only with their recorded value, and the clock, nested clock, increment, slug, stamp, derived, composed, reference, unique and renewed changes the plan models. |
| `update` (action) | A `POST`, `PUT` or `PATCH` to an item path plus an action segment (`/{type}/{id}/archive`) sets, on the entity before the segment, each scalar the recorded calls showed the action set (`set`), with any sent members; it is served only when a recorded call found those fields already set, so a toggle never is. |
| `delete` | Removes the entity the path names. |
| bulk `update` or `delete` | A `DELETE`, `PUT` or `PATCH` at a collection, or a `POST` to it plus `delete`, `remove` or `destroy`, applies its effect to every entity the body names, as recorded: an array of ids or of objects carrying the id field, at the root or as the body's one array member (`{"IDs": […], "Read": true}`). |
| `document` | Merges the body into the plan's document object, or replaces it for `PUT`. |
| Effect | Call |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `create` | Adds an entity to the collection the path names, built from the observed entity with each ruled field taken from the call or generated, at the plan's `insert` position. A plan tied to its exemplar's collection writes only there. |
| `update` | Sets the sent members on the entity the path names, constants for members accepted only with their recorded value, and the clock, nested clock, increment, slug, stamp, derived, composed, reference, unique and renewed changes the plan models. |
| `update` (action) | A `POST`, `PUT` or `PATCH` to an item path plus an action segment (`/{type}/{id}/archive`) sets, on the entity before the segment, each scalar the recorded calls showed the action set (`set`), or flips each boolean they showed it flipping both ways (`toggle`), with any sent members; it is served only when a recorded call found what it sets already set, or flipped back what it toggles. |
| `delete` | Removes the entity the path names. |
| bulk `update` or `delete` | A `DELETE`, `PUT` or `PATCH` at a collection, or a `POST` to it plus `delete`, `remove` or `destroy`, applies its effect to every entity the body names, as recorded: an array of ids or of objects carrying the id field, at the root or as the body's one array member (`{"IDs": […], "Read": true}`). |
| `document` | Merges the body into the plan's document object, or replaces it for `PUT`. |
An update's unsent changes follow the plan's rules. A `held-clock` is a clock
the client sends back as it read it and the application stamps anew (Ghost's
@@ -741,7 +757,9 @@ the entity already names under its `created…by` counterpart into a
`modified…by` or `updated…by` field. A `derived` field takes a value showing
the one sent member's text that the entity stores nowhere (a field Ghost
derives from `html`), only with that member's recorded value. An action's
`set` rule sets a scalar to the value the recorded calls left it at.
`set` rule sets a scalar to the value the recorded calls left it at, and its
`toggle` rule flips a boolean, refusing a call on an entity that holds none
there (Miniflux's `PUT /v1/entries/{id}/bookmark` stars and unstars).
Its answer has the status and content type of the plan's recorded response,
with the written entity or its identity rendered in, no body, or the recorded
@@ -756,11 +774,19 @@ sending a `derived` rule's member to an entity that does not hold the value the
recorded call found, a nested clock on an entity holding no such object, and a
rendered answer missing a field the recorded response carried, and an update or delete of an entity the state does not hold answers
the recorded 400, 404 or 410 of the tool or of an item view of the type, if
any. A refused call leaves the state unchanged. Values a write generates are
any. A served delete of a type whose item view has a `deleted_flag` (the
member, `deleted`, `isDeleted` or `is_deleted`, its reads set `true` on a
record the application soft-deleted, as EspoCRM does) keeps the entity until
`data/reset` or `data/add`, within the size `data/add` loads, so a read of it by
id answers its last fields with that flag `true`. A refused call leaves the
state unchanged. Values a write generates are
deterministic: the clock starts at `write_clock` and advances one second per
served write, sequences take one past both the largest held value and the
largest they generated, and UUIDs and tokens derive from the state Evidence
id, tool, field and write count, skipping held values. `data/reset` and
id, tool, field and write count, skipping held values. If `write_clock` is null,
plans needing `clock`, `held-clock`, or `nested-clock` retain their learned rules
but are withheld with `unknown-clock`; other confirmed plans can still be served.
`data/reset` and
`data/add` restart the clock, counter and sequences, so the same calls after a
reset give the same state. Answers carry `state: {"source": "state", "view":
"create" | "update" | "delete", …}` or `"document-write"`; a bulk answer adds
@@ -864,8 +890,9 @@ 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 integer from 2^53 below 1e21, such as `1e20`, in any spelling), is refused
rather than altered. Caller data preserves all own JSON members, including
`__proto__`; unknown members of the state document's structure are refused.
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
@@ -974,7 +1001,8 @@ 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);
(at most 63 characters for its DNS service label; Windows device names and
labels interpreted as IP addresses 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
@@ -992,7 +1020,12 @@ 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
framework maps for an MCP server env, and `MCP_ALLOWED_HOSTS` naming the loopback
addresses and the environment name, because the container binds outside loopback
and the server refuses to serve on such a bind without an operator-declared
allowlist: the framework's published port is reached over loopback and its
gateway proxies to the env container by the compose service name (the
environment name). 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
+256 -3
View File
@@ -30,15 +30,18 @@ code units; follow `coverage.next_offset`. The page preserves `source_status` an
`reported_total_bytes`: exhausting retained text does not make a partial decoded
manifest complete. Complete source Evidence remains exportable under the existing
session lifetime. Servers without retention reject summary before starting JADX.
One-shot CLI output remains complete. Older servers require the existing complete
request after schema discovery. APK authenticity and runtime behavior remain
One-shot CLI output remains complete by default. Select `--detail summary` with
`--evidence_output /local/capture.json` to retain complete Evidence before returning
a linked view. Older servers require the existing complete request after schema discovery. APK authenticity and runtime behavior remain
unverified.
## Manifest component projection
`inspect_android_package` also returns a static inventory of declared
activities, aliases, services, receivers and providers from the decoded
manifest. `declared_name` preserves the source attribute; `name` resolves a
manifest. The binary XML decoder preserves component class spelling, including
`$` in nested classes, without applying JADX class aliases. `declared_name`
preserves the decoded source attribute; `name` resolves a
relative name only when the manifest package is known and the resolved copy
fits the UTF-8 byte budget. An unresolved package or exhausted name budget
retains the declared name and marks the inventory partial. Empty component
@@ -76,6 +79,61 @@ capacity limitation appears only when an actual collection limit was reached.
The projection does not merge manifests, expand resource references, or
observe runtime enabled/export state.
`enabled` and `grant_uri_permissions` report only literal component-level
`android:enabled` and provider-level `android:grantUriPermissions` declarations.
They are `null` when absent or not a literal boolean; missing attributes are not
filled from application defaults. A nonliteral declaration gets a limitation.
`process` preserves the exact component-level `android:process` spelling (including
empty or symbolic values), or `null` when absent or omitted under the inventory-wide
1 MiB copy budget. Neither field resolves resources, merges manifest values or
establishes the effective runtime process or enabled state. The exact boolean
attributes are retained in `enabled_declaration` and
`grant_uri_permissions_declaration`, including resource references.
`intent_filters` preserves each filter's source ordinal, exact priority spelling,
actions, categories and individual data declarations (scheme, host, port, path,
path prefix/pattern/advanced pattern/suffix and MIME type). These are declarations,
not computed Android matching rules. `meta_data` lists names; values remain in the
complete decoded manifest. Component, filter, data and metadata `location` values
use one-based lines/columns and UTF-16 offsets into that manifest. A component's
`declaration_index` preserves its original declaration ordinal, including gaps.
`declaration_coverage` distinguishes complete, partial and unknown observations.
Historical Evidence omits newly introduced fields and defaults coverage to
`unknown`; omission never establishes absence. Current records contain the fields,
with null for absent or unresolved scalar declarations. The inventory retains at
most 32 filters and 64 nested action/category/data/metadata records per component,
and shares a 1 MiB structured-value copy budget across components. Omitted values
or unsupported filter constructs mark coverage partial and include a limitation;
complete retained manifest text remains accessible.
For a small answer, select `detail: "summary"` with an explicit view:
```json
{
"kind": "android",
"facet": "components",
"actions": ["android.provider.Telephony.SMS_RECEIVED"],
"fields": ["name", "permission", "enabled", "process", "intent_filters"],
"offset": 0,
"limit": 16
}
```
The same JSON works with CLI `--view` or retained `inspect_analysis_view`.
`kinds`, `names` and `actions` use exact matching; names accept either the recorded
declared or resolved name, actions match any requested action, and different
filters combine with AND. `exported` matches only explicit declarations, keeping
`exported_default` separate. Empty selectors match nothing. Every selected row
retains its parent-array `source_index` and `declaration_coverage`; source coverage,
parent identity and limitations remain alongside the page. Follow
`coverage.next_offset`. The 1 MiB projection budget can shorten a page; a single
oversized row requires fewer selected fields. Exhausting a partial source does
not establish complete manifest coverage. `facet: "component-summary"` applies
the same filters and counts kinds, declaration coverage and explicit/default
exported values separately. Both adapters use the same retained projection;
repeated pages do not reload JADX.
The service `foreground_service_type` field preserves the declared attribute,
including an empty value or surrounding spaces; `null` means the attribute is
absent or the component is not a service. This field does not validate service
@@ -230,6 +288,162 @@ instructions into field declarations, leaving an empty or incomplete method
body. The selected method's disassembly preserves those instructions and retains
the same source byte limit and explicit truncation reporting.
## Apply an R8/ProGuard mapping
Release builds shrunk by R8 or ProGuard rename classes and members. Select the
build's `mapping.txt` with `mapping_path` on `inspect_android_class` or
`inspect_android_method`, or `--mapping-path` on the matching CLI command:
```sh
rea inspect-android-class /path/Example.apk a.b --mapping-path /path/mapping.txt \
--detail summary --evidence_output /tmp/class-evidence.json
```
For agent workflows, select `detail: "summary"` on class and method inspection.
It preserves the complete normalized member inventory or selected method body,
including mapping annotations, while retaining duplicate raw provider calls in
the complete parent Evidence. The reply links that parent's identity and digest;
export it with `export_evidence_bundle` or read its summary again through
`inspect_analysis_view`. CLI summaries require `--evidence_output` and return
the portable bundle path. Omitted or `complete` detail preserves complete inline
Evidence. Search and reference operations retain their existing contracts.
Symbol summary views admit at most **1 MiB**, including view context. An admitted
method's source can already consume that amount; a larger combined summary
fails explicitly instead of silently truncating facts. MCP refusal includes
the retained parent ID. Select complete detail, or inspect one method rather
than a whole class, when the requested summary does not fit.
The mapping path must be absolute. Selectors still take the observed names, such as
`a.b`, and observed rows are unchanged. The result adds one `mapping` block with
the file's path, SHA-256 and size, the header values the file reports
(`compiler`, `compiler_version`, `min_api`, `map_version`, `pg_map_id`,
`pg_map_hash`), valid record counts and up to 16 malformed line samples. Its
`symbols` list has one entry per observed class, inner class, method and field;
`inspect_android_method` lists the class and the selected method. `coverage`
counts each resolution status. With summary delivery, these unchanged facts are
under the view's `summary` field; the view separately reports source coverage.
Lookups use the bridge's raw DEX names, not JADX display aliases such as a
renamed reserved word. Each symbol resolves as:
- `mapped`: exactly one record matches. A class needs one record for its raw
name (`verified_by: "class"`). A method must also match its DEX prototype
(`"descriptor"`) and a field its DEX type (`"type"`). R8 residual signature
metadata is used when present; otherwise original types are translated
through the file's class records.
- `ambiguous`: `multiple-records`, `descriptor-mismatch`, `type-mismatch`,
`ambiguous-class` or `residual-signature-conflict`, with `candidate_count` and
up to 8 candidates. Conflicting residual metadata never selects a winner. A name match
whose prototype or type does not verify is never reported as mapped.
- `unmapped`: no valid record matched the raw identity.
- `unknown` with reason `projection-budget`: this claim did not fit the combined
reply budget. The observed raw symbol remains present; `coverage.unknown`
counts these omissions. Inspect that specific class or method separately,
or consult the selected local mapping file for complete source records.
A line continues an inline frame stack when it repeats the previous line's
minified range and obfuscated name and gives a single call-site line, such as
`:7`. Only the outermost original of a stack becomes a candidate. Original
line numbers and source files are not projected. Malformed records are counted
and skipped, so an `unmapped` symbol might be described by one of them. A file
that is missing, not a regular file, not UTF-8, larger than the byte limit or
without any class record, such as `usage.txt` or `seeds.txt`, is refused before
JADX is used. Requests read their mappings one at a time, in the same queue as
the JADX work and under the same operation deadline. A mapping failure therefore never starts or retires the JADX
session, and a different mapping reuses the loaded APK.
## Link native declarations to JNI candidates
When advertised, `inspect_android_jni_bindings` links original `ACC_NATIVE`
declarations from standard root `classes*.dex` members to bundled ELF libraries.
The supplied JAR's DEX reader preserves duplicate declarations before decompiler
deduplication. This operation does not load the APK into the decompiler.
MCP defaults to retained summary delivery when `detail` is omitted; select
`complete` explicitly to receive the full report inline.
```json
{
"path": "/absolute/Example.apk",
"class_name": "org.conscrypt.NativeCrypto",
"method_names": ["EVP_PKEY_new_RSA"],
"abis": ["arm64-v8a"],
"detail": "summary"
}
```
Class/method names and optional `descriptors` select raw DEX identities.
`library_paths` selects exact logical APK paths such as
`lib/arm64-v8a/libconscrypt_jni.so`; each library's `source_path` preserves its
original ZIP spelling. Omitted filters include all scoped facts; `[]` matches
none. Class selection never narrows the global inventory used for table-class
attribution.
Independent `declarations`, `libraries`, `candidates` and `bindings` collections
have stable IDs and source ordinals. Candidates retain APK/library digests,
ABI, function addresses and file offsets. Table candidates also retain section,
table and entry identity plus all three name/signature/function pointer slots
and their relocation sources. JNI exports follow the
[UTF-16 escaping and short-before-long rules](https://docs.oracle.com/en/java/javase/21/docs/specs/jni/design.html#resolving-native-method-names);
failed escaping does not acquire an invented export match. Tables require
NUL-terminated [Modified UTF-8 strings](https://docs.oracle.com/en/java/javase/21/docs/specs/jni/types.html#modified-utf-8-strings),
valid descriptors and executable load mappings. REL, RELA and RELR retain
separate provenance; unsupported packed relocations and unresolved pointer
spans stay explicit unknowns.
A static `JNINativeMethod` entry names no class. Attribute it uniquely only
when exactly one declaration in the complete recorded native inventory has
that `(name, descriptor)` pair. Multiple classes remain ambiguous after a
class filter; a partial inventory cannot establish unique attribution.
Each selected declaration has a row per selected/observed ABI. `matched` means
candidate presence was observed; `ambiguous` means multiple observed targets
or class associations remain. Binding `coverage` is separate: a matched
partial row does not establish complete uniqueness, and an empty partial scan
is `unknown`, never `unmatched`. ELF/ABI label mismatches preserve facts without
asserting a binding. No result establishes library loading, runtime registration
or method invocation.
Summary returns the first 64 selected binding rows, their declaration/candidate
closure and every selected library's identity, coverage and failure reason;
counts and page coverage describe the full selected binding set. Selected
declaration IDs have separate preview coverage, so native declarations remain
visible even when the APK has no bundled ABI libraries. Complete
Evidence stays retained. Read exact fields or further pages without reopening
files or rerunning analysis:
```json
{
"source": { "kind": "retained-evidence", "evidence_id": "ev_<digest>" },
"view": {
"kind": "android-jni",
"collection": "bindings",
"offset": 64,
"limit": 64,
"fields": ["declaration_id", "abi", "status", "coverage", "candidate_ids"]
}
}
```
Collections also include `declarations`, `candidates` and `libraries`, with
exact filters and batch lookup by declaration/candidate/library IDs. `row_index`
is the original parent collection index; DEX and
ZIP source ordinals stay separate. Complete detail returns the full report.
CLI uses the same selection and delivery contracts. Its common one-shot
default remains complete; summary delivery requires an explicit Evidence path:
```sh
rea inspect-android-jni-bindings /absolute/Example.apk \
--query '{"class_name":"org.conscrypt.NativeCrypto","method_names":["EVP_PKEY_new_RSA"],"abis":["arm64-v8a"]}' \
--detail summary --evidence_output /absolute/fresh-jni-evidence.json
```
Optional `--view` accepts the same JSON page and requires summary delivery.
Evidence bundles never overwrite files. Complete declarations and one library
selection are cached within the immutable APK session. Changing ABI/library
selection replaces the scan; class/method selection reuses it. Fresh analysis
still validates current caller APK bytes. Idle/close releases the caches;
retained Evidence remains historical and independently readable.
## Interpret the result
- Package inspection retains decoded manifest XML, summary declarations,
@@ -266,6 +480,11 @@ the same source byte limit and explicit truncation reporting.
`dex_descriptor`, for example `(I)V`. Display names can be JADX aliases;
the descriptor alone is not a complete raw DEX method ID. Overload indices
are tied to this artifact and engine, not stable identities across builds.
- A `mapping` block appears only when the caller selected `mapping_path`. Its
names are claims from that file, not observations of the APK. REA does not
check that the mapping belongs to this build; `pg_map_id` is reported, not
compared. Evidence keeps the selected path in its parameters and the file's
SHA-256 in the result.
- Method inspection reports Java or smali, fallback markers and complete/partial
returned text. Decompiled source is a derived representation. A complete text
result does not establish complete semantics or a byte-identical reconstruction.
@@ -355,6 +574,19 @@ target/configuration changes, failure, timeout, cancellation, MCP disconnect or
server shutdown. One-shot CLI commands always join cleanup before returning.
REA never writes to the original APK or launches target code.
JNI scans reuse the analyzer process without loading the APK into the
decompiler. They admit at most 64 MiB per DEX member and 256 MiB of DEX bytes,
with a 4 MiB native-declaration JSON allowance before MCP string escaping.
Native libraries are processed sequentially: one 64 MiB buffer, 256 MiB total
selected read work, and a 16 MiB parsed-library-facts allowance. ZIP inventory
and library counts also have explicit resource bounds. Unexamined occurrences
remain unknown. A complete relationship report has a separate 16 MiB serialized
allowance; summaries/pages allow 1 MiB including their provenance envelope.
These are resource admissions, not claims about maximum valid Android formats.
Select fewer ABI/library occurrences or smaller retained pages when needed.
Completed parsed library facts survive failed reader finalization in typed
partial observations; the exact reader owner remains available for cleanup retry.
On Windows, stdin writes preserve stream backpressure and run outside the Node
event loop. Cancellation terminates the retained job, including descendants,
before workspace cleanup. On Windows, a detached REA helper owns the private
@@ -440,6 +672,27 @@ complete, case-sensitive search contract. A protocol frame above **8 MiB**, or c
**32 MiB per operation**, fails with a diagnostic instead of returning an incomplete inventory
as complete. These are memory-safety boundaries, not undocumented result caps.
A selected R8/ProGuard mapping is re-read and SHA-256 checked on every call, up
to **64 MiB**. The serialized provider keeps one successful parsed index, keyed
by byte length and digest with fixed parser options. Identical bytes reuse that
index; changed bytes are reparsed, missing files still fail, and each response
preserves the currently selected path. The index is released on provider idle
retirement or close. Omitting `mapping_path` never applies the cached mapping.
During replacement, the old index can coexist with the new parse until it
succeeds; these transient allocations count toward process memory.
Before retaining records, the parser admits an estimated **128 MiB** index
representation and **8 MiB** of expanded mapped claims per residual class,
including shared header facts. The index allowance accounts for strings and
containers; it is not a measured V8 heap cap. Parameter and metadata expansion
is admitted before splitting or JSON decoding. These fixed resource bounds
have no runtime override; refusal reports `resource_constraint`, the source
line and mapping SHA-256. Ambiguous lookups count all candidates while keeping
only the first eight in stable file order. A separate **8 MiB** combined claim
budget applies to the actual query set, including outer and inner classes,
before cloning the report. Claims that do not fit become explicit `unknown`
entries; other admitted claims and all observed identities remain available.
## Real verification
Download the explicit public fixtures once; this installs no tools:
+24 -12
View File
@@ -179,26 +179,31 @@ share the application workflow, projection, retention and publication owners.
- `schemes_agree_on_signer` (observed): every present block scheme presents
the same _set_ of signer certificates. An extra signer in one scheme is
disagreement; a signer without a certificate makes it `null` (unknown).
Build-tools 33+ rotate through v3.1 by default, so a rotated app usually
reads `false` here and `true` below.
A single present block scheme with known signers agrees with itself;
v1 is compared separately below.
- `signer_change_declared_by_rotation` (declared): the signers differ, but
each appears in a lineage the APK declares. Read the two together: a
rotated APK shows `false` / `true`; signers that differ with no declared
lineage containing them show `false` / `false`. It is `null` when a
signer's identity is unknown, or when the signers differ and a declared
lineage could not be decoded.
each appears in a lineage the APK declares. Read the two together: block
schemes with different signers covered by a declared lineage show `false`
/ `true`; differing signers without such a lineage show `false` / `false`.
A lineage alone does not establish a change between block schemes. It is
`null` when a signer's identity is unknown, or when the signers differ and
a declared lineage could not be decoded.
- `v1_signers_match_block_signers` (observed): the v1 signer certificates
equal what the lowest block scheme that has signers (v2, else v3, else
v3.1) expects v1 to carry. That is its signer set, except that a v3/v3.1
signer declaring a rotation lineage expects the lineage's first
(original) certificate, as apksig requires. `false` is notable: the JAR
signature names a different key than the block signature. A key rotation
keeps v1 (and v2) on the original key, so it reads `true` while
`schemes_agree_on_signer` reads `false`, with or without v2. `null` when
v1 or a block scheme is absent, any signer's identity is unknown (a
signature names a different key than the block signature. When v1 uses
the lineage's original key and v3 its newer key, this comparison reads
`true`. If v3 is the only present block scheme, agreement is `true` and
declared inter-block signer change is `false` even though rotation is
present. If v2 also uses the original key, agreement is `false` and the
declared inter-block change is `true`. `null` when
v1 or a populated block scheme is absent, any signer's identity is unknown (a
`decode_error`, a `null` certificate or a `subjectKeyIdentifier`
`SignerInfo`), or the lineage's original certificate cannot be
identified; a limitation then says why.
identified. When identities or a lineage origin are unknown, limitations
explain why; absence is shown in the scheme records.
- `strongest_scheme`, `rotation_present`, `source_stamp_present`,
`self_consistent`.
@@ -239,6 +244,13 @@ serialized size of the report together with its limitations (which repeat
archive names) is then checked against an 8 MiB output budget (the exact check
is authoritative); an over-budget report is refused, not truncated.
Signing blocks admit at most 4096 ID/value pairs; at most 4096 signing-relevant
META-INF entries are retained. These fixed counts, signer/lineage counts and the
report byte budget return nonretryable `resource_constraint` errors naming the
effective allowance. This release has no runtime override for them. Waiting for
an active scan cannot raise a fixed count, and complete CLI JSON cannot raise the
report budget. Occupied scan-queue capacity remains retryable after a scan finishes.
The whole-file reader allocates the selected snapshot and bounded read scratch;
total process memory exceeds the selected file's size. It also computes the complete
file SHA-256, so inspection is not header-only. Content digests are recomputed
+6 -5
View File
@@ -100,12 +100,13 @@ still suppresses all string projection, including in this mode.
- **Metadata comes from apktool.yml as apktool printed it.** Version codes
keep their own spelling (`'7'` versus `7`); `package_name` is read from
the decoded manifest, not inferred.
Apktool 3's emitted `version: 3.x.y` header selects its single-line string
dialect: literal hashes, single quotes, empty strings, and the text `null`
stay part of the value; producer backslashes and Unicode escapes decode
once. Older/tagged documents retain YAML scalar semantics; double-quoted
values also retain YAML string semantics.
The `version: 2.9.0`-or-later header that Apktool 2.9+ and 3 emit selects
their single-line string dialect: literal hashes, single quotes, empty
strings, and the text `null` stay part of the value; producer backslashes
and Unicode escapes decode once. Older/tagged documents retain YAML scalar
semantics; double-quoted values also retain YAML string semantics.
This distinction follows the released
[2.9.0 metadata writer](https://github.com/iBotPeaches/Apktool/blob/b64e257c9b689eb9630ad0241f2fe4f4a749955b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/VersionInfo.java#L38-L42),
[3.0.3 metadata writer](https://github.com/iBotPeaches/Apktool/blob/18b5e99cb56ff9451e8aa55b065dcf5bbd616975/brut.apktool/apktool-lib/src/main/java/brut/androlib/meta/VersionInfo.java#L49-L55)
and [string escape owner](https://github.com/iBotPeaches/Apktool/blob/18b5e99cb56ff9451e8aa55b065dcf5bbd616975/brut.j.yaml/src/main/java/brut/yaml/YamlStringEscapeUtils.java#L55-L116).
- **The manifest is the decoded text**, bounded at 512 KiB and reported as
+7 -2
View File
@@ -101,8 +101,8 @@ limitation reports how many inventoried entries were left out. IPA projection
still lists every archive component, including `SwiftSupport/`.
`platforms` lists `macos` for application roots with `Contents/`. It lists `ios`
for shallow application roots that have an `Info.plist`. An application root
with neither, such as an empty inventory, has no platform.
for shallow application roots that have an `Info.plist` at their root. An
application root with neither, such as an empty inventory, has no platform.
## macOS bundle anatomy
@@ -149,6 +149,11 @@ directories rather than `Versions/Current`. A framework's `info_plist_path` is
because `Versions/Current` decides which one applies) or when its single
version directory has no `Resources/Info.plist`.
A `shallow` bundle's `info_plist_path` is its root `Info.plist`. Without one,
it is `Resources/Info.plist`: a flattened macOS framework keeps its binary,
`_CodeSignature/`, and `Resources/` directly in the `.framework`, like a single
`Versions/<version>/` directory without the `Versions/` wrapper.
AppleDouble sidecar files (`._*` and `__MACOSX/`) are inventory facts, but they
describe neighbouring files. They are excluded from roots, bundle roles, and the
anatomy components.
+3 -3
View File
@@ -21,14 +21,14 @@ graph TD
subgraph "Application Layer"
APP["src/application/<br/>Shared CLI/MCP workflows<br/>enhanced analysis and investigations"]
SESSION["SessionProviderRouter + BinarySession<br/>one immutable deep binding per target<br/>disjoint auxiliary routing"]
REGISTRY["AnalysisProviderRegistry<br/>sorted deep candidates<br/>deterministic selection, no fallback"]
REGISTRY["AnalysisProviderRegistry<br/>sorted deep candidates<br/>deterministic selection, no fallback<br/>ProviderInspectionScope: prerequisite observation lifetime"]
RECORDS["src/application/investigation/<br/>composed InvestigationRecords + narrow ports<br/>EvidenceLedger and Unknown ownership"]
SNAPSHOT["BinarySessionRecords + AnalysisSnapshotCache<br/>binary target/profile snapshots and session file ownership<br/>record coordination and post-commit notifications"]
JS_RECON["src/application/javascript/ + src/artifacts/javascript/<br/>JavaScript artifact reconstruction<br/>directory/ASAR reads<br/>AST-only bundle projection"]
end
subgraph "Provider Layers (selected adapters)"
PROVIDER_OWNERS["src/providers/<br/>shared deferred client and inspection owners<br/>exact cleanup retry and attributed failures"]
PROVIDER_OWNERS["src/providers/<br/>shared deferred client owners<br/>exact cleanup retry and attributed failures"]
PWNTOOLS["src/native/pwntools/ + src/native/pwndbg/<br/>BYO offline ELF/core adapters<br/>owned snapshots/Python and optional core-only GDB<br/>unchanged upstream parsers, ABI structures and mapping API"]
WASM["src/wasm/<br/>caller-supplied WABT; immutable artifact inspection<br/>owned process supervision and retryable workspace cleanup"]
APKSIG["src/apkSignature/<br/>in-process APK Signing Block + v1 reader<br/>bounded single read, no device or execution"]
@@ -75,7 +75,7 @@ graph TD
end
subgraph "Domain Layer"
DOMAIN["src/domain/<br/>Pure side-effect-free modules<br/>format declarations, Evidence, comparisons, application graphs"]
DOMAIN["src/domain/<br/>Pure side-effect-free modules<br/>format declarations, provider selection, Evidence, comparisons, application graphs"]
end
subgraph "Configuration"
+21 -4
View File
@@ -52,7 +52,11 @@ 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
parent/child structure independently. Node value lengths are comparable only
when both nonempty snapshots declare the same `node_value_length_unit`.
Missing or different units leave length comparison unknown; independent node
or frame structural differences can still prove change. Empty inventories have
no value lengths to compare. Frame IDs and sibling enumeration order
are capture-local and do not establish a change; duplicate IDs, missing parents,
and cyclic ancestry remain unknown. A complete frame difference can still prove
change when DOM nodes are incomplete, and vice versa. Partial DOM or metadata
@@ -400,7 +404,19 @@ 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
next-request event falls inside the window. A redirect row's optional
`redirect_response` contains the prior response `url`, CDP-reported `status`,
and `scope`. The URL has transport credentials removed; URL and status are
withheld unless its origin is approved. Missing or malformed response URLs have
null scope and add `invalid_protocol_value` timeline coverage; a valid URL with an
unsupported protocol has `unsupported` scope. Outside-policy and unsupported
responses mark the timeline as policy-filtered with `disallowed_origin` or
`unsupported_url`. Missing status remains null rather than zero. A supplied
non-numeric status is also null and records `invalid_protocol_value` coverage;
the other valid response facts remain available. Historical rows may omit this
field; omission does not establish that no prior response existed. Response
headers and bodies are discarded. The row timestamp belongs to the next request,
not an exact prior response time. 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. Session
@@ -415,7 +431,8 @@ allowance; exhaustion fails the observation explicitly instead of guessing scope
Response metadata parses repeated CDP header field lines independently. The
Link projection retains their declarations in order. `csp.directives` lists the
directives of every CSP policy in order, across field lines and comma-separated
policies, without recording policy boundaries, so a directive name can repeat.
policies, without recording policy boundaries, so a directive name can repeat
across policies. As in CSP3, a repeated name within one policy is ignored.
Single-valued policy fields combine their lines as one comma-separated value,
as RFC 9110 specifies. Each link keeps its target in `href` and
its relationship context in `context_url` with a separate `context_scope`;
@@ -448,7 +465,7 @@ not bound the whole process heap.
REA retains local observation data and removes only URL userinfo credentials, explicitly declared scenario secrets, and values from structured credential/storage fields:
- URL observations preserve the complete local URL, including query values, fragments, duplicate parameters, and their order. Only username/password userinfo is removed; malformed original URL strings remain available with `origin: null`.
- DOM snapshots retain node types, node names, value lengths, and attribute names, but not text or attribute values.
- DOM snapshots retain node types, node names, value lengths, and attribute names, but not text or attribute values. `dom.node_value_length_unit` is `utf16-code-units` for web observations and applies to every node's `node_value_length`; it counts JavaScript string code units, not Unicode code points or UTF-8 bytes. Electron observations declare `utf8-bytes` instead. Historical captures without the unit leave it unknown; reading them does not infer a unit or convert their stored lengths.
- Supported DOM URL attributes are projected separately as resolved destinations. Empty `action` on HTML or XHTML forms and empty `formaction` on HTML or XHTML submit controls resolve to the document URL; other relative URL attributes resolve against the captured document base.
- Accessibility structure and reported roles are retained by default, while names and descriptions require `include_accessibility_text: true`. The browser protocol may omit an individual role; that role remains unknown for comparison. Other observed accessibility differences can still establish a change.
- Network observations retain method, status, MIME type, size, type, initiator stack location, and complete URLs with userinfo credentials removed. Redirects reported by CDP are attached as ordered `redirects` on the one request ID, with the prior request URL, CDP response URL, method/type, response status/MIME/encoded length, request timestamp, and the next `requestWillBeSent` event timestamp. CDP delivers `redirectResponse` with that next request event, so the latter is an event boundary rather than an exact response timestamp. Redirect response headers and bodies are discarded; hops outside the selected origins are discarded with the request chain. Headers are discarded after an allowlisted projection of length/encoding, structured CSP/Link/policy fields, and untrusted agent hints. Cookies and authorization headers are never retained.
+242 -5
View File
@@ -51,6 +51,30 @@ 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.
## Validate a scenario before running it
`validate-browser-scenario INPUT_JSON` checks one scenario against the same
`browserScenarioSchema` refinement that `capture_browser_scenario` admits, and
stops there. `INPUT_JSON` may be inline JSON, a JSON file path, or `-` for
standard input.
```bash
rea validate-browser-scenario ./browser-scenario.json --json
```
A valid scenario reports `{"valid":true,"actions":<count>,"secrets":<count>}`
and exits 0. An invalid one exits 1 and reports the same field paths capture
would report, so a correction made here is the correction capture needs:
duplicate or reserved step IDs, duplicate secret identities and
environment-variable names, undeclared secret references, request-step
violations, and unknown fields.
Validation performs no browser discovery, launch, attachment, or navigation and
constructs no provider. It does not read secret environment variables, so a
scenario whose declared variables are unset still validates; the missing-value
failure belongs to capture. A schema-valid scenario does not prove that the
executable or target is available on the host.
## Minimal launch example
Save this as `browser-scenario.json`, replacing the executable path with an
@@ -173,6 +197,12 @@ distinction: it closes and deletes provider-owned profiles, but only disconnects
from an external CDP browser. Real-browser verification checks both outcomes and
confirms that an attached external browser remains alive.
CDP connections leave Playwright's default-context overrides disabled. The
selected page receives the declared scenario environment and temporary focus
emulation, so actions can complete while that page is in the background.
Its environment owner clears these overrides before disconnecting; other pages
keep their media settings. Connecting does not create a bootstrap page.
That cleanup requires REA to remain running. Abrupt termination, including
Windows process-tree termination or POSIX `SIGKILL`, can leave the launch
profile and Playwright artifacts behind. A profile can retain cookies, history,
@@ -207,7 +237,8 @@ HTTP(S) URLs may include ordinary query values and fragments directly. Use
ordered structured query entries when a value needs to reference a declared
environment-backed secret. Form, storage, and cookie values are either literal
strings or declared secret references; request step headers can also read a
cookie or local storage value from the page. Raw URL userinfo credentials are rejected.
cookie or local storage value from the page, and request steps and `goto`
destinations can send [saved values](#saved-values). Raw URL userinfo credentials are rejected.
Captured credential-header
values are not retained, and declared secret values are redacted automatically.
A secret may be declared solely to
@@ -380,8 +411,10 @@ data you may change. This scenario creates one item:
- Request steps follow no redirects: a redirect answer fails the step, and
nothing is sent to the location it names, though a write the redirect
answered may already have been applied. `expected_status` cannot name a 3xx
status. Give the path the redirect names; with header values selected, the
capture records its `Location`.
status. Manual redirects can be opaque to the page and may not produce a
response event; their status and `Location` can therefore be unavailable even
when network events and header values were selected. Such captures report
incomplete event coverage.
- Header values are literals, declared secrets, a cookie the browser holds for
the request URL (`{"source": "cookie", "name"}`, HttpOnly cookies included,
whose value the page's scripts can then see while the request runs), or a
@@ -400,6 +433,17 @@ data you may change. This scenario creates one item:
by default) get smaller: after a 32-character `X-CSRFToken` value, a body over
about 47 KiB is kept as `unavailable`. Raise `capture.limits` when the
application's responses are larger.
- A header can send Basic credentials, `{"source": "basic_credentials", "parts":
[username, password]}`: the base64 of `username:password`, after a `prefix`
such as `"Basic "` or with none, as some APIs take encoded credentials in
their own header. Each part is a literal, a declared secret, a saved value, a
cookie or a local storage entry, so a header a frontend builds from a login
token can be sent too; the password is never a literal other than empty, since
Evidence records literals as written, and a username with a colon fails the
step, since Basic authentication ends the username at its first colon. The
encoded value is redacted however short, as
`[REDACTED:page:<step_id>.<header>]`, and parts read from the page are
redacted as page values are.
- Validation refuses a header name given twice in a step, header names a
page's `fetch` cannot set, such as `Cookie`, `Origin`, `Host` or `Sec-*`, and
`User-Agent`, which Chrome drops; it refuses line breaks and other ASCII
@@ -425,6 +469,143 @@ Captures with request steps state in `limitations` that the steps sent their
declared requests through the page's fetch. A scenario without request steps
is unchanged.
## Saved values
A step can keep a string or number from a JSON response, by name, and a later
step can send it, so a scenario can read back, edit and delete an object whose
id the application assigns:
```json
{
"browser": {
"mode": "launch",
"executable_path": "/absolute/path/to/chromium"
},
"start_url": { "url": "http://127.0.0.1:3000/items" },
"actions": [
{
"step_id": "save-item-1",
"action": "click",
"timeout_ms": 10000,
"locator": { "kind": "role", "role": "button", "name": "Save" },
"save_response": {
"method": "POST",
"path": "/api/items",
"save": [{ "name": "item_1", "json_pointer": "/id" }]
}
},
{
"step_id": "open-item-1",
"action": "goto",
"timeout_ms": 10000,
"destination": { "url": "http://127.0.0.1:3000/items/{saved:item_1}" },
"wait_until": "load"
},
{
"step_id": "copy-item-1",
"action": "request",
"timeout_ms": 10000,
"method": "POST",
"path": "/api/items/{saved:item_1}/copies",
"json": {
"source_id": "{saved:item_1}",
"title": "Copy of {saved:item_1}"
},
"expected_status": [201]
}
]
}
```
- A `request` step saves with `save: [{name, json_pointer, secret}]`, from its
own response. A `click` or `press` step saves with `save_response: {method,
path, save}`, from a newly observed matching response while the step waits.
The recorder watches before the action and excludes requests already running,
such as an earlier autosave. Method/path matching does not prove that the UI
caused the request: use a path that distinguishes the intended operation from
background polling. Multiple observed matches before binding fail as ambiguous;
requests starting after this observation window cannot be ruled out. It matches the method and a path on the
start origin as the browser spells it, so a path may name `My List` or
`My%20List` (`{*}` matches one segment, and the query is ignored), and fails
the step unless a 2xx JSON response arrives before its `timeout_ms`; one still
being read when the step times out or is cancelled saves nothing. A pointer
that names no string or number fails the step, so later steps never send a
missing value, as does a response over 4,000,000 characters: a request step
stops reading and aborts its fetch there. A UI step reads a body only when
its decoded size is bounded at 12,000,000 bytes or less: its received size,
or the declared Content-Length of one served from cache, times 1032 for each
gzip or deflate coding, the most DEFLATE expands. Other codings and unknown
or zero sizes are refused before materializing the body; decoded text over
the character limit also fails. The UI action may already have applied.
- `{saved:name}` sends a saved value in a request step's `path`, including its
query, and in a `goto` destination's `url`, percent-encoded; a destination's
structured `query` values are sent as declared. A saved value that makes a
path segment `.` or `..`, alone or with the text beside it (including `%2e`),
fails the step, since the URL would drop it. In a request step's `json` body,
a string that is only `{saved:name}` becomes the saved value with the JSON
type it was saved with, so a saved number id is sent as a number, and
`{saved:name}` inside a longer string is filled as text. A header value or
Basic credentials part sends one as `{"source": "saved", "name"}`. Other
braces, such as `{id}`, are sent as written, and so is a percent-encoded
`%7Bsaved:name%7D` anywhere but a `goto` URL, whose parsed form spells the
braces that way.
- Validation refuses a saved value that no earlier step saves. A later save of
the same name replaces the value. An integer past 2^53, which JSON parsing
would round to another number, and a number that is not finite, such as
`1e400`, negative zero, or a value that underflows to zero, such as `1e-400`, fail the step
that saves it.
- A scenario keeps at most 4,000,000 characters of saved values at once,
counting distinct retained redaction spellings, including trimmed variants,
of values saved as secret. Replacing a binding releases its live value
charge, while secret spellings remain protected for the scenario lifetime.
A save past the budget fails before changing the binding.
- A value saved with `secret: true` is redacted however short, as a declared
secret is, as `[REDACTED:page:<step_id>.<name>]`. The selected source
response is protected before retaining its body or header values, including
when only headers were requested. If that body cannot be read safely, its
body and header values remain unavailable. Before publishing the capture,
the selected source transaction's earlier URL, request headers and request
body are also protected using the admitted values. Unresolved source values
withhold that transaction's affected metadata/content with an explicit
limitation. Before publication, retained events are rechecked
with the final marked-response values, including immediate follow-up requests
and their response bodies, console/page errors, WebSocket text and event URL/name fields. Learned redaction facts are independent of source-identity readiness. Unknown source values withhold only the selected
source transaction. Other saved values, such as ids, stay visible, since
environments model them. The environment build warns about saved values
named like credentials that are not marked secret
(`credential-named-saved-values`).
- Page-derived cookie/local-storage values and constructed Basic credentials
remain redacted only from observations made after they were read/built.
They do not retroactively rewrite earlier facts. The final event projection
borrows only declared and response-marked patterns; promotion of an already
held page value to an explicit response secret preserves its first marker.
Projection state is session-local, references admitted pattern/byte owners,
and is invalidated on admission or response classification changes.
- Screenshots are withheld as `missing` from the start when the scenario plans
any response save marked `secret: true`, page-derived or Basic authentication
header values, or whenever nonempty sensitive values
are already known. Raw pixels cannot be safely text-redacted, so the provider
does not request pixels in those cases. This also protects earlier steps and
partial failures without retaining an image to scrub later. Other requested
artifacts remain available; affected screenshot/aggregate completeness is
partial and is not eligible for equality.
- Saved URLs and expanded request JSON are admitted before building their expanded strings or
serializing. Its allowance is the smaller of Node's string limit and
one sixteenth of current V8 available heap bytes, allowing for the expanded
tree, serialization, Playwright transport and browser-side copies. Size
accounting includes JSON escaping and repeated references; each distinct
saved value's size is measured once per request. An oversized request fails
before browser dispatch; the complete request envelope, including repeated
header values, is checked as well. URL encoding uses a conservative
nine-characters-per-UTF-16-unit allowance before encoding a saved value.
Reduce the payload/repetitions, or raise the parent
Node heap and restart; this is a conservative allocation estimate, not a
measurement or guarantee of browser/process-family memory.
- Evidence records a request step's empty `save` list as absent, so a scenario
that saves nothing records the same parameters and `scenario_sha256` as
before saved values existed, and REA versions without saved values read its
captures.
## Network evidence
`capture.events: ["network"]` retains request, response, completion, failure,
@@ -472,8 +653,9 @@ the browser's wall-clock start, and `elapsed_ms`, its time from that start to
the end of the response, when the browser reports them. The environment views
time scenario records from these, as HAR entries are timed: the browser's start
where it reported one, else `observed_at`, which trails it by up to tens of
milliseconds while REA reads other responses, and a duration of 0 where the
browser reported none. Captures made before these fields existed lack them and
milliseconds while REA reads other responses. A duration is retained only from a
unique terminal event that reports it; missing or ambiguous durations stay
omitted, while an explicitly reported zero remains zero. Captures made before these fields existed lack them and
are read in record order. REA versions before them refuse captures that carry
them. Scenario comparisons ignore all three (`ignore_network_request_timing`).
Requests sharing a URL remain distinct. Redirects link to the preceding
@@ -621,3 +803,58 @@ rules and preserve the same missing fact.
Network normalization also commits the removal of capture-local transaction IDs,
attribution to the requesting step, and unordered transaction comparison. These
built-in rule identities participate in the normalization digest.
## Summary delivery and retained views
`capture_browser_scenario` accepts `detail: "summary"` to retain the complete
capture in the MCP session and return its summary. The default remains
`complete`. Delivery detail does not change scenario parameters or identity.
The summary reports each step's status, error, URL and captured/missing/truncated
section names. It omits `not_requested` sections and repeated `before_url` values.
The accessibility tree comes from the first unsuccessful step, or the final
step on success; when that step captured no tree, its nearest earlier captured
tree is identified explicitly. Event and network counts cover retained records,
with capture omissions reported separately.
For the one-shot CLI, save the complete Evidence before selecting a summary:
```bash
rea capture-browser-scenario scenario.json --detail summary --evidence_output /absolute/path/scenario-evidence.json --json
```
Use the returned `normalized_result.parent_evidence_id` with
`inspect_analysis_view` source `{kind: "retained-evidence", evidence_id: "..."}`.
For a CLI bundle, use an `evidence-file` source with its absolute path and the
parent Evidence ID. Views read the recorded capture; they never replay actions.
- `{kind: "summary"}` returns the same overview.
- `{kind: "browser-scenario", collection: "steps", step_indices: [2], artifacts: ["accessibility"], offset: 0, limit: 1}` returns selected recorded steps and artifacts.
- `{kind: "browser-scenario", collection: "events", event_kinds: ["response"], transaction_ids: ["request-2"], offset: 0, limit: 20}` pages selected events with original item indices.
Omitted filters select all; empty arrays select none. Pagination counts matching
retained rows. Exhausting a page does not establish capture completeness or
current application state.
Transaction pages use `{kind: "browser-scenario", collection: "transactions", limit: 20}`.
Their stable identity is the parent Evidence ID plus `transaction_id`; each row
keeps original event indices. Metadata events are returned by default. Select
`event_kinds: ["network-content"]` for recorded bodies and header values, or
`event_kinds: []` for identity and indices alone. A `step_indices` filter selects
a whole transaction when any retained event belongs to a selected step; this
is receipt attribution, not proof that the action caused the request.
For a large retained tree, request `{kind: "browser-scenario", collection: "text",
step_index: 10, artifact: "accessibility", offset: 0, limit: 2048}`. `dom` is also
supported. Offsets and limits count UTF-16 code units. The full artifact digest
and byte size remain attached to each page. Missing, truncated and unrequested
text stay explicit; source truncation counts are preserved without treating an
exhausted page as a complete capture.
Network summary counts include every retained transaction identity, including
those whose request event was dropped. Missing request events, conflicting
metadata and observed request failures have separate counts. `transactions` is
`null` when network observation was unrequested or its legacy selection is
unknown and there are no retained transactions; an observed empty inventory is
`0`. Full capture omissions remain available and each page carries source
completeness, dropped-event counts and omitted-transaction accounting.
+62
View File
@@ -0,0 +1,62 @@
# Bun standalone executables
`inspect-artifact` inventories embedded Bun module graphs in Mach-O `__BUN,__bun`,
PE `.bun`, ELF `.bun`, and appended trailers. `extract-artifact` writes their stored
module contents through the existing safe output tree. Neither operation executes
the executable or decompiles bytecode.
```sh
rea inspect-artifact ./hello --json
rea extract-artifact ./hello --json
```
In MCP, open the executable with `open_binary`, then call `inspect_artifact`.
Use `detail: "summary"` for large graphs and `inspect_analysis_view` to page retained
Evidence. The root metadata's `entry_point_logical_path` is the reader-owned
location of its entry module. Use it as an inventory `logical_paths` filter,
then read selected node fields with the returned content identity. This also
works for names mapped to indexed extraction paths. The complete Evidence stays
retained; no source-name normalization is needed in the caller.
The root reports the carrier, layout, module count, entry point, raw flags and
compile exec-argv. Each module retains its source name, loader and encoding values,
entry-point status, sizes and SHA-256. Sourcemaps, bytecode and module-info regions
are separate children. Source names such as `/$bunfs/root/main.js` remain in
metadata; extraction uses a relative path. Unsafe or non-UTF-8 names receive an
indexed path and retain their source spelling or bytes. Virtual names deeper
than 256 logical path parts also use an indexed path with an explicit limitation,
preventing unbounded path-tree work while retaining the source fact. Duplicate names remain
separate occurrences; ordinary extraction collision rules apply.
The recognized record shapes are the 36-byte Bun 1.3.3 layout and the 52-byte
Bun 1.3.9 layout. These labels identify structural layouts, not a detected compiler
version. Bun does not store an explicit revision identifier: unknown table sizes
and ambiguous known layouts are unsupported. A future layout that is byte-for-byte
compatible cannot be distinguished. Invalid pointers and truncated claimed sections
are malformed. An absent trailer without a named section does not establish a Bun
graph. Unknown enum values remain raw, with a null name.
Sourcemaps are stored Bun regions, not necessarily standalone JSON source maps.
Extracted contents retain their original encoding. Use JavaScript analysis only on
compatible source files; bytecode is retained as evidence, not decoded.
Module parsing reads exact metadata ranges rather than loading stored asset
bodies or whole pages around small pointers. A cache retains at most 256 KiB
and 1,024 ranges for one reader preparation. Cumulative uncached metadata reads
are limited to 256 MiB, checked before allocation or I/O. The module table,
decoded strings and combined logical path tree have separate admission checks;
at most 250,000 distinct path prefixes are admitted before inventory construction.
Stored bodies are range-streamed for hashing and extraction. Header/suffix observations are reused
only for the same admitted file state, with selected-path checks before publication.
See [limits and recovery](design/limits-and-recovery.md) for admission ceilings.
Synthetic tests cover the carriers and malformed declarations. Run
`node scripts/verify-bun-standalone.mjs` after `npm run build:cached` for local Bun
verification, and add `--docker` to compile a Linux fixture with `oven/bun:1.4.0`.
Bun and Docker are fixture producers only and are not installed by REA.
Layout references: [Bun 1.3.3 serializer](https://github.com/oven-sh/bun/blob/bun-v1.3.3/src/StandaloneModuleGraph.zig)
and [Bun 1.3.9 serializer](https://github.com/oven-sh/bun/blob/bun-v1.3.9/src/StandaloneModuleGraph.zig).
The current 52-byte record order can also be checked in the
[Bun 1.4.4 Rust serializer](https://github.com/oven-sh/bun/blob/bun-v1.4.4/src/standalone_graph/StandaloneModuleGraph.rs).
+192 -14
View File
@@ -51,6 +51,15 @@ module page. See
[JavaScript application workflows](javascript-application-workflows.md) for
views, feature traces and comparisons that take the same saved Evidence.
Add `--timings` to a command to write one JSON timing record to stderr. For
example, `rea inspect-elf-notes program --json --timings > result.json` keeps
stdout as a parseable result and writes
`{"rea_timings":{"version":1,"command_ms":42}}` to stderr. `command_ms`
measures CLI command dispatch and result delivery; it is not provider-only or
analysis-only time. The flag is off by default, and the record omits stages
that REA did not measure. Root version reporting does not dispatch a command
and has no command timing record.
## JSON Lines record output
Use `--format jsonl` to consume row-oriented results one record per line:
@@ -73,9 +82,14 @@ arbitrary nested graph array.
A top-level array emits its elements in source order. An object must have one
clear `rows`, `items`, `records`, or `occurrences` array, directly or under
`page`. Evidence uses the same boundaries inside `normalized_result`.
An arbitrary report or a scalar selection is refused with an actionable error;
use `--format json` for a complete document. If several collections exist,
select one with `--filter-output`, for example `normalized_result.rows`.
Any other selection is refused before a record is written, including an
arbitrary report, a scalar, a nested array elsewhere, and a columnar object such
as the `inspect-sqlite-database --table` `normalized_result.rows`
(`{columns, values}`). The refusal is the caller error `invalid_request`
(`invalid_input`) and names the selection and its observed shape; the analysis
itself succeeded, so use `--format json` for the complete document. If several
collections exist, select one with `--filter-output`, for example
`normalized_result.rows` for an analysis view.
Object collections finish with a control record:
@@ -151,6 +165,15 @@ into the current shell:
eval "$(rea completions bash)"
```
For zsh, initialize completion before loading the hook. If your shell already
runs `compinit`, place the hook after that existing initialization:
```zsh
autoload -Uz compinit
compinit
eval "$(rea completions zsh)"
```
The Bash hook supports macOS system Bash 3.2. It uses optional completion
features when the shell provides them and falls back to portable registration.
Completion includes standard global options and the active command's options;
@@ -236,6 +259,28 @@ Formats 2, 3 and 4 retain header, directory and integrity facts. Compact deliver
keeps complete Evidence in the requested bundle. See [Godot PCK](godot-pck.md)
for embedded packs, batch queries and unknown encrypted coverage.
Inspect a UnityFS AssetBundle without running Unity:
```sh
rea inspect-artifact content.bundle --detail summary --evidence_output evidence.json --json
rea extract-artifact content.bundle --json
```
Format versions 6 through 8 retain header, block and directory facts with
none/LZ4/LZ4HC block decompression. See [UnityFS](unityfs.md) for encryption
and LZMA coverage boundaries.
Inspect an ESP32-family app or bootloader image without esptool:
```sh
rea inspect-artifact firmware.bin --json
rea extract-artifact firmware.bin --json
```
The inventory lists each segment with its ESP-IDF load classification, the
checksum and SHA-256 results, the descriptor and any Secure Boot v2 signature
blocks. See [ESP images](esp-image.md) for recognition, coverage and refusals.
Inspect a Node.js SEA carrier without running it:
```sh
@@ -246,6 +291,42 @@ rea extract-artifact ./application --json
See [Node.js SEA](node-sea.md) for supported layouts, script and asset paths,
fuse observations, and the real-fixture verification lane.
Inventory and extract Intel HEX or S-record regions:
```sh
rea inspect-artifact ./firmware.hex --json
rea extract-artifact ./firmware.hex --json
```
See [Intel HEX and S-record images](hex-records.md) for recognition, region
names, metadata and limits.
Inspect and extract stored U-Boot legacy uImage payloads and components:
```sh
rea inspect-artifact ./firmware.bin --detail summary --evidence_output firmware.json --json
rea extract-artifact ./firmware.bin --json
```
See [U-Boot uImage](uimage.md) for verified CRCs, physical component ranges,
unknown names, resource limits and retained views. Compressed bytes stay stored.
`inspect-artifact` and `extract-artifact` also read ZIP members compressed with
Zstandard (standard method 93). They retain the shared ZIP CRC, declared-size,
overlap and archive expansion checks. The native streaming decoder keeps the
existing 128 MiB Zstandard window cap; frames requiring a larger window are
refused. Deprecated method 20 and other unregistered ZIP codecs remain unsupported.
Inventory and extract U-Boot FIT images:
```sh
rea inspect-artifact ./boot.itb --json
rea extract-artifact ./boot.itb --json
```
See [U-Boot FIT images](fit-images.md) for recognition, data sources, hashes
and limits.
Inspect local model declarations without loading weights:
```bash
@@ -438,7 +519,13 @@ 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, JADX, and Kuna, run
reasons in `details.rejections`. Each rejection names its `origin`: `availability`
entries describe local readiness failures, including missing configuration or an
invalid existing registration; they do not establish target support. `target`
entries record a refused kind, format, architecture, or role. An availability-only
message describes the recorded rejections without claiming that every provider
is unconfigured or that target support is known.
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
@@ -480,6 +567,11 @@ Dispatching a provider metadata write invalidates the active session's snapshot
even if its reply fails: the provider may already have applied the write.
Close and reopen the target before importing or saving another snapshot.
Saved snapshots include only cache entries whose subject identifies the selected
target. Unbound observations and observations of child artifacts remain available
in the open session and its Evidence bundle; they are excluded from the target's
saved replay entries without changing their subjects.
Snapshots retain eligible target-scoped question histories in full, including
mutation Evidence recorded while another target was active. Observations and
related questions must still belong to the saved target. If those dependencies
@@ -535,6 +627,14 @@ rea compare /absolute/path/to/evidence/left.json /absolute/path/to/evidence/righ
rea compare left.json right.json --record_pairs '[{"left_evidence_id":"ev_<left-sha256>","right_evidence_id":"ev_<right-sha256>"}]' --json
```
Migration: replace `rea compare-bundles` with `rea compare`; the former command
has been removed. The MCP tool remains `compare_bundles`.
`rea compare` compares records by Evidence identity and explicit pairs. It does
not read artifact contents: the inventories of two builds are unresolved
records, or one opaque change when you pair them. Use `compare-artifacts`,
described at the end of this section, to compare their contents.
`--record_pairs` supplies an explicit JSON array of observation pairs, matching
MCP `compare_bundles.record_pairs`. Pair IDs must exist on their named sides and
be one-to-one. Without pairs, one-sided membership remains unknown; REA does
@@ -558,6 +658,24 @@ 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.
Compare two artifact inventories with `compare-artifacts`. It takes the same
`left` and `right` input as MCP `compare_artifacts`: complete Evidence, or an
`evidence-file` source with an optional `evidence_id` that selects one record
from a bundle. Relative paths resolve from the working directory:
```bash
rea inspect-artifact old.zip --json > old.json
rea inspect-artifact new.zip --json > new.json
rea compare-artifacts '{"left":{"kind":"evidence-file","path":"old.json"},"right":{"kind":"evidence-file","path":"new.json"}}' --json
```
A one-shot command keeps no session Evidence, so it refuses a
`retained-evidence` source with `details.reason: "missing"`. Select the record
from a saved bundle instead.
For an artifact summary selected from a bundle, include its complete parent
inventory in the same bundle. The command resolves that parent from the
authenticated file records; a summary-only file cannot supply missing facts.
## Import historical source
Historical source inventories preserve exact filenames, including literal backslashes
@@ -733,8 +851,18 @@ 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`
then to `127.0.0.1` and an ephemeral port. A bind outside loopback requires
`MCP_ALLOWED_HOSTS` or `--allowed-hosts`, a comma-separated list of client host
names or IP addresses without URLs or ports. For example:
```sh
rea mcp --http --host 0.0.0.0 --allowed-hosts 127.0.0.1,rea.lan
```
Requests with a different `Host` or browser `Origin` receive `403`; a missing
`Origin` is accepted. The announced client URL uses the bound hostname when
admitted, otherwise the first declared hostname, with the actual bound port.
It 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
@@ -772,9 +900,18 @@ 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
`MCP_PORT`, then `127.0.0.1` and an ephemeral port. A non-loopback bind requires
`MCP_ALLOWED_HOSTS` with the same hostname rules and Host/Origin gates as above.
`environment-serve` uses this environment setting; `--allowed-hosts` belongs to
`rea mcp --http`. For example:
```sh
MCP_ALLOWED_HOSTS=127.0.0.1,rea.lan rea environment-serve manifest.json --evidence capture.json --host 0.0.0.0
```
`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
like a blank `MCP_HOST`. The admitted client URL is written to stderr as one JSON log line
(`"msg":"MCP transport listening"`). See
[agent environments](agent-environments.md) for what the state and replay
return and do not establish.
@@ -921,8 +1058,8 @@ Malformed format values and token windows fail with `INVALID_OUTPUT_VALUE` in th
selected structured format. Token limits and offsets must be nonnegative safe
integers; zero selects an empty window. These checks run before command execution. `--json` is indented on a terminal and compact when piped or
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.
through `jq .` for indented files. A formatting refusal exits nonzero even when
the underlying operation succeeded.
`--format md` escapes backslashes, pipes, and inline Markdown syntax in table
headers and cells so source text is displayed literally, and renders cell line
@@ -934,6 +1071,42 @@ values instead of replacing them with an object label. Table widths are measured
iteratively, so an admitted row page is not limited by the JavaScript function
argument count.
Markdown refuses selected NUL characters and unpaired UTF-16 surrogates because
renderers or UTF-8 output would substitute them. TOON refuses selected unpaired
surrogates for the same UTF-8 reason. Use JSON or YAML to retain those values.
An authored replacement character and valid supplementary characters are not
treated as malformed.
`--format csv` and `--format tsv` export one selected row collection. Select an
exact array path with `--filter-output` and provide comma-separated direct
scalar columns with `--columns`; column order is the output column order:
```bash
rea inspect-analysis-view request.json --format csv \
--filter-output normalized_result.rows --columns name,address
```
The first line is a REA metadata record,
`# rea-delimited-v1 <JSON>`. It carries the selected path, view request, limitations and unknowns,
coverage, source coverage and completeness, command, and duration. A metadata
value of `null` means that the selected row collection did not provide that
fact; it does not mean complete coverage. The following line is the header.
CSV records use CRLF line endings; TSV records use LF. Cells containing the
delimiter, quotes, or line breaks are quoted and embedded quotes are doubled.
Values are emitted as UTF-8 without Unicode normalization. Missing and `null`
cells are empty; booleans and finite numbers use their ordinary text forms.
String cells and headers that begin with spreadsheet formula syntax are refused
with a structured error; unpaired surrogates in selected cells or headers are
also refused. JSON retains those values unchanged.
Delimited output does not flatten nested Evidence or nested field values.
It returns a structured error and a nonzero status if the filter does not
select exactly one row array, a row is not an object, or a selected cell is
nested or formula-leading. JSON remains the complete canonical output; use it
to retain fields outside the selected columns or preserve exact formula-leading
text. Token counting and token windows are not
available for CSV/TSV because slicing would corrupt records or metadata.
`--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`
@@ -952,10 +1125,10 @@ Cutter when available. This is separate from `--format json`, which selects the
CLI result representation; the global `--json` flag selects that same CLI
representation.
Cutter still accepts deprecated `--json=true` and `--json=false` compatibility
values. When both forms are present, `--json-output` takes precedence in either
argument order. Bare `--json` retains its global meaning of selecting JSON CLI
output formatting.
Cutter no longer accepts command-local `--json=true` or `--json=false`.
Replace these with `--json-output=true` or `--json-output=false`, respectively.
Combine `--json-output` with bare `--json` when both Cutter command output and
the CLI result should use JSON; either argument order is accepted.
| Status | Meaning |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -1083,3 +1256,8 @@ rea inspect-pe-load-config /absolute/path/to/application.exe --json
Reports TLS callbacks and size-covered load-config fields without execution.
Use `--max-callbacks` and `--max-file-bytes` to set read budgets. See
[PE TLS and load configuration](pe-load-config.md).
Bun standalone executables use the existing `inspect-artifact` and
`extract-artifact` commands to inventory and materialize embedded source,
sourcemaps and bytecode without running the executable. See
[Bun standalone executables](bun-standalone.md) for layout coverage and limits.
+155 -29
View File
@@ -6,6 +6,45 @@ for the reviewed setup transaction and [client IDs](installation.md#supported-ag
The versioned verification notes below describe their stated runs; live service
acceptance is verified only where explicitly recorded.
## Launchers and PATH
A client launched from a desktop app, IDE or service can inherit a different
`PATH` from your terminal. An absolute path to `rea-agents` does not resolve its
interpreter: the npm launcher's `#!/usr/bin/env node` still searches `PATH` for
Node. Running that command successfully in a terminal does not establish that
the client can launch it.
For JavaScript installations, setup registers the selected runtime
executable and REA script by absolute path. On POSIX, it prefers executable
`node` or `bun` and REA aliases on setup's `PATH` only when they resolve to the
same selected files. This preserves manager-owned aliases across version updates;
otherwise setup uses the selected paths directly. This also applies when setup
runs through a package runner: retain the selected cache entry and runtime while
the registration uses them. Clearing either makes startup fail without resolving
another package from the client's project. Restore the same installation before
repairing it; an unidentified registration remains untouched. See
[installation and recovery](installation.md#package-runners-and-global-installation).
Setup does not copy your ambient environment into client
settings. To refresh an older registration, preview
`rea setup --client <client-id> --skill=false --dry-run`, then run the same command
without `--dry-run` and approve the displayed changes. Setup preserves unrelated
settings, backs up changed configuration and leaves an aligned registration
unchanged. Restart the client after applying the update.
If a runtime manager removes the registered executable and no surviving alias
was available, doctor reports its identity as unknown and setup retains the
registration. REA does not infer that an arbitrary missing executable was Node
from its script argument. Back up the client's configuration, verify the absolute
path and supported version of the runtime you intend to use, then update only
the runtime command, preserving the REA script arguments and other settings.
Rerun setup to review the registration and restart the client.
`rea mcp doctor --json` tests the production MCP adapter using the runtime
executable and environment of the terminal running doctor. It does not launch
the client's configured command or reproduce the client's environment. If doctor
passes but the client disconnects, inspect the client's startup error and registered
launcher; see [verification scope](client-verification.md#launch-environment-verification).
## Runtime settings and client deadlines
`update_analysis_settings` changes curated defaults inside the running REA
@@ -40,6 +79,17 @@ Connect Fiddler Everywhere's MCP server separately for HTTP traffic debugging,
preserving your REA client entry. See the
[setup instructions and public skills](web-network-captures.md#fiddler-everywhere-mcp-and-public-skills).
## VS Code
`rea setup --client vscode` configures the default VS Code user profile's
`mcp.json`. Setup honors `VSCODE_PORTABLE` and `VSCODE_APPDATA` when they are
present in its environment. It cannot infer a running window's named profile
or `--user-data-dir`; configure that profile separately when needed.
`rea setup --client copilot_cli` instead configures Copilot's user
`mcp-config.json`. VS Code can forward eligible profile servers to Copilot
sessions; see the [VS Code MCP configuration reference](https://code.visualstudio.com/docs/agents/reference/mcp-configuration).
## GitHub Copilot CLI
Setup preserves an existing `tools` selection in the REA registration, including
@@ -170,14 +220,25 @@ and Claude Code reports that autocompact is thrashing. To avoid this:
`mcpServers.rea` entry in `~/.claude.json` (`$CLAUDE_CONFIG_DIR/.claude.json`
when that variable is set), then restart Claude Code. Setup keeps this
override.
- To remove entire tool families from the upfront catalog, run
`rea setup --client claude_code --tool-families <ids>` with the families the
workflow needs (see [the advertising scope contract](mcp-contracts.md#tool-family-advertising-scope)).
Out-of-scope tools are not advertised and their calls fail with the SDK's
disabled-tool error, so widen the selection when a task needs another
family. Setup writes the scope into the entry's `env` as
`REA_MCP_TOOL_FAMILIES`; rerun setup with a different selection to refresh
it, then restart Claude Code.
The sizes above come from REA's own `tools/list`. A live Claude Code session
against DeepSeek's API is unverified.
For a client whose stdio reader rejects the complete catalog frame, add
`"REA_MCP_OUTPUT_SCHEMA_PROFILE": "off"` to REA's `env` object and restart the
client. This omits only advertised output schemas; REA still validates complete
structured results against its canonical contracts. See [MCP output schema
For a client whose stdio reader rejects the complete catalog frame, set
`"REA_MCP_OUTPUT_SCHEMA_PROFILE": "compact"` to bound every advertised output
schema, or `"off"` to omit them, in REA's `env` object, then restart the client.
Both keep canonical result validation and complete structured results; `compact`
keeps a widened root shape and `off` advertises nothing. On catalogs large
enough that full input schemas alone approach the frame limit, also keep the
input profile at its `compact` default. See [MCP output schema
profiles](mcp-contracts.md#output-schemas).
## Kimi Code
@@ -210,6 +271,21 @@ registration but does not contribute to the derived tool timeout; raise
`toolTimeoutMs` to cover a longer selected JADX deadline.
This headroom is a practical default, not a guarantee for every analysis
duration. Setup preserves positive timeout values already in the `rea` entry.
Setup also forwards explicitly selected input/output schema profiles,
`REA_MCP_MAX_RESPONSE_BYTES`, `REA_MCP_MAX_INPUT_ELEMENTS`, provider paths and supported Ghidra, JADX and Kuna
settings. It also forwards explicit executable and resource selections for ADB,
apktool, packet capture, GDB/Rizin/objdump, Cutter, WABT, Wakaru, firmware and
signal tools, browser inspection, and pwntools/pwndbg. This includes their
supported prlimit overrides, Darwin Swift compiler/SDK/module-cache selections,
and compile timeout, logging level and explicitly configured reference-secret
patterns. A provider being unavailable does not discard its selected paths;
doctor reports its readiness separately. Explicit selections override discovered
defaults, including when setup runs again with a changed selection. Unrelated
environment variables, process ownership tokens and one-shot target paths are not
copied. For an explicitly configured startup target, see the
[initial-target settings](mcp-contracts.md#initial-target-at-startup). Existing
client environment overrides remain intact unless setup supplies the same key.
You can edit `startupTimeoutMs` and `toolTimeoutMs` there; doctor keeps positive
caller-selected values aligned and reports a non-blocking advisory when a tool
timeout is shorter than the known provider allowance.
@@ -267,6 +343,15 @@ Setup and doctor follow Qwen Code's tilde and working-directory-relative home
overrides. Qwen Code also discovers personal skills in `~/.agents/skills`,
where setup installs the bundled workflow.
If an existing direct-script registration fails with `env: node: No such file or
directory`, refresh it through setup as described under [Launchers and PATH](#launchers-and-path).
For an immediate Qwen-specific workaround, when Node is installed in
`/opt/homebrew/bin`, add `"PATH": "/opt/homebrew/bin:${PATH}"` to that server's
existing `env` object and restart Qwen. Qwen expands `${PATH}` from its parent
environment; other clients can use different substitution syntax. Qwen's stdio
launcher inherits the parent `PATH` and applies server overrides; a reduced
parent environment does not establish that Qwen removed Homebrew from it.
## Antigravity
Antigravity 2.0 discovers personal skills in `~/.gemini/config/skills`.
@@ -418,17 +503,51 @@ comments and unrelated settings. It resolves that file from `HERMES_HOME`, else
from the platform default Hermes itself uses — `%LOCALAPPDATA%\hermes` on
Windows, `~/.hermes` elsewhere — including any `HERMES_DATA_DIR_SUFFIX`. Hermes
connects an entry unless `enabled` is false, so setup states `enabled: true`.
Aliases whose anchor is defined in the `rea` entry retain their original resolved
values when setup refreshes or uninstall removes that entry. Setup does not
redirect another server's alias to REA's new launcher or policy.
This also covers an anchor on the removed registration key. References to
definitions outside the entry keep sharing the original value, including when
another definition later reuses the same anchor name.
Hermes personal skills install under the active Hermes home's `skills` directory.
Setup, doctor and uninstall follow the root's `active_profile` selection, as
plain Hermes CLI commands do. An explicit `HERMES_HOME` pointing to
`profiles/<name>` selects that named profile directly. An invalid, missing or
deleted sticky profile is reported instead of writing into the default home;
it also remains an unresolved skill selection, so setup cannot report a
successful empty installation. Overrides nested beneath the native Hermes home
use that native home's sticky selection and profile root together, matching
[Hermes's root rules](https://github.com/NousResearch/hermes-agent/blob/748c79a1c6873124d84071cdabb4062a75913e1f/hermes_constants.py#L83).
Repair the profile or run `hermes profile use default` before retrying.
Setup, doctor and uninstall share REA's sticky-profile resolver.
A custom `HERMES_HOME` outside the platform default home
reads its own `active_profile`. An override physically inside the default home
uses that default home's sticky selection and profile root together, including
when the final override directory does not yet exist.
For example, with `HERMES_HOME=~/.hermes/sub` and `~/.hermes/active_profile` set
to `coder`, setup selects `~/.hermes/profiles/coder/config.yaml` and that
profile's skills directory. It does not read `~/.hermes/sub/active_profile`.
Without an outer named selection, this override uses `~/.hermes/sub/config.yaml`.
Use a home outside the platform default tree for an independent sticky selection.
This describes REA's current routing, not full Hermes CLI equivalence.
At Hermes commit `748c79a1`, the
[sticky lookup](https://github.com/NousResearch/hermes-agent/blob/748c79a1c6873124d84071cdabb4062a75913e1f/hermes_cli/main.py#L612-L632)
also reads the outer selection, but
[`resolve_profile_env`](https://github.com/NousResearch/hermes-agent/blob/748c79a1c6873124d84071cdabb4062a75913e1f/hermes_cli/profiles.py#L2431-L2461)
resolves it beneath the configured `HERMES_HOME`. For nested overrides, confirm
the profile Hermes actually uses and point `HERMES_HOME` directly at that
`profiles/<name>` directory before setup. Compatibility is tracked in
[#3939](https://github.com/morluto/rea/issues/3939).
REA resolves existing ancestor directories before checking physical containment,
including symlinks and junctions, even when the override directory does not exist.
An override beneath a symlinked default home therefore uses the default home's
sticky selection. If `~/.hermes/link` points outside the default home,
`HERMES_HOME=~/.hermes/link/new` instead uses that override root, whether or not
`new` exists. Previewed destinations retain the configured path spelling.
An unreadable path or dangling alias leaves the home unresolved; repair that path
before configuring Hermes. Inspect setup's previewed destinations before applying
changes.
An explicit `HERMES_HOME` pointing to `profiles/<name>` selects that named
profile directly, bypassing sticky selection. An invalid, missing or deleted
sticky profile is reported instead of writing into the default home; repair the
profile or run `hermes profile use default` before retrying. It also remains an
unresolved skill selection, so setup cannot report a successful empty installation.
REA follows `HERMES_HOME` whitespace trimming, environment-variable expansion,
and home expansion before resolving that profile. Setup previews the resolved
configuration and skill destinations; doctor and uninstall use those same paths.
@@ -445,10 +564,12 @@ installs its skill copy there.
## Factory Droid
For [Factory Droid](https://docs.factory.com/harness/mcp), setup writes
`mcpServers.rea` into the user-level `~/.factory/mcp.json`. Entries carry
`command`, `args`, and `env`. Droid discovers personal skills from
`~/.factory/skills` ([skills](https://docs.factory.com/harness/skills)), so
setup installs its skill copy there.
`mcpServers.rea` into the user-level `~/.factory/mcp.json` (the
`FACTORY_HOME_OVERRIDE` override replaces the home that contains `.factory`).
Entries carry `command`, `args`, and `env`. Droid discovers personal skills
from `~/.factory/skills` ([skills](https://docs.factory.com/harness/skills),
following `FACTORY_HOME_OVERRIDE` when set), so setup installs its skill copy
there.
## Trae
@@ -496,9 +617,10 @@ the fallback file untouched. Existing REA environment overrides are preserved
when refreshing its command. A malformed or unreadable fallback file fails setup instead of
being silently suppressed; repair or remove it and rerun. Uninstall removes an
REA-owned `rea` entry from both the native table and the fallback, backing up
each changed file, so an emptied native table cannot load a leftover fallback
registration; other fallback servers, settings and a foreign `rea` entry are
kept. ZCode disables a
each changed file. If removing the last native server would activate a retained
fallback server, uninstall refuses before changing either file; review the
fallback configuration before retrying. Other fallback servers, settings and a
foreign `rea` entry are kept. ZCode disables a
server with `enable: false` on its entry; doctor reports such a registration
as stale, and rerunning setup removes the flag to repair it. Native configuration
uses strict JSON; setup refuses comments, trailing commas and a BOM rather than
@@ -521,10 +643,16 @@ boundaries. FreeBuff MCP loading and skill discovery have not been verified
with an installed native FreeBuff client/version; filesystem tests cover REA's
editing, discovery, and ownership behavior only. Automatic applicability
requires the FreeBuff profile directory even when the shared MCP file exists.
When uninstall cannot establish FreeBuff or another shared-storage reader from
product discovery, a malformed or unreadable shared MCP file is retained
unchanged and does not stop other REA removals, including `--purge-data`. When
FreeBuff or ZCode product applicability is established or unresolved, the same
malformed shared file stops uninstall before removals. See
[Diagnose, update, and remove](installation.md#diagnose-update-and-remove).
FreeBuff is main-only and is not in a published release yet; npm 6.7.0 is the
latest. `rea setup --client freebuff` against `@latest` reports an unsupported
client until a release containing it is published.
FreeBuff setup support requires `rea-agents@6.8.0` or later. Older versions
reject `rea setup --client freebuff` as an unsupported client. See the
[installation guide](installation.md#supported-agents) for client availability.
## DeepSeek Harness
@@ -591,8 +719,10 @@ become active again. Malformed applicable files block setup before changes.
Grok Build loads `[mcp_servers.rea]` from `$GROK_HOME/config.toml`, or from
`~/.grok/config.toml` when `GROK_HOME` is unset or empty. Setup edits that server
table, `[mcp_servers.rea.env]`, and a root `disabled_mcp_servers` entry that
names `rea`. It sets `startup_timeout_sec = 30` and leaves every other name
in that list. The shared skill installed under `~/.agents/skills` is already
names `rea`. It defaults `startup_timeout_sec` to 30 seconds, preserves an
existing positive timeout, and leaves every other name in that list.
[Grok supports longer startup timeouts](https://docs.x.ai/build/features/mcp-servers)
for cold package-runner launches. The shared skill installed under `~/.agents/skills` is already
on Grok Build's skill path.
Grok Bot (`grok_bot`) is detected from `~/.grokbot`, or from `SAND_DATA_ROOT`
@@ -622,10 +752,6 @@ can override an inherited disable. Lower files and other server entries remain
unchanged; a legacy server named `servers` that conflicts with the native table
requires manual repair before setup can write.
When Hermes aliases refer to an anchored REA entry, refreshing or removing REA
retains the aliases' original resolved values. Setup does not redirect another
server's alias to REA's new launcher or policy.
With no client selected, the interactive skill choice targets the shared
`~/.agents/skills` copy. Selecting a client targets its personal destination
when supported. Use `rea setup --skill-client shared --skill` for the shared
+18
View File
@@ -11,6 +11,16 @@ and provider lanes. Each record below states its host, client version, model
fixture, and remaining coverage; a native-client run with a loopback model does
not establish live model-service acceptance.
## Launch environment verification
`rea mcp doctor --json` starts the production MCP adapter with the current runtime
executable and environment. A healthy result establishes that adapter's
initialization, discovery and target-free request flow; it does not verify a
client's configured launcher or its inherited environment. Test the generated
registration through the actual client, including a reduced `PATH` when checking
desktop or service startup. Record the client version and launch environment
separately from terminal doctor results. See [launcher troubleshooting](client-configuration.md#launchers-and-path).
## Published Pi code-mode renderer limit
A separate probe of the published `@earendil-works/pi-codemode` 1.1.0 and 1.2.0
@@ -53,6 +63,14 @@ skill setting; Hermes discovers it through the selected `HERMES_HOME`.
Set `REA_VERIFY_HERMES_STICKY_PROFILE=1` to exercise native Hermes selection of
a named sticky profile with `HERMES_HOME` still pointing to its root.
For Qwen on POSIX, set `REA_VERIFY_QWEN_REDUCED_PATH=1` and select its JavaScript
entry point with `REA_VERIFY_QWEN_COMMAND` to test a restricted client environment.
Setup retains the caller's `PATH`; the native Qwen `chat` or `call` run then uses
an isolated `PATH` containing only Bash for the shell-tool fixture. The lane
checks that `node`, `npm` and `npx` cannot be found and uses the generated REA
registration unchanged. Its receipt records `reducedPath`, `clientPath` and
`registrationCommand`; the option alone does not establish a passing native run.
The Qwen lane also supports native Windows (verified with Qwen Code 0.25.1 and
Node 24.19.0 for both `chat` and `call`). With Node 24.18.0, the same `call`
journey reached full Evidence readback but the client aborted during exit with
+17
View File
@@ -169,6 +169,7 @@ cannot partially apply. Clients coordinating writes can supply
| `capture.decoder_old_generation_mib` | Next owned capture decoder |
| `javascript.analysis_timeout_ms`, `javascript.max_heap_mb` | Next source analysis / new JavaScript worker |
| `wasm.command_timeout_ms` | Next WABT operation |
| `native.matching_representation_bytes` | Next `match_native_functions` request |
### Precedence and lifetime
@@ -243,6 +244,8 @@ Inspection then reports the runtime value while retaining the launch error.
Reset exposes the invalid launch state again; it does not repair or replace it
with the built-in default. Provider availability and execution must resolve the
same effective setting so readiness changes along with repair and reset.
`REA_NATIVE_MATCHING_REPRESENTATION_BYTES` is validated the same way, by
`match_native_functions` alone.
## Keep a fixed ceiling honest
@@ -375,3 +378,17 @@ The [verification report](../verification/runtime-analysis-settings.md) separate
public MCP checks, simulated provider coverage, real Ghidra execution, and
measured task costs. It does not establish real-provider behavior for every
editable setting or active worker telemetry.
## Bun standalone module graphs
`MAX_BUN_MODULE_COUNT` admits at most 100,000 module records.
`MAX_BUN_RETAINED_BYTES` admits at most 256 MiB of serialized graph payload and
separately bounds retained entry metadata. Physical metadata read work is also
limited to 256 MiB per preparation, including repeated uncached ranges. A
256 KiB / 1,024-entry exact-range cache avoids full-page amplification. The
combined logical path tree admits at most 250,000 distinct prefixes; this is
checked before adding nodes, with shared prefixes counted once. The shared
artifact expansion budget also bounds the sum of referenced member lengths. Refusals name the boundary.
There is no runtime override; additional host memory or `NODE_OPTIONS` does not
raise these ceilings. Use a smaller producer fixture or a separately reviewed
reader for larger graphs. No partial extraction is claimed on admission failure.
+8 -6
View File
@@ -53,7 +53,7 @@ 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.
`get_evidence_bundle` 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`,
@@ -135,11 +135,13 @@ 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.
select up to 100,000 entries and 64 MiB. A separate 32 MiB representation
budget bounds retained rows, paths and facts before growth. Each retained path
is charged at the larger of its UTF-16 heap size and its escaped JSON size, so
typical macOS bundle paths fit about 20,000 rows, and control-character paths
fewer. 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
+110
View File
@@ -0,0 +1,110 @@
# .NET single-file bundles
Use `rea inspect-artifact /absolute/path/host --json` to inventory an ordinary
.NET single-file host and `rea extract-artifact /absolute/path/host --json` to
materialize its members into a fresh, REA-owned output directory. With a host
selected through `open_binary`, the corresponding MCP tools are
`inspect_artifact` and `extract_artifact`. No .NET installation is needed for
inspection or extraction.
For a compact inventory, call `inspect_artifact` with `detail: "summary"`,
then use `inspect_analysis_view` with the returned `parent_evidence_id`.
Inventory occurrence pages accept `logical_paths`, `occurrence_ids`, selected
`fields`, `offset`, and `limit`; node pages accept batches of `artifact_ids`
to retrieve expanded-byte digests. Include `format_metadata` and
`source_location` when member declarations and stored extents matter. Identity
fields survive projection, and the complete inspection Evidence stays retained.
REA detects the apphost marker and its preceding header offset from PE, ELF,
and thin Mach-O bytes, regardless of filename. An unbundled apphost's zero
offset remains an ordinary native artifact. Universal Mach-O slice inventory
keeps its existing behavior; bundled contents inside slices are not expanded.
When a native file has a recognized PyInstaller CArchive, apphost-marker
scanning stops before its payload. A .NET helper stored inside that archive
does not replace the outer container's format; an outer .NET host can still
contain a PyInstaller helper as a member.
## Supported layout
| Header | Producer generation | Member encoding |
| ------ | ---------------------------------- | --------------------------- |
| 1.0 | .NET Core 3.x | Uncompressed |
| 2.0 | .NET 5 | Uncompressed |
| 6.0 | .NET 6 and later using this layout | Uncompressed or raw DEFLATE |
Versions, minor versions, and flags outside this set are refused explicitly;
they do not silently become an ordinary PE or a successful empty inventory.
Flags 0 and the v2+ compatibility flag 1 are admitted. Unknown file-type bytes
are retained with a limitation, rather than treated as executable authority.
Encrypted/protected wrappers and recovering their payloads are outside this
reader's scope.
The host keeps its whole-file SHA-256. Each embedded file gets its expanded-byte
SHA-256, path, declared size, compressed size, and `format_metadata` declaration
(`major_version`, `minor_version`, `file_type`). Its `source_location` describes
the stored host extent, including the compressed length when applicable.
The root manifest's `root_format` is `dotnet-bundle`; the root content node
still records its native PE/ELF/Mach-O format. A file-type declaration or `.dll`
suffix does not establish a valid assembly. Inspect an extracted component
explicitly with the managed tools to establish PE/CLI facts.
## Admission and containment
Metadata is range-read with a 64 KiB cache. Policy budgets are 16 MiB of
manifest metadata, 100,000 files, 64 KiB per UTF-8 string, 512 MiB of stored or
expanded bytes per file, 256 path parts per member, 250,000 distinct in-memory
path-tree nodes, and 2 GiB of aggregate expanded bytes. The node budget counts
shared directory prefixes only once. These are REA
resource policies, not limits imposed by Microsoft's format. Marker scanning
streams 64 KiB chunks and reuses completed probe facts during extraction;
ordinary native files without a marker incur one extra
read pass before host hashing.
Extraction hashes the whole host again through the same descriptor used to read
members and compares it with the inventory's root digest before creating an
output directory. This adds a full-host read pass to extraction, including when
the embedded members themselves are small.
Malformed/truncated headers, unsafe or conflicting paths, overlapping member
ranges, members crossing the manifest, contradictory configuration extents,
invalid UTF-8, corrupt/trailing compressed data, and incorrect expanded sizes
fail before output publication. Source descriptor/path identity is checked
during reading; extraction verifies the host digest and member bytes against
the inventory. Existing output roots are never overwritten. Cancellation and
failures release owned streams/descriptors through the shared extraction
rollback scope.
## Reproduce producer fixtures
The source-owned generator uses the installed .NET 8 SDK's **Microsoft
HostModel** producer to emit x64 v1, v2, plain v6, and compressed v6 bundles
for Windows, Linux, or macOS. It does not run generated hosts or download runtime packs. Supply an
SDK apphost template from
`packs/Microsoft.NETCore.App.Host.<rid>/<version>/runtimes/<rid>/native/apphost`
(`apphost.exe` on Windows). Pass `windows` (the default), `linux`, or `osx`
as the optional third generator argument to match that template.
```bash
dotnet build scripts/fixtures/dotnet-bundle/BundleFixture.csproj -c Release --configfile scripts/fixtures/dotnet-bundle/NuGet.Config -o /absolute/path/producer -p:BaseIntermediateOutputPath=/absolute/path/producer-obj/
dotnet /absolute/path/producer/BundleFixture.dll /absolute/path/apphost.exe /absolute/path/absent-bundles-directory
rea inspect-artifact /absolute/path/absent-bundles-directory/net8-compressed/Probe.exe --json
rea extract-artifact /absolute/path/absent-bundles-directory/net8-compressed/Probe.exe --json
```
The generator writes `oracle.json` beside each host. An independent C#
`BinaryReader`/`DeflateStream` pass records version, member types and stored
extents, then compares every expanded member digest with its source file.
Compare those records with inspection Evidence and the extracted bytes.
This verifies Microsoft's compression writer separately from synthetic parser
fixtures; it is not evidence that the bundled host executes on a target runtime.
Deterministic boundary and public-entrypoint coverage:
```bash
npm run test:focused -- tests/boundary/filesystem/dotnetBundleArtifacts.test.ts tests/acceptance/dotnetBundleJourney.test.ts
```
Layout references: Microsoft's [manifest writer](https://github.com/dotnet/runtime/blob/v8.0.22/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs),
[file entry writer](https://github.com/dotnet/runtime/blob/v8.0.22/src/installer/managed/Microsoft.NET.HostModel/Bundle/FileEntry.cs),
[apphost marker handling](https://github.com/dotnet/runtime/blob/v8.0.22/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs),
and [compression producer](https://github.com/dotnet/runtime/blob/v8.0.22/src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs).
+7
View File
@@ -75,6 +75,13 @@ DOM node indices retain their snapshot positions. Invalid rows are omitted with
completeness diagnostics, so `total_nodes` can exceed the retained node count
and a parent index can refer to an omitted source node.
`dom.node_value_length_unit` is `utf8-bytes`: each node's `node_value_length`
counts the bytes needed to encode its value as UTF-8, not characters. Web
observations instead declare `utf16-code-units`. These existing measurements
are preserved; the unit is reported once for the whole DOM, without retaining
text values. Historical captures without the unit leave it unknown; reading
them does not infer a unit or convert their stored lengths.
Script metadata retains its execution-context frame ID when CDP supplies one and
records admission separately in `frame_scope`. An `authorized` scope refers to
the observed document generation; `unknown` retains the known frame ID without
+4 -8
View File
@@ -691,12 +691,8 @@
"type": "object",
"properties": {
"logical_path": { "type": "string" },
"declared_sha256": {
"anyOf": [{ "type": "string" }, { "type": "null" }]
},
"calculated_sha256": {
"anyOf": [{ "type": "string" }, { "type": "null" }]
},
"declared_sha256": { "type": ["string", "null"] },
"calculated_sha256": { "type": ["string", "null"] },
"unpacked": { "type": "boolean" }
},
"required": [
@@ -705,7 +701,7 @@
"calculated_sha256",
"unpacked"
],
"additionalProperties": false
"additionalProperties": {}
},
{
"type": "object",
@@ -731,7 +727,7 @@
"calculated_md5",
"unpacked"
],
"additionalProperties": false
"additionalProperties": {}
}
]
}
+316
View File
@@ -0,0 +1,316 @@
# ESP images
REA reads ESP32-family firmware images through `inspect-artifact` /
`inspect_artifact` and `extract-artifact` / `extract_artifact`. OTA downloads,
app partitions and second-stage bootloaders are all ESP images. Reading is
static: no esptool, device or flash access is needed, and no code is run or
disassembled.
```sh
rea inspect-artifact ./firmware.bin --json
rea inspect-artifact ./ota.bin --detail summary --evidence_output evidence.json --json
rea extract-artifact ./firmware.bin --json
```
For MCP, open the file with `open_binary`, then call `inspect_artifact`. The
summary's `root_format_metadata` holds the image facts. Use its
`parent_evidence_id` with `inspect_analysis_view` to select segment rows.
`extract_artifact` writes one file per segment and per signature block.
For agent sessions, advertise the `session,artifact,application` tool families
and consider setting both `REA_MCP_INPUT_SCHEMA_PROFILE` and
`REA_MCP_OUTPUT_SCHEMA_PROFILE` to `compact`. The output profile bounds each
advertised output schema to 4,096 bytes by relaxing nested client validation;
REA still validates complete results against the canonical contracts. Pair
this with retained summaries and selected inventory views to limit the context
needed for one question. See [MCP contracts](mcp-contracts.md) for the profiles
and their client compatibility tradeoffs.
The layout facts follow ESP-IDF v6.1 (`esp_app_format.h`, `esp_app_desc.h`,
`esp_bootloader_desc.h`, `esp_image_format.c`, the ROM `secure_boot.h`
headers and `docs/en/security/secure-boot-v2.rst`) and esptool v5.6.0
(`bin_image.py`, `cmds.py`, `loader.py`, espsecure).
## Recognition
The container format is `esp-image`. A file is an ESP image when its bytes
show all of these; the file name does not matter:
- magic `0xE9` at offset 0 and 1 to 16 segments. A count of 0 is valid but
loads nothing, and accepting it would admit x86 programs that begin
`E9 00`;
- a flash mode and flash speed code that ESP-IDF's enums define;
- a `hash_appended` byte of 0 or 1, as esptool requires;
- when the file holds the first segment header, a segment length that is a
multiple of 4.
Later segments, the checksum and the digest are integrity facts. A truncated
download is still an ESP image, with its integrity reported as unavailable.
| Input | Outcome |
| --------------------------------------------------- | ---------------------------------------------------------------- |
| ESP8266 image (v1 or v3): same magic, 8-byte header | Refused: "ESP8266 firmware images are not supported…" |
| Flash-encrypted image (ciphertext) | Not recognized: the bytes carry no magic. Unknown, not malformed |
| ESP8266 v2 image (magic `0xEA`) | Not recognized |
An ESP8266 image has its first segment header at offset 8, and that segment
loads into ESP8266 DRAM, IRAM (Arduino's eboot links at `0x4010F000`) or the
IROM flash window, where v3 and Arduino app images begin. In an ESP32-family
header the same bytes hold `wp_pin` and the drive settings, which esptool and
ESP-IDF write as `0xEE` and zeros. Inside another container, an ESP8266 image
is classified as a plain file.
Recognition cannot exclude every file that starts with an x86 near jump
(`0xE9`), such as a DOS `.com` program. An explicit `--target-format dos-com`
or `raw-binary` selection skips ESP recognition.
## Image facts
Root `format_metadata` has `kind: "esp-image"`:
| Field | Label | Meaning |
| ------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------- |
| `header` | observed | Every `esp_image_header_t` field, with ESP-IDF's names, for example `entry_addr`, `chip_id`, `min_chip_rev_full` |
| `chip` | derived | `target`, `isa` and the table's `source` (`ESP-IDF v6.1`) from `chip_id`; `null` for an ID the table lacks |
| `checksum` | derived | `offset`, `stored`, `computed` and `status`: `valid`, `invalid` or `unavailable` |
| `appended_sha256` | derived | The digest `hash_appended` adds: `offset`, `stored`, `computed` and `status`, including `not-appended` |
| `image_end` | derived | End of the checksum block and any appended digest; `null` when the file ends before it |
| `signature_sector_offset` | derived | The Secure Boot v2 signature sector, when it holds at least one valid block |
| `undescribed_trailing` | derived | Byte ranges after the image that nothing describes; empty when every byte is described |
| `descriptor` | observed | `esp_app_desc_t` or `esp_bootloader_desc_t` fields, with ESP-IDF's names, and the descriptor's file `offset` |
The descriptor's `kind`, derived from its magic, classifies the image as an
`app` or a `bootloader`. Without a descriptor the role is unknown.
The ISA comes from `chip_id`, never from the series letter: ESP32-S31 is
RISC-V. The chip table covers every `esp_chip_id_t` in ESP-IDF v6.1:
| `chip_id` | Target | ISA | `chip_id` | Target | ISA |
| --------- | --------- | ------ | --------- | ---------- | ----- |
| `0x0000` | `esp32` | xtensa | `0x0012` | `esp32p4` | riscv |
| `0x0002` | `esp32s2` | xtensa | `0x0014` | `esp32c61` | riscv |
| `0x0005` | `esp32c3` | riscv | `0x0017` | `esp32c5` | riscv |
| `0x0009` | `esp32s3` | xtensa | `0x0019` | `esp32h21` | riscv |
| `0x000C` | `esp32c2` | riscv | `0x001C` | `esp32h4` | riscv |
| `0x000D` | `esp32c6` | riscv | `0x0020` | `esp32s31` | riscv |
| `0x0010` | `esp32h2` | riscv | | | |
Other IDs, for example esptool v5.6.0's ESP32-E22 (`0x1F`), have `chip: null`
and unclassified segments.
**Integrity.** The checksum is the XOR of every segment data byte, seeded with
`0xEF`, in the last byte of the next 16-byte block. The appended SHA-256 covers
every byte through the checksum. Both are facts, not admission rules: a
mismatch is reported with a limitation and the segments stay readable.
**Descriptors.** Both descriptors begin segment 0: ESP-IDF's bootloader reads
the app descriptor there, and esptool places the bootloader descriptor there.
Strings stop at the first NUL and are omitted, with a limitation, when they
are not valid UTF-8. The bootloader descriptor's magic is a single byte
(`0x50`), so its reserved bytes, which ESP-IDF zero-fills, must also be zero.
A `--ram-only-header` image puts RAM segments first, so its app descriptor is
not in segment 0 and its role is unknown. `mmu_page_size` keeps ESP-IDF's
name and value: the MMU page size as a base-2 logarithm, as
`esp_app_desc_t` declares it, so `16` means 64 KiB. It is `0` in images built
before ESP-IDF v5.4. `spi_flash_mode` is the next byte, which ESP-IDF v6.1
names, kept as stored and not interpreted; releases that reserve it leave it
`0`. A file can end inside the app descriptor: every field it holds in full
is kept, a field it cuts off is `null`, and `observed_length` gives the
descriptor bytes the file holds. The segment's truncation is reported as usual.
## Segments
Each header-declared segment is one entry named `segment-<index>.bin`, for
example `segment-00.bin`, so two builds pair segments by position. Its
`source_location` is the segment data in the image file. `format_metadata`
(`esp-image-segment`) records `index`, `load_addr`, `data_len`,
`header_offset` and `classification`.
`classification` follows ESP-IDF's bootloader (`should_map` and
`should_load` in `esp_image_format.c`) on a cold boot:
| Value | Meaning |
| ------------ | ------------------------------------------------------------------------------------------------- |
| `mapped` | Inside the chip's IROM, DROM or, where the MMU is per memory type, PSRAM range (`soc.h`) |
| `loaded` | `should_load` selects it: not mapped, at or above `0x10000000`. RAM ranges are not checked |
| `not-loaded` | Below `0x10000000`: the padding segments esptool writes at address 0, including `--secure-pad-v2` |
| `unknown` | The chip is unknown, or the mapping depends on the bootloader's MMU page size |
`loaded` does not mean the bootloader accepts the segment. Before loading,
ESP-IDF's `verify_load_addresses` rejects the image when a loaded segment is
not entirely in the chip's DRAM, IRAM, RTC memory or SPM, or overlaps the
bootloader's own stack, data or loader code. For example, an ESP32-C6
segment at `0x43000000` is `loaded` here and rejected there. REA models no
RAM ranges.
Padding segments are inventoried and extractable, but are never load regions.
When waking from deep sleep, ESP-IDF also skips RTC-memory segments; that
runtime case is not modelled. ESP32-C6 and ESP32-H2 map flash from
`0x42000000` through 256 pages of the bootloader's configured MMU page size,
which no image records. The app descriptor's page size describes the app's
build, not the bootloader's. With page sizes from 8 KiB (which the hardware
supports and esptool builds for) to 64 KiB, segments from `0x42200000` to
`0x43000000` are `unknown`. Ranges follow ESP-IDF's `should_map`, not esptool's
wider placement ranges.
A segment cut short by the end of the file is the bytes the file holds, with
an entry limitation that gives the declared length.
Artifact comparison uses each segment's `load_addr` and `data_len` as its
declaration, so a segment that moves with unchanged bytes is `changed` in
`metadata`. Segments pair by index: inserting or removing one shifts the
paths of the segments after it. Header offsets and `classification` are not
compared; the image's own change covers the header and chip. The image's and
the signature blocks' `format_metadata` carry no declaration: their fields
come from their own bytes, which content comparison covers, and a block's
`image_digest_matches` follows the image's content.
## Secure Boot v2 signatures
A signature sector starts at the next 4 KiB boundary after the image and
holds up to three 1216-byte slots. A slot holds a block when it has the `0xE7`
magic and a matching CRC32 at offset 1196, the rule ESP-IDF and espsecure
apply. Each slot is examined independently, so an erased or damaged slot does
not hide a later block. Each block is an entry, `signature-block-<slot>.bin`,
with `esp-image-signature-block` metadata:
| Field | Meaning |
| ---------------------------------- | ------------------------------------------------------------------------- |
| `index`, `version`, `scheme` | Slot 0 to 2, version byte, and `rsa` (`0x02`) or `ecdsa` (`0x03`) |
| `sha_version`, `curve_id` | For ECDSA, the third byte (0 is SHA-256, 1 SHA-384) and the curve ID byte |
| `digest_algorithm`, `image_digest` | The digest the block records |
| `image_digest_matches` | Whether it equals the digest of every byte before the sector |
| `public_key_sha256` | SHA-256 of the block's public key, the value eFuse key digests hold |
| `signature_status` | Always `unverified` |
Signatures are observed, not verified: REA checks no public key, signature or
eFuse. `public_key_sha256` is the digest espsecure `signature-info-v2`
prints, so it can be compared with `espefuse summary`. An unknown version or
`sha_version` leaves the layout-dependent fields `null`. A slot with the magic
but no matching CRC32 is not a block: it is reported in a limitation, whether
or not another slot holds a block, and its bytes are undescribed. Secure Boot
v1 signatures are not decoded.
## Coverage and limitations
Bytes after the image are described when they are erased flash (`0xFF`) or a
signature sector's blocks; erased slots and slack in that sector count as
erased flash. Every other byte is in `undescribed_trailing`.
| Situation | Outcome |
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| Segment data or a segment header beyond the end of the file | Truncation limitation; checksum and SHA-256 `unavailable`; coverage `unknown` |
| File ends before the checksum or the appended digest | That status is `unavailable`, with a limitation; coverage `unknown`, since a signature sector could follow |
| Checksum or SHA-256 mismatch | `invalid`, with a limitation; coverage is unchanged |
| Erased flash after the image that runs past the three slots | Described; no limitation |
| Erased flash that ends before the three slots are complete | Limitation; coverage `unknown`, since a signed image cut there would have lost its sector |
| A signature sector the file cuts short | Limitation; coverage `unknown` |
| Any other bytes after the image | Ranges in `undescribed_trailing`, a limitation, and coverage `unknown` |
| Segment length that is not a multiple of 4 | Limitation: ESP-IDF rejects such an image |
| Segment of 16 MiB or more, except on chips with 32-bit cache addresses | Limitation: ESP-IDF rejects such an image |
ESP32-S3, ESP32-P4, ESP32-C5, ESP32-C61, ESP32-H4 and ESP32-S31 map flash
through 32-bit cache addresses (`SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP`), so
ESP-IDF sets no 16 MiB segment limit for them. For an unknown chip the limit
is not applied.
Undescribed bytes include other flash contents such as an app partition's
stale data, a Secure Boot v1 signature, and the flash segments that esptool
`--ram-only-header` writes after the checksum without counting them. REA
reports their ranges and does not guess their structure. In the padding, in a
sector without a valid block, in the sector's slack and after the sector, the
first byte that is not erased starts a range to the end of that region. A
slot that is neither a block nor erased is reported whole. Adjacent ranges
are merged.
A whole-flash dump of a chip whose bootloader is at offset 0, such as
ESP32-C3 or ESP32-S3, is recognized as that bootloader image; the partition
table, apps and data follow as undescribed bytes.
## Limits
An image has at most 16 segments and 3 signature blocks. Decoding reads each
byte once and retains only fixed-size fields. It reads through erased flash to
find the first byte that is not erased, and stops there. There is no
file-size limit.
## Analyzing a segment
Inventory does not disassemble code or build a memory map. `open_binary`
admits neither RISC-V nor Xtensa as a raw-binary architecture, so a segment
cannot yet be opened as a raw image. Each segment's `source_location` and
`load_addr` give the file offset and address to map it at by hand, for
example with the Rizin tool's `om` command.
## Verification
Synthetic fixtures with computed checksums, digests and CRCs cover
recognition, ESP8266 layouts, the ESP32, ESP32-C3, ESP32-C6 and ESP32-P4
memory maps, truncation at each structure, integrity mismatches, erased and
undescribed trailing bytes, signature slots including damaged and unknown
layouts, and the refusals. CLI and stdio MCP tests exercise the same artifact
provider and advertised schemas.
The optional real lane builds ELF files from source, converts them with
esptool and compares REA's facts with `esptool image-info`:
```sh
REA_RISCV_CLANG=/path/to/clang REA_RISCV_LLD=/path/to/ld.lld \
REA_ESPTOOL_PYTHON=/path/to/python-with-esptool \
npm run verify:esp-images
```
It needs a Clang with the RISC-V target, `ld.lld` and a Python that can run
`esptool` and `espsecure`. It checks each tool before building anything and
names the variable to set when one is missing, and it warns when esptool is
not v5.6.0, the version whose sources the layout facts cite. It builds an
ESP32-C3 app, the same app with `--dont-append-digest`, `--secure-pad-v2`,
`--ram-only-header` and `--pad-to-size`, a bootloader, and ESP8266 v1 and v3
images. It then checks:
- entry point, chip ID, each segment's length, address and header offset,
checksum, digest and descriptor fields against `image-info`;
- each segment's classification in the app, its variants and the
bootloader, whose linker scripts fix every section's region, including the
`not-loaded` padding that `--secure-pad-v2` adds;
- after signing with RSA-3072 and appending ECDSA P-256 and P-384 blocks,
each block's `public_key_sha256` against espsecure `signature-info-v2`,
and that its recorded digest matches;
- extraction of the app and the signed image: each segment file equals the
bytes after esptool's segment header offset, each signature block equals
its slot in the sector espsecure appended, and the source's SHA-256 is
unchanged and equals the reported `root_sha256`;
- the `--pad-to-size` erased tail is described; the `--ram-only-header`
flash segments are undescribed;
- a flipped checksum, a flipped digest byte, a truncated segment (where
`image-info` stops with "End of file reading segment"), and both ESP8266
refusals.
`REA_XTENSA_ESP32_GCC` adds an ESP32 (Xtensa) app built with Espressif's
`xtensa-esp32-elf-gcc`. Without it the report marks that image as skipped.
Each command runs as a process tree owned by the shared verifier command
owner, so a timeout also stops the linker or assembler a compiler driver
starts. The lane removes its workspace only after every tree has stopped and
keeps it when that cleanup cannot be confirmed.
The lane ran on macOS arm64 with Node 24.22.1, Homebrew Clang and LLD 21.1.8,
and `xtensa-esp32-elf-gcc` 14.2.0 (crosstool-NG esp-14.2.0_20251107), once
with esptool and espsecure v5.6.0 and once with 4.12.0. All checks passed for
all 13 images in both runs. With v5.6.0 the complete run, including the builds
and every esptool call, took 21.7 s elapsed, 16.9 s user CPU and 6.1 s system
CPU under `/usr/bin/time -l` with warm caches. The largest single process
peaked at a 253 MiB resident set; the combined peak of all processes was not
measured.
The lane does not establish:
- the other chips: only ESP32-C3 (RISC-V) and ESP32 (Xtensa) images come
from a real producer; the other rows of the chip table are checked against
the ESP-IDF v6.1 headers by reading them;
- images from a real ESP-IDF project build, an OTA download or a device's
flash, none of which it inspects;
- that a signature is valid: it compares digests, and nothing verifies a
signature.
It does not run in CI.
+4 -2
View File
@@ -80,8 +80,10 @@ without bytecode text or duplicated raw stdout:
}
```
The result is distinct derived Evidence linked to its complete parent. Its
`normalized_result.summary` preserves every producer-returned selector, decoded
The result is distinct view Evidence linked to its complete parent. Like the
parent, it has `confidence: inferred`; projection never strengthens inferred
candidates. Its `normalized_result.summary` preserves every producer-returned
selector, decoded
byte offset, dispatch, argument/mutability string including null, carrier/decoded
identities, original limitations and explicit unknowns. Payload `evidence_kind`
remains `inferred`. It preserves stderr/truncation and records stdout text length.
+45 -1
View File
@@ -82,6 +82,11 @@ Published file `relative_path` preserves producer spelling for lineage; `path`
uses the writer's actual normalized filename. An extracted filename that cannot
be represented losslessly as UTF-8 fails publication explicitly with its raw
name bytes in hexadecimal instead of silently omitting the entry.
Unpublished symlinks retain the extracted tree's target bytes in lowercase
`link_target_hex`; `link_target` is null when those bytes are not valid UTF-8.
Older retained Evidence may omit the hexadecimal field. Unblob may have rewritten
the target before REA observed it, so these bytes are not necessarily those stored
in the firmware image.
## CLI and MCP
@@ -275,7 +280,7 @@ Additional lanes are explicit, so the base lane stays small:
REA_FIRMWARE_VERIFY_EXT4=1 npm run fixtures:firmware
REA_FIRMWARE_VERIFY_EXT4=1 npm run verify:firmware
# Existing Ghidra 12.1.x and its declared JDK required.
# Existing Ghidra 12.x (>=12.1) and its declared JDK required.
REA_FIRMWARE_VERIFY_GHIDRA=1 npm run verify:firmware
```
@@ -286,9 +291,48 @@ REA_FIRMWARE_VERIFY_GHIDRA=1 npm run verify:firmware
generated gzip/USTAR/ext4 with a Linux x64 ELF child; SquashFS, UBIFS, proprietary
firmware, other hosts and architectures remain unverified.
## Inspect ESP images
Use `inspect-artifact` / `inspect_artifact` on an ESP32-family app or
bootloader image, such as an OTA download or app partition, for its chip,
classified segments, checksum and SHA-256 results, descriptor and Secure Boot
v2 signature blocks. `extract-artifact` / `extract_artifact` writes one file
per segment and signature block. Reading is portable and needs no external
tool. See [ESP images](esp-image.md).
## Inspect extracted devicetrees
Use [`inspect_devicetree`](devicetree.md) / `rea inspect-devicetree` on an
extracted DTB for its node/property tree, reservations, hardware summary and
selected phandle relationships. FDT v16/v17 inspection is portable and requires
no external tool or disassembler.
## Inspect Intel HEX and S-record images
Use `inspect-artifact` / `inspect_artifact` on an Intel HEX or Motorola S-record
file for its address regions, declared start address and record facts, then
`extract-artifact` / `extract_artifact` for one raw file per region. Decoding is
portable and requires no external tool. See
[Intel HEX and S-record images](hex-records.md).
## Inspect U-Boot legacy uImages
`inspect-artifact` / `extract-artifact` recognize a legacy uImage by its
`0x27051956` magic and inventory it without running or decompressing it.
The root facts record the 64-byte header (architecture, OS, type, and
compression as raw values and names, load and entry addresses, image name,
and timestamp) with the header and data CRC32 verified; the stored payload
is extractable as `payload.bin`, and multi-file and script images additionally
expose each sub-image as `image-<n>.bin` from the stored size table. Declared
addresses are facts from the header, not proven entry points, and compressed
payloads stay as stored. Intel HEX/S-record and FIT images are separate
readers and are not covered here. See [U-Boot legacy uImage](uimage.md) for
component padding, preserved names, resource policies and verification scope.
## Inspect U-Boot FIT images
Use `inspect-artifact` / `inspect_artifact` on a U-Boot FIT (`.itb`) for its
images, declared load and entry addresses, configurations and verified hashes,
then `extract-artifact` / `extract_artifact` for one raw file per image.
Decoding is portable and requires no external tool. See
[U-Boot FIT images](fit-images.md).
+172
View File
@@ -0,0 +1,172 @@
# U-Boot FIT images
REA inventories U-Boot Flattened Image Tree (FIT, `.itb`) files through
`inspect-artifact` / `inspect_artifact`, and materializes the stored bytes of
each image through `extract-artifact` / `extract_artifact`. Decoding is static
and needs no external tool.
```sh
rea inspect-artifact ./boot.itb --json
rea inspect-artifact ./boot.itb --detail summary --evidence_output evidence.json --json
rea extract-artifact ./boot.itb --json
```
For MCP, open the file with `open_binary`, then call `inspect_artifact`. Summary
delivery retains the complete Evidence; use `parent_evidence_id` with
`inspect_analysis_view` to read selected images and fields. `extract_artifact`
returns a fresh `output_root` containing one raw file per image. FIT summaries
use the current projection identity; there is no pre-coverage FIT summary variant.
## Recognition
A FIT is a flattened devicetree (FDT v16 or v17) with a top-level `/images`
node. Recognition walks the structure block within the first 4 KiB of the file
only; the file name does not matter. A devicetree whose `/images` node begins
after 4 KiB, a devicetree without `/images`, and any other FDT version stay on
the plain devicetree route: `open_binary` refuses them and
[`inspect_devicetree`](devicetree.md) still parses them. A U-Boot control DTB
that contains `/images` is treated as a FIT. The container format is `fit`.
Recognition is a probe. The complete devicetree parse decides, so a file whose
prefix declares `/images` but whose structure is malformed fails as a
malformed FIT rather than falling back to plain classification.
## Images and metadata
Each child of `/images` is one inventory entry named `images/<unit-name>.bin`,
listed in devicetree order. Its bytes come from exactly one data source:
| Source | Stored bytes |
| --------------- | --------------------------------------------------------------------------------------- |
| `data` | The embedded property value |
| `data-offset` | `data-size` bytes at `data-offset` past the devicetree end, aligned to 4 (`mkimage -E`) |
| `data-position` | `data-size` bytes at `data-position` from the start of the file (`mkimage -p`) |
`data-position` is read as U-Boot reads it: an offset from the start of the
FIT, not a machine address.
Image `format_metadata` (`fit-image`) records `index`, `name`, `description`,
`type`, `arch`, `os`, `compression`, `load` and `entry`, the `data_source`,
the raw `declared_offset` for external data, `image_data` (the shared-data
link), `cipher_present`, `cipher_algo`, `hash_algorithms`, `hashes_verified`,
`hashes_unverified`, `signature_count`, `signatures_unreadable` and
`signature_algorithms`. Algorithm lists are arrays. Nullable declaration fields
are absent unless named in `unreadable_fields`, which records parsing failures
per field. Hash or signature warnings do not make unrelated declarations unknown.
`load` and `entry` fold one or two 32-bit cells into a lowercase
`0x…` value, as U-Boot does, independent of `#address-cells`.
Root `format_metadata` (`fit`) records `fdt_version`, `fdt_totalsize`,
`external_data_base` (the aligned devicetree end), the root `description`,
`timestamp` (seconds since 1970) and `address_cells`, plus
`default_configuration` and `configurations`. A missing description or
timestamp is `null`.
Image bytes are reported as stored. Compressed images are not decompressed and
ciphered images are not decrypted: entries report `encrypted: false` and the
cipher declaration in `cipher_present` and algorithm in `cipher_algo`. A missing
or malformed algorithm stays `null`; it does not establish unciphered bytes.
Embedded `image-data` links require byte-identical stored properties; external
links require matching physical ranges.
The extracted file holds the stored bytes. Direct-analysis suggestions require
`compression: "none"` and `cipher_present: false`.
## Hashes and signatures
Hash subnodes are children whose name starts with `hash`. Inventory verifies
`crc32` (4 bytes, big-endian), `md5`, `sha1`, `sha256`, `sha384` and `sha512`
over the stored bytes, the same bytes mkimage hashed after any ciphering. All
hashes of an image are computed in one streamed pass while the inventory is
prepared, so a mismatch fails the whole inventory, naming the image, hash
node, algorithm, and the declared and computed values. A supported algorithm
whose value has the wrong length also fails.
Other algorithms such as `crc16-ccitt`, `crc8` or `sm3_256`, a hash without a
readable `algo`, and a hash without a `value` are not verified; each is
counted in `hashes_unverified` and reported as an image limitation.
Signature subnodes (names starting with `signature`) on images and
configurations retain the total declaration count, readable algorithms and
`signatures_unreadable`. Missing or malformed algorithms carry source limitations
so unknown declarations remain distinguishable from absence. Signatures are never
verified.
## Configurations
`/configurations` is optional. Each child records its `name`, `description`,
and the image references `kernel`, `firmware`, `fdt` (base plus overlays),
`ramdisk` and `loadables`, always as lists, plus its signature algorithms.
`compatible`, `fpga`, `script`, `cmdline` and `load-only` are not reported. A
reference to a name that is not an `/images` child, and a `default` that names
no configuration, are reported as limitations and kept as declared. Each
configuration carries `unresolved_reference_count`; dangling references share one
configuration-level diagnostic while every original reference remains available.
## Facts, limitations and failures
| Situation | Outcome |
| ---------------------------------------------------------------------------------------------- | ------------------------------------ |
| Malformed devicetree, truncated header, `totalsize` past the end of the file | Fails as malformed |
| No data source, more than one data source, external data without `data-size` | Fails as malformed |
| `data-offset`, `data-position` or `data-size` not one 32-bit cell, `image-data` not one string | Fails as malformed |
| External data outside the file, overlapping the devicetree or another image | Fails as malformed |
| Two images with an identical external range linked by `image-data` | Accepted as shared data |
| A dangling, chained or mismatched `image-data` link | Fails as malformed |
| Hash mismatch, or a supported hash value with the wrong length | Fails integrity |
| Unsupported, algorithm-less or value-less hashes | Unverified, reported as a limitation |
| Malformed `description`, `type`, `arch`, `os`, `compression`, `load`, `entry` or `timestamp` | `null`, reported as a limitation |
| Dangling configuration reference, missing default configuration | Reported as a limitation |
Failures apply to the whole file and return no partial inventory.
## Limits
The devicetree, including any embedded image data, must be at most 16 MiB; a
larger `totalsize` fails as a memory limit. Store large images externally
(`mkimage -E`): external data of any size is streamed from the file and never
loaded into memory. A FIT may declare at most 1,024 images and 1,024
configurations, and an image at most 8 hash nodes; the devicetree parser's
node, property and depth bounds also apply. The sum of declared image sizes
is bounded by the shared archive expansion budget. These are fixed resource
bounds with no runtime override. Configurable ceilings are tracked in
[#6176](https://github.com/morluto/rea/issues/6176).
## Analyzing an image
Inventory does not execute anything, and `load` and `entry` are declarations.
After extraction:
- inspect `flat_dt` images with [`inspect_devicetree`](devicetree.md);
- open an uncompressed image with `open_binary` using format `raw-binary`, an
architecture matching its declared `arch`, and `entry_point` set to its
declared `load` address; raw-binary maps file offset 0 and seeds analysis at
`entry_point`. Automatic suggestions require nonempty bytes, an admitted
architecture/address/extent, and a declared entry that is absent or equal to
load. Distinct or unreadable entry declarations remain in Evidence without
a raw-loader suggestion, since this loader cannot represent separate mapping
and analysis entry addresses.
## Comparison
Artifact comparison reports changes to an image's payload interpretation,
including load and entry declarations. Equivalent external offset forms and
inventory positions leave those declarations unchanged. Unavailable
interpretations remain unknown, while independently known changes survive.
## Verification
Synthetic fixtures with computed hashes cover embedded, `data-offset` and
`data-position` layouts, shared data, overlap and bounds failures, every
verified hash algorithm, configurations, resource limits, inventory,
extraction and reader lifecycle. CLI and stdio MCP tests exercise the same
artifact provider and advertised schemas. Real U-Boot `mkimage` 2023.01 output
has also been verified for embedded, `-E -B 0x200`, and
`-E -p 0x2000 -B 0x200` layouts, with byte-exact extraction checked against
`dumpimage`. The OpenWrt 24.10.3 ABT ASR3000 recovery FIT was checked against
`mkimage`, `fdtget` and `dumpimage`, including its kernel, initrd and devicetree.
No image was executed.
For small containers, complete delivery avoids an additional view request.
Choose summary and selected views when the omitted facts justify that extra
request; summary delivery does not reduce the underlying inventory work.
+1 -1
View File
@@ -119,7 +119,7 @@ installation's language catalog, the same catalog REA uses to admit
and still succeeds on the stock checks.
The ELF lane (`npm run verify:ghidra:ppc`) is separate. See
[PowerPC ELF analysis through Ghidra](/ghidra-ppc).
[PowerPC ELF analysis through Ghidra](ghidra-ppc.md).
## Not supported yet
+1 -1
View File
@@ -3,7 +3,7 @@
REA can analyze DOS MZ executables and explicitly selected COM images through the bring-your-own Ghidra adapter.
The Linux x64 and macOS arm64 verification lanes exercise actual 16-bit disassembly and
decompilation through the CLI and stdio MCP. Provider admission accepts Ghidra
12.1.x and that installation's declared JDK range. The verification lane uses
12.x (>=12.1) and that installation's declared JDK range. The verification lane uses
Ghidra 12.1.4 and JDK 21; no DOS emulator or cross-compiler is required.
## Open and inspect
+49 -1
View File
@@ -30,6 +30,17 @@ signal. Confirm resource causes from process output or host/container records;
operation-scoped JVM `OutOfMemoryError` observations retain their separate resource
classification. Automatic kernel or cgroup OOM attribution is not implemented.
After the authenticated startup handshake, rejected inputs (`invalid_request`,
`not_found`, `ambiguous`, or an invalid function name) use
`diagnostics.diagnostic_scope: "request"` when their active output checkpoint is
available. They preserve the active request's
`failure_output`, target/profile identity and runtime/log coordinates, while
omitting cumulative launcher stdout/stderr and launch-support output. Startup,
process, protocol and other remote failures retain full session diagnostics.
The Ghidra client still owns its bounded cumulative output; this projection does
not clear it or alter session readiness. Log paths refer to the owned ephemeral
runtime and are removed by normal cleanup.
Provider selection and profile identity follow
[MCP contracts](mcp-contracts.md#identity-and-discovery). One deep
provider stays bound to the target; runtime failure never selects another
@@ -160,6 +171,43 @@ have no file backing. ELF mappings are observed
without independent format-specific load-image verification, as the result's
status and limitations state.
For large relocation inventories, select MCP `inspect_native_load_image` with
`detail: "summary"`. It returns verification state, observed identity and counts,
while retaining complete Evidence. Use `normalized_result.parent_evidence_id`
with `inspect_analysis_view` and a view such as:
```json
{
"kind": "native-load-image",
"collection": "relocations",
"offset": 0,
"limit": 32,
"fields": ["address", "status", "type"]
}
```
Collections are `source_files`, `mappings`, `relocations`, `entry_points`,
`entry_context`, `checks` and DOL `sections`. Optional
`indices` select original row indices before paging; empty indices select none.
Fields are collection-specific. Relocation defaults omit byte payloads; check defaults omit potentially large `expected`/`observed` inventories. Request those fields explicitly when needed. Other collections default to all fields. Metadata recovery remains counted and retained in complete parent Evidence.
Parent Evidence, collection and `source_index` identify a row, including same-address
relocation alternatives. Null counts or rows mean unrecorded or inapplicable;
they never establish an empty observation. Exhausting a page does not upgrade
unsupported verification or runtime coverage. Pages query immutable retained
facts without reopening the target or repeating Ghidra work.
Each page carries the source's structured `verification_status` independently
of its page coverage.
CLI summary delivery requires a complete Evidence bundle:
```sh
rea inspect-native-load-image <path> --provider ghidra --detail summary --evidence_output /new/load-image.json --json
```
Read selected pages later through `inspect-analysis-view` using the returned
parent ID and an `evidence-file` source pointing to that bundle. Complete
delivery remains the default in both adapters.
An unsuccessful numeric procedure lookup reports the current Ghidra image base
and gives the CLI commands above alongside the corresponding MCP operations.
Repeat any target-format, architecture, and entry-point options used to open the
@@ -251,7 +299,7 @@ host/provider acceptance run with only the host compiler.
`--dll`. These static fixtures contain source-owned encoded instructions; they
are not compiler-produced programs. See the [Windows verification scope](windows-ghidra-p0.md#native-authority-and-target-identity)
for real-provider coverage and exclusions.
These lanes check all 26 read-only operations, target/snapshot/import SHA-256 linkage,
These lanes check all 27 read-only operations, target/snapshot/import SHA-256 linkage,
and project, endpoint, process, and runtime cleanup. The independent native
lane checks DACLs, handle admission, cancellation, and Job Object lifecycle.
`npm run verify:ghidra:windows:package` packs and installs REA into an isolated
+12 -3
View File
@@ -1,9 +1,18 @@
# Godot PCK archives
`inspect-artifact` and `extract-artifact` read ordinary Godot PCK formats 2, 3
`inspect-artifact` and `extract-artifact` read ordinary Godot PCK formats 1, 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.
and 4.7.1 produced formats 2, 3 and 4 respectively in verification; other engine
releases have not been verified. Format 1 compatibility follows the
[Godot 3.5 loader](https://github.com/godotengine/godot/blob/3.5/core/io/file_access_pack.cpp#L201-L242)
and [exporter](https://github.com/godotengine/godot/blob/3.5/editor/editor_export.cpp#L1094-L1164)
layout and is covered by synthetic standalone and embedded fixtures; an actual
Godot 3 export has not been exercised.
Format 1 uses an 84-byte header, no pack or member flags, and absolute member
offsets in the complete source file, including an embedded executable carrier.
Its reported flags and file base are zero because those fields are absent.
Zero-offset removal records remain unsupported; REA does not apply patches.
Inspection retains the original header and directory facts, including engine
version, flags, declared file count, source paths, offsets and declared MD5.
+4 -1
View File
@@ -36,7 +36,7 @@ The MCP tool `project_harmony_application_graph` takes the same
- exact component paths, artifact IDs, and hashes (manifests, Ark bytecode,
resources, native libraries, JavaScript, signing)
- a packaging-model hint: Stage is claimed only from a `module.json` entry
- a packaging-model hint: Stage is claimed only from an exactly cased `module.json` entry
outside a classified resource path, FA only from `config.json` outside a
classified resource path, otherwise `unknown`
- FA resources under `assets/<module>/resources/` as well as Stage `resources/`
@@ -46,6 +46,9 @@ The MCP tool `project_harmony_application_graph` takes the same
- path-based N-API bridge hypotheses between bytecode and `libs/<abi>` native
libraries
An unavailable manifest can still supply a path-based model hint; its content
identity remains unknown. Manifest names follow case-sensitive ZIP member names.
File and slice occurrences supply component and child-package paths; directory
trees and symlinks retain their identities in the source inventory without
being classified as code files. Ark and JavaScript runtime hints summarize the
+129
View File
@@ -0,0 +1,129 @@
# Intel HEX and S-record images
REA inventories Intel HEX (I8HEX, I16HEX, I32HEX) and Motorola S-record (S19,
S28, S37) programming files through `inspect-artifact` / `inspect_artifact`, and
materializes their decoded bytes through `extract-artifact` /
`extract_artifact`. Decoding is static and needs no external tool.
```sh
rea inspect-artifact ./firmware.hex --json
rea inspect-artifact ./firmware.s37 --detail summary --evidence_output evidence.json --json
rea extract-artifact ./firmware.hex --json
```
For MCP, open the file with `open_binary`, then call `inspect_artifact`. Summary
delivery retains the complete Evidence; use `parent_evidence_id` with
`inspect_analysis_view` to read selected regions and fields. `extract_artifact`
returns a fresh `output_root` containing one raw file per region.
## Recognition
A file is recognized only when its first line, starting at byte 0, is a fully
valid record: correct start character, hex digits, byte count, checksum, known
record type and fixed length. The file name does not matter. A byte-order mark,
a leading blank line or an invalid first record leaves the file unrecognized,
so it falls through to plain `file` classification. Recognition never searches
for a record later in the file. The container formats are `intel-hex` and
`srec`.
## Regions and metadata
Each inventory entry is one address-contiguous region of decoded bytes, named
`0x<start>-0x<end>.bin` with an inclusive end address of eight lowercase hex
digits, for example `0x08000000-0x0800001f.bin`. Regions are listed in ascending
address order. Out-of-order records are sorted into regions; gaps separate
regions and are never filled.
Region `format_metadata` (`hex-record-region`) records `start_address`,
`end_address`, `length`, `record_count`, and `first_line`/`last_line`: the
1-based line span of the contributing data records.
Root `format_metadata` (`hex-records`) records:
| Field | Meaning |
| ------------------------------------------------- | --------------------------------------------------------------------------------- |
| `encoding`, `variant` | `intel-hex` or `srec`; the variant derived from the record types seen, or `mixed` |
| `line_count`, `record_count`, `data_record_count` | Lines read, non-blank records, and data records |
| `data_bytes`, `duplicate_bytes`, `region_count` | Unique decoded bytes, bytes rewritten with identical values, and regions |
| `lowest_address`, `highest_address` | Address bounds of the decoded bytes, or `null` without data |
| `termination` | Whether Intel `01` or S-record `S7`/`S8`/`S9` was present |
| `start_address`, `start_address_record` | The Intel `05` EIP or the `S7`/`S8`/`S9` address, with its record type |
| `start_segment_cs`, `start_segment_ip` | The Intel `03` CS:IP pair |
| `header_hex`, `header_text` | S-record `S0` data as hex, and as text only when every byte is printable ASCII |
| `declared_data_record_count` | The last `S5`/`S6` count, validated against the data records before it |
`variant` is `null` for an S-record file in which no data or termination
record establishes an address width. Start addresses are declared facts, not
proven entry points.
## Facts, limitations and failures
| Situation | Outcome |
| ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| Gaps between regions | Separate regions; never zero-filled |
| Out-of-order records | Sorted into regions |
| An address written twice with the same value | Accepted and counted in `duplicate_bytes` |
| An address written twice with different values | Fails, naming the address and the line spans of both writes |
| Checksum mismatch, odd hex length, non-hex character, byte count disagreeing with the line | Fails with the line, declared and computed values, and record type |
| Line longer than 521 (Intel) or 514 (S-record) characters, excluding the line ending | Fails before the line is decoded |
| Intel type `06` or higher, `S4`, wrong fixed length for Intel `01`–`05` or `S5`–`S9` | Fails |
| Missing Intel `01` or `S7`–`S9` | Regions are returned; coverage is unknown and the file may be truncated |
| A non-blank record after termination, or a second `S0` | Fails; blank lines are allowed anywhere |
| `S5`/`S6` count different from the data records before it | Fails |
| Termination type not matching the data address width | Reported as a limitation; the declared fact is kept |
| Conflicting repeated `03`/`05` start records | Fails; identical repeats are allowed |
| An Intel data record whose 16-bit offset wraps past `0xFFFF` | Fails: producers disagree on whether the address wraps or continues linearly |
| I16HEX data above `0xFFFFF`, or data crossing the S1/S2/S3 address width | Fails |
Lowercase hex, LF and CRLF line endings, and trailing spaces or tabs are
accepted. A CR not followed by LF is an invalid character. Failures apply to
the whole file and return no partial regions.
## Limits
The file must be at most 128 MiB. Every data byte needs two hex digits, so the
decoder reserves at most half the file size for decoded bytes before reading,
and stores only written addresses. The decoder retains at most 65,536
address-discontiguous record runs before merging them into regions. A run is a
sequence of consecutive records whose addresses continue each other. Both are
fixed resource bounds, not format limits, and fail as limits (`file-size` and
`capacity`) with no runtime override. Configurable ceilings are tracked in
[#6176](https://github.com/morluto/rea/issues/6176). The line-length limits are
the one-byte record count: Intel HEX allows 255 data bytes, while S-record
counts include address and checksum bytes.
Decoded regions are cached only for the reader's lifetime. Each open checks
its admitted carrier identity again. Region streams copy at most 64 KiB per
chunk, so consumers cannot mutate cached bytes and opening a large region does
not copy it in full. Caller cancellation keeps its exact reason, and closing
the reader waits for active region streams to close.
## Analyzing a region
Inventory does not establish the CPU, byte order or memory map, or that a
declared start address is executable. To disassemble a region, extract it and
open the region file with `open_binary` using format `raw-binary`, an
architecture you choose, and `entry_point` set to the region start address;
raw-binary maps file offset 0 at `entry_point`. Each region is opened
separately, so references between regions are not resolved. A caller-selected
Ghidra language and base address for raw-binary imports is tracked in
[#4246](https://github.com/morluto/rea/issues/4246); Thumb-only Cortex-M images
may be refused or decoded in ARM state until
[#5744](https://github.com/morluto/rea/issues/5744) is resolved.
## Verification
Fixtures with computed checksums cover supported record types, checksums,
termination, address gaps and overlaps, resource refusals, inventory, extraction
and reader lifecycle. CLI and stdio MCP tests exercise the same artifact
provider and advertised schemas, including retained Evidence views.
GNU objcopy 2.40 output was also checked on Linux: the system `true` ELF was
converted to Intel HEX and S-record, with additional address-rebased I32HEX
and S37 cases. Each yielded 13 regions. A 19,124,817-byte Intel HEX conversion
of the system Python 3.11 ELF yielded 11 regions containing 6,799,261 decoded
bytes. Public CLI inspection and extraction matched GNU BFD address ranges
and independently exported section bytes. Adjacent GNU sections were joined
without filling address gaps. These are real producer outputs from system
applications, not vendor-firmware or target-execution verification; srec_cat
and other producers remain unverified. No general speedup is claimed.
+6 -1
View File
@@ -40,7 +40,12 @@ Record the image digest, REA source revision and these dependency versions:
- OpenSSL and cURL advertising HTTP3 and HTTP2 in `curl --version`.
The verified guest used Python 3.14.7, cURL 8.22.0, ngtcp2 1.25.0 and nghttp3
1.18.0. Other dependency profiles need verification. Back up the guest's
1.18.0. The current requirements update certifi from 2026.7.22 to 2026.10.19
to remove the compromised emSign trust root described in
[GHSA-6q48-6c7w-9gw2](https://github.com/certifi/python-certifi/security/advisories/GHSA-6q48-6c7w-9gw2).
The revised dependency graph has not been rerun in that sealed guest; the
historical verification does not cover this update. Other dependency profiles
need verification. Back up the guest's
`/etc/hosts` before adding `127.0.0.1 lab.test`. Reserve guest TCP/UDP loopback
ports 18443 and 19443. These changes belong only to the disposable guest.
+66 -1
View File
@@ -80,6 +80,71 @@ Native MCP 1.1.2 can navigate in the previously focused pseudocode tab when swit
Native tool observations retain actual tool names and complete JSON text. Upstream `structuredContent` can be a shortened preview even while text contains the full result. REA reads the full native representation and rejects missing/malformed text instead of treating previews as complete observations.
### Migrate a legacy attached registration
Both attached profiles remain supported. Migrating replaces the upstream server;
adding `"protocol": "native"` to a legacy Python proxy registration is insufficient.
The native plugin is separate from mrexodia/ida-pro-mcp, and upgrading mrexodia to
its modern tool catalog does not select this profile.
1. Back up the working registration file. Install and start the native plugin
using its [upstream instructions](https://github.com/0xshlomil/ida-free-mcp).
IDA and the plugin are bring-your-own; REA does not install or build them.
Use a build with the navigation correction described above, and restrict its
listener to loopback or apply the documented host firewall restriction.
Stop the legacy endpoint first if both servers would use the same port.
2. Open the same original input binary in IDA and wait for analysis. Keep that
file readable by REA. The native metadata resource must report its recorded
input SHA-256; the resource's `path` identifies the database, not an input
file to substitute. Universal Mach-O inputs still require a thin extraction.
3. Replace the registration, using the native plugin's actual local endpoint.
For example, this legacy registration:
```json
{
"mode": "attached",
"command": "python",
"args": [
"/absolute/path/to/ida_pro_mcp/server.py",
"--ida-rpc",
"http://127.0.0.1:13337"
]
}
```
becomes:
```json
{
"mode": "attached",
"protocol": "native",
"url": "http://127.0.0.1:13337/mcp"
}
```
Keep `REA_IDA_MCP_CONFIG` pointing at the replacement file and close/reopen
the REA binary session to connect with it. If changing the environment's
configuration path, restart the MCP server as described above. Do not reuse
the legacy RPC URL as an MCP HTTP endpoint.
4. Check `binary_session` availability before resuming workflows. Direct
`procedure_callers` becomes unavailable and dossier callers remain unknown;
incoming address xrefs do not establish direct call edges. Native strings
use C-string rendering. Assembly and instruction reads no longer navigate
the GUI; native pseudocode still changes focus and closes existing
pseudocode tabs. IDA Free decompilation may require cloud access and consent.
5. Run the [real-provider verification](#verification) with two distinct
functions and the required second-function marker. Supply independently
known string and xref oracles for those checks. Existing Windows evidence
covers IDA Pro 9.3 with the documented source build and listener change;
it does not establish stock-plugin, Windows Free, or native macOS behavior.
A valid registration or successful doctor check alone does not verify the
connection, target identity, or function switching.
REA continues to verify identity and image base around requests and closes only
its connection, preserving the attached database. Restore the backed-up legacy
registration and its upstream endpoint to return to the legacy profile.
The legacy producer moves the active GUI as a side effect: assembly and raw function instructions jump to the function, and successful pseudocode opens or reuses a pseudocode view. A function dossier does both. Native GUI decompilation also changes the active view. `binary_session` reports these operations with `effects.may_show_ui: true`; headless operations and the other attached operations report `false`.
## Give REA a target for headless analysis
@@ -175,7 +240,7 @@ The verifier requires the resolved procedure in both inventory and procedure sea
The initial real workflows use stdio registrations for the legacy Windows GUI profile and a Windows x64 headless supervisor with IDA 9.3. The headless workflow has also passed on macOS arm64 with IDA Professional 9.1 (build 9.1.250226) against the same upstream commit `c133c3853faa111a9b00ee615c013b720d0c4acd`, using a source-built arm64 Mach-O fixture; Mach-O C symbols carry a leading underscore, so the procedure name is `_rea_fixture_add`. Streamable HTTP is tested against a loopback MCP fixture with the pinned client SDK; a real IDA HTTP-supervisor workflow remains unverified. Linux headless engine operation, other IDA releases, architectures, and modern attached GUI tools require their corresponding real workflows before support is claimed.
Native Windows verification uses IDA Pro 9.3 with the public two-function fixture and Windows `whoami.exe`, using upstream `c9d15d98e8a143fc74f6e14037c48f63889b6d6c` with a loopback-listener change. It covers production CLI/MCP parity, distinct-function switching, identity and connection cleanup. See the [correctness and performance measurements](https://github.com/morluto/rea/blob/main/experiments/analysis-efficiency/ida-native-windows.md). This follow-up did not run Windows IDA Free or native macOS.
Native Windows verification uses IDA Pro 9.3 with the public two-function fixture and Windows `whoami.exe`, using upstream `c9d15d98e8a143fc74f6e14037c48f63889b6d6c` with a loopback-listener change. It covers production CLI/MCP parity, distinct-function switching, identity and connection cleanup. See the [correctness and performance measurements](https://github.com/morluto/rea/blob/a2e2c29b59e8775b0e6aedb09a9eb16adf32646b/experiments/analysis-efficiency/ida-native-windows.md). This follow-up did not run Windows IDA Free or native macOS.
Headless readiness distinguishes an explicit `auto_analysis_ready: false` from
unknown readiness (`null`). The former returns a retryable capability refusal
+6
View File
@@ -528,6 +528,12 @@ message names one reason:
| `image-range-overlap` | Two images claim the same type definitions. |
| `invalid-string` | A name index is outside the strings section, its string is unterminated, or it is not valid UTF-8. |
Record extents are checked for the decoded images, types, methods, fields,
properties, events, parameters, string literals, nested types, generic
containers, generic parameters and interface offsets. Other header sections
are checked for file bounds and overlap; their internal record layouts are not
decoded or validated by this inventory.
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`.
+14 -14
View File
@@ -47,20 +47,20 @@ For runtime instrumentation, see the [Frida guide](./frida-instrumentation.md).
## Choose a guide
| 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), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [PE imports](pe-imports.md), [PE TLS/load config](pe-load-config.md), [ELF notes](elf-notes.md), [Linux kernel modules](kernel-modules.md), [Apple IPS](apple-ips.md), [Erlang BEAM](erlang-beam.md), [offline ELF layout](binary-diagnostics.md), [recorded crashes](recorded-crashes.md) |
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-binaries.md), [Rust dependencies](rust-binaries.md), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [PE imports](pe-imports.md), [PE TLS/load config](pe-load-config.md), [ELF notes](elf-notes.md), [Apple IPS](apple-ips.md), [Erlang BEAM](erlang-beam.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), [GameCube DOL](ghidra-dol.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), [APK signatures](apk-signature.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) |
| 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), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [PE imports](pe-imports.md), [PE TLS/load config](pe-load-config.md), [ELF notes](elf-notes.md), [Linux kernel modules](kernel-modules.md), [Apple IPS](apple-ips.md), [Erlang BEAM](erlang-beam.md), [offline ELF layout](binary-diagnostics.md), [recorded crashes](recorded-crashes.md) |
| Inspect native functions, references, or types | [Native binaries](native-investigation.md), [Go metadata](go-binaries.md), [Rust dependencies](rust-binaries.md), [CPython pyc files](python-pyc.md), [PE certificates](pe-certificates.md), [PE imports](pe-imports.md), [PE TLS/load config](pe-load-config.md), [ELF notes](elf-notes.md), [Apple IPS](apple-ips.md), [Erlang BEAM](erlang-beam.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), [GameCube DOL](ghidra-dol.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), [UnityFS](unityfs.md), [U-Boot uImage](uimage.md), [.NET](managed-code-analysis.md), [Python packages](python-packaged-applications.md), [Android](android-analysis.md), [APK signatures](apk-signature.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), [ESP images](esp-image.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), [admission limits and recovery](design/limits-and-recovery.md),
+274 -75
View File
@@ -3,13 +3,14 @@
Run REA, connect your selected agents, and check the tools needed for your task.
Setup previews configuration changes and asks for approval before applying them.
| Task | Section |
| --------------------------------- | --------------------------------------------------------------------------------------------------- |
| Connect an agent | [Start setup](#start-setup), then [review changes](#review-setup-changes) |
| Diagnose one task | [Scoped readiness checks](#check-readiness-for-your-task) |
| Configure an analysis engine | [Hopper](#hopper), [Ghidra](#ghidra), the [IDA guide](ida-provider.md), or [Kuna](kuna-provider.md) |
| Update or remove REA | [Maintenance](#diagnose-update-and-remove) |
| Resolve a client-specific problem | [Client configuration](client-configuration.md) |
| Task | Section |
| ---------------------------------- | --------------------------------------------------------------------------------------------------- |
| Connect an agent | [Start setup](#start-setup), then [review changes](#review-setup-changes) |
| Install a Claude Code/Codex plugin | [Agent plugins and marketplaces](#agent-plugins-and-marketplaces) |
| Diagnose one task | [Scoped readiness checks](#check-readiness-for-your-task) |
| Configure an analysis engine | [Hopper](#hopper), [Ghidra](#ghidra), the [IDA guide](ida-provider.md), or [Kuna](kuna-provider.md) |
| Update or remove REA | [Maintenance](#diagnose-update-and-remove) |
| Resolve a client-specific problem | [Client configuration](client-configuration.md) |
## Start setup
@@ -84,9 +85,16 @@ For an existing configuration, setup and uninstall recovery refuse a detected
replacement or edit and name the recovery backup. Quit clients before editing their configuration;
these checks do not lock out another writer modifying the same file in place,
or exclude pathname changes between the final check and publication.
Setup refreshes an existing `rea` registration only when its launcher proves REA
ownership. Foreign or unresolved launcher identity blocks setup before any
backup or write, including an OpenCode legacy entry that migration would remove.
Review the existing launcher and manually rename or remove that registration to
approve replacing it. A different existing installation path is foreign to the
current entrypoint; a path that cannot be resolved remains unknown. Cordis uses
its stable REA entry ID instead of launcher identity.
Setup also retains valid environment overrides in REA's existing server entry,
such as `REA_MCP_INPUT_SCHEMA_PROFILE`, `REA_MCP_OUTPUT_SCHEMA_PROFILE`, and
`REA_MCP_MAX_RESPONSE_BYTES`.
`REA_MCP_MAX_RESPONSE_BYTES`, and `REA_MCP_TOOL_FAMILIES`.
Detected provider settings replace only matching environment keys.
Setup manages REA's launcher, selected provider settings, and recommended timeout
defaults. Codex approval policies, tool selections, and other caller-owned server
@@ -162,7 +170,9 @@ Setup leaves existing skill copies in other locations untouched.
Setup refuses symbolic links at the selected skill directory or its managed
`references` directory, matching uninstall and update's ownership rules. Use a
regular skill directory, or select `--skill=false` to configure the client
registration without installing the bundled skill.
registration without installing the bundled skill. A non-directory ancestor is
reported as `ENOTDIR`; preserve the blocking file and correct the directory path
before rerunning setup.
The final selected directories are checked before approval and again before
setup changes any client or Hopper installation. Unselected client destinations
do not block other setup choices. Doctor reports linked or non-directory skill
@@ -204,7 +214,8 @@ identity remains available at `identity.catalog`.
Setup pins package-runner MCP registrations to the exact installed REA version,
installs the matching skill and on-demand references in the same plan, and adds
`startup_timeout_sec = 30` for Codex and Grok Build. Codex also receives a
`startup_timeout_sec = 30` for Codex and Grok Build when no positive timeout
is already configured. Codex also receives a
`tool_timeout_sec` derived from known provider startup plus operation headroom.
## Limit REA to one project or agent profile
@@ -264,7 +275,7 @@ After reviewing an update plan, rerun that same prefixed setup command without
`--dry-run` and approve its exact changes. Profile removal likewise needs the
prefix on `claude mcp remove --scope user rea` and any `rea uninstall` command;
keep the broader client scope of uninstall in mind. Restart the selected
profile after changing its pinned registration.
profile after changing its registration.
`claude mcp remove` removes only the registration. To remove REA from this
profile without running the broader uninstall flow, first back up the profile's
@@ -314,34 +325,30 @@ commands. Record an existing selection first if you intend to restore it after
finishing. The configuration path below is the default profile's
`~/.claude.json`; a different active profile uses its own config root instead.
Register with the variable unset:
<!-- x-release-please-start-version -->
Register with the variable unset, substituting the absolute runtime and entry
script from your existing installation or setup dry-run:
```bash
claude mcp add --scope local rea -- npx -y rea-agents@6.8.0 mcp
claude mcp add --scope local rea -- "/absolute/path/to/node" "/absolute/path/to/rea/scripts/rea.mjs" mcp
```
On native Windows, use the same project directory and wrap the package-runner
shim so the stdio client can launch it:
On native Windows, use the same project directory and absolute paths:
```powershell
claude mcp add --scope local rea -- cmd.exe /d /c npx -y rea-agents@6.8.0 mcp
claude mcp add --scope local rea -- "C:\Program Files\nodejs\node.exe" "C:\tools\rea\scripts\rea.mjs" mcp
```
<!-- x-release-please-end -->
Local scope stores the entry under that directory's path in `~/.claude.json`,
so other projects don't load it. This route doesn't install the bundled skill.
Avoid `--scope project`, which writes `.mcp.json` into the repository where it
can be committed or copied. `rea doctor` and `rea uninstall` read only the
user-level entry, so they don't report or remove a local-scope registration;
remove it with `claude mcp remove --scope local rea` from the same directory.
`rea update` doesn't refresh it either, so it stays on the version it names.
`rea update` doesn't refresh it either, so it continues using the selected installation.
To move it to a newer release, first back up the project entry in
`~/.claude.json` and record its environment and other metadata. In particular,
preserve caller-selected overrides such as `REA_MCP_INPUT_SCHEMA_PROFILE` and
`REA_MCP_MAX_RESPONSE_BYTES`. Run `claude mcp remove --scope local rea` from the
`REA_MCP_MAX_RESPONSE_BYTES`, and `REA_MCP_TOOL_FAMILIES`. Run `claude mcp remove --scope local rea` from the
same directory, then recreate it with the platform-appropriate command above
and the new version. Reapply every recorded environment value with Claude
Code's `mcp add --env NAME=value` options and restore any other retained entry
@@ -374,7 +381,7 @@ Select the part you want to check:
| Task | Readiness check |
| ----------------------------------- | ------------------------------------------------------------------------ |
| Static JavaScript/Electron analysis | Run `rea analyze-javascript-application PATH --json` directly. |
| One analysis engine | `rea doctor --provider ghidra --json` (or `hopper`, `ida`) |
| One analysis engine | `rea doctor --provider ghidra --json` (or `hopper`, `ida`, `kuna`) |
| One agent registration | `rea doctor --client codex --json` (see [client IDs](#supported-agents)) |
| Installed workflow instructions | `rea doctor --skill --json` |
@@ -412,6 +419,13 @@ The public error code varies by caller: `capability_unavailable`,
only a generic startup error. Check this prerequisite before following
provider-specific recovery advice.
`binary_session` still returns status on such a host. Providers whose
readiness check reaches the owned-child launch, such as Ghidra's Java probe,
JADX and Apktool, report themselves unavailable with a reason naming the
missing `ps`. A provider that fails an earlier configuration check, such as
JADX without `REA_JADX_MCP_JAR`, keeps that reason. The other providers keep
their own status. `open_binary` keeps the refusal described above.
## Diagnose, update, and remove
`rea doctor --json` is strictly read-only. `rea update` updates only the npm or Bun global installation that owns the running CLI. Source checkouts and package-runner copies must be updated through the mechanism that owns them; a fresh package-runner invocation can use `npx rea-agents@latest` or `bunx rea-agents@latest`. `rea uninstall` removes only REA-owned agent registrations and skill files; `--purge-data` additionally removes REA cache and state paths.
@@ -429,11 +443,19 @@ and other MCP servers. Purging removes REA's legacy cache and state under
archives under `${XDG_CACHE_HOME:-~/.cache}/rea/hopper-releases`. Other cache
namespaces remain intact. A caller-selected `REA_KUNA_CACHE_DIR` is retained
and reported because REA cannot establish ownership of its entire contents.
Lexically equivalent spellings of that default directory, including a trailing
separator, a `.` segment, or a repeated separator, share its purge result.
The comparison preserves POSIX `..` traversal and literal backslashes.
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. Uninstall reports each
candidate `configuration_path` with its outcome. A client with multiple files
keeps their individual `actions` alongside its aggregate status and detail,
path stops the operation before anything is removed when that client's
product applicability is established or unresolved. Shared registration
storage such as `~/.agents/mcp.json` whose product cannot be established
(for example when FreeBuff and ZCode discovery directories are absent) is
retained unchanged and does not block other REA removals, including cache
and state deletion with `--purge-data`. A client that fails 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
@@ -495,6 +517,10 @@ Do not rename `index.cjs` to `index.mjs` or disable protection to make startup p
### Update the owning installation
Read-only metadata and version checks time out after 10 seconds. This does not
interrupt a package installation already in progress. If a probe cannot be
stopped, the updater reports a cleanup failure.
`rea update` installs the exact resolved
release into the npm prefix or Bun global directory that owns the running
package, then checks the new executable's version before reporting success.
@@ -525,8 +551,8 @@ non-TTY, and JSON modes without applying configuration changes.
## Released package and main
Repository main documents its current code and generated catalog. `@latest`
selects the npm release, and persistent MCP registrations are pinned to the
version that performed setup. Installing newer instructions does not update a
selects the npm release, and managed MCP registrations bind the installation
that performed setup. Installing newer instructions does not update a
running server or its registration.
The npm release checked on **2026-10-11** was **6.4.0**, published from
@@ -649,6 +675,10 @@ an existing Hopper launcher is selected through `HOPPER_LAUNCHER_PATH`. Ghidra
and IDA have their own provider-specific host requirements; Windows Ghidra uses
the [experimental P0 boundary](windows-ghidra-p0.md).
If the Linux package download receives an HTTP failure, setup includes the
observed HTTP status in its `download_failed` diagnostic. The status does not
establish the underlying cause or guarantee that retrying will succeed.
Hopper metadata and package downloads require HTTPS throughout the redirect
chain; a redirect to HTTP is refused before that destination is requested.
@@ -825,9 +855,13 @@ stage `connection`.
If macOS denies Apple Events, allow the application that starts REA under
**System Settings → Privacy & Security → Automation**, then retry. REA releases
the target reservation when the native helper reports its complete authorization
rejection and its arguments cannot alter the helper's generated AppleScript.
Arguments containing quotes, backslashes, or line breaks remain unchanged but
cannot establish that a failed handoff opened no document. Other failed handoffs
rejection after literal argument admission. Before application handoff, REA refuses
double quotes, backslashes, or line breaks in the final launcher path or arguments,
with `details.launch_rejection.boundary: "argument_encoding"` and the affected source/index.
Select literal-safe launcher/runtime paths and loader arguments, or another
compatible provider. REA preserves original file names and evidence: a quoted
executable name can still work when its prepared image path is literal-safe;
database paths must themselves be representable. Other failed handoffs
retain ownership until document closure is confirmed. If a timed-out bridge
becomes ready later, `close_binary` connects to that run, authenticates its
identity, and requests document shutdown. Once its listener is ready, the bridge
@@ -894,7 +928,12 @@ selected only when it is the arm64 family's only candidate. REA checks the
entire source's SHA-256 while copying the slice; source identity and reported
offsets still refer to the original container. Any other ambiguous architecture
subtype requires an explicitly extracted thin image; REA does not guess.
Configured loader arguments remain explicit overrides.
Set `HOPPER_LOADER_ARGS_JSON` in REA's launch environment to a JSON array of
strings to override the derived Hopper loader arguments, for example
`["-l","Mach-O"]`. Empty string elements are preserved; NUL bytes are not
accepted. An omitted setting or empty array uses the derived arguments. `rea
setup` forwards an explicitly selected setting to supported registrations;
restart the MCP server to apply a change. These arguments are Hopper-specific.
FAT64 is distinct from the CPU architecture: FAT32 containers can contain 64-bit
executable images. This preparation avoids the Raw Binary loader dialog observed
with native FAT64 loading on Hopper 6.1.0-demo.
@@ -966,7 +1005,7 @@ copying license secrets into logs, or killing unrelated Hopper processes.
REA connects to an existing Ghidra installation on Linux x64/arm64, macOS x64/arm64,
or experimental Windows x64 P0.
It accepts Ghidra 12.1.x and the 64-bit full JDK declared by that installation's
It accepts Ghidra 12.x (>=12.1) and the 64-bit full JDK declared by that installation's
`application.java.min` and `application.java.max`. The JDK's reported platform must also
map to the same native decompiler directory as the host: a JDK running under
emulation (for example x86_64 under Rosetta on Apple silicon) or reporting a
@@ -974,7 +1013,8 @@ non-host `os.name` fails the doctor
even when it is an otherwise accepted 64-bit full JDK. Select a matching JDK
through `JAVA_HOME`; adding another decompiler in the JVM-selected directory
does not satisfy this host-validated admission rule. Current 12.1 releases require
JDK 21 or newer and set no maximum. The bridge is verified with Ghidra 12.1.4
JDK 21 or newer; Ghidra 12.2 declares JDK 25 or newer. Neither sets a maximum.
The bridge is verified with Ghidra 12.1.4
and JDK 21. Each installation must include the native decompiler for the host
architecture in `Ghidra/Features/Decompiler/os/<platform>/` or the corresponding
`build/os/<platform>/` directory. Linux ARM64 uses `linux_arm_64`; official
@@ -985,7 +1025,7 @@ reported as incompatible instead of being admitted from its directory name, and
a header that cannot be read or recognized is reported as unknown. REA does not
build or install native tools, or change Gatekeeper quarantine settings.
The adapter exposes 26 read-only operations: fourteen inventory/name/search
The adapter exposes 27 read-only operations: fifteen inventory/name/search
operations and twelve function-analysis operations. These cover metadata,
decompilation, assembly, resolved calls, typed references, xrefs, function
dossiers, instructions, recovered data types, measured load mappings, loaded
@@ -1064,14 +1104,15 @@ rea providers --json
```
`rea setup` can configure supported Windows agents and install the bundled
REA skill after approval. Direct registrations use Node to launch REA's entry
script; package-runner registrations use the pinned `npx` or `bunx` command. Hopper
REA skill after approval. Managed registrations use the absolute selected Node or
Bun runtime and REA entry script, including when setup ran through a package runner. Hopper
installation remains unavailable on Windows. Setup never installs Ghidra,
Java, or Python. It preserves valid detected Ghidra/JDK settings in agent
registrations. See [Windows Ghidra P0](windows-ghidra-p0.md) for provider diagnostics.
The separate `rea mcp add` builtin currently uses Incur's package-runner child
launcher, which can fail on Windows with `MCP_ADD_FAILED: spawn npx ENOENT`
The separate `rea mcp add` builtin delegates most clients to Incur's package-runner
child launcher. Run that acquisition from a trusted directory; prefer managed
`rea setup` when supported. That child launcher can fail on Windows with `MCP_ADD_FAILED: spawn npx ENOENT`
before registering a client. REA's setup path is unaffected. For a client supported
by setup, review `rea setup --client opencode --skill=false --dry-run --json`
(substitute its client ID), then use the same scoped command without `--dry-run`
@@ -1089,7 +1130,7 @@ the application metadata and headless launcher. An explicitly supplied
REA reports that error instead of silently selecting another installation.
This discovery is read-only and does not execute the Ghidra launcher.
Doctor validates the platform, architecture, Ghidra 12.1.x application version,
Doctor validates the platform, architecture, Ghidra 12.x (>=12.1) application version,
`support/analyzeHeadless` or `support/analyzeHeadless.bat`, the installation's
Java major range, 64-bit JDK bitness, and the presence of `javac`/`javac.exe`.
It also checks that the reported JVM `os.arch` and `os.name` map to the same native decompiler
@@ -1145,9 +1186,10 @@ This coordinate selects only REA's session-private configuration directory, not
the installation or an existing user configuration directory.
Each verified session uses an ephemeral temporary project and isolated
home/cache/config/temp paths. REA passes `-readOnly`, `-deleteProject`, uses
Ghidra's default analysis settings, and loads its packaged Java
bridge via `-scriptPath`; it never opens an existing user project. Linux and
home/cache/config/temp paths. By default REA passes `-readOnly`, `-deleteProject`,
uses Ghidra's default analysis settings, and loads its packaged Java
bridge via `-scriptPath` into a new ephemeral project; opt-in
[existing-project reuse](#reuse-an-existing-ghidra-project) opens only an owned copy. Linux and
macOS use a current-user-only local bridge socket and descriptor. The
project remains under the selected temporary directory. If its Unix socket
pathname would exceed the host's byte limit, REA allocates a separate owner-only
@@ -1166,7 +1208,7 @@ original process owner for a later cleanup retry.
The experimental Windows transport uses authenticated IPv4 loopback with a
private native-owned bearer descriptor and Job Object process ownership.
Operations begin only after default auto-analysis completes. `open_binary`
In the default fresh-import mode, operations begin only after default auto-analysis completes. `open_binary`
selects and validates the target/provider binding; it does not wait for Ghidra
import and auto-analysis. The first Ghidra-backed query starts that work lazily.
The provider startup deadline is 330,000 ms by default for import, analysis,
@@ -1297,6 +1339,63 @@ not needed for the make step, only for the Ghidra provider. If your toolchain
rejects the inherited `-mmacosx-version-min=10.6` flag, retry the make with
`ADDITIONAL_FLAGS="-w"`.
### Reuse an existing Ghidra project
For repeated investigations, select an expanded local project marker with
`REA_GHIDRA_PROJECT_PATH=/absolute/projects/app-analysis.gpr`. Both CLI and MCP
use this shared selection. `REA_GHIDRA_PROGRAM_NAME` selects one exact program
in the project root; when omitted it defaults to the selected target's filename.
Paths, globs and command flags are not program names. The matching `.rep`
directory must be present; restore `.grez` archives with Ghidra first.
```bash
export REA_ANALYSIS_PROVIDER=ghidra
export REA_GHIDRA_PROJECT_PATH=/absolute/projects/app-analysis.gpr
export REA_GHIDRA_PROGRAM_NAME=app
rea decompile /absolute/target/app --procedure entry --provider ghidra --json
```
Set the same variables in the MCP server environment and restart/reconnect;
`open_binary` still selects the original target file. `rea setup` retains these
explicit settings in a saved registration. Fresh import remains the default
when the project setting is absent. This route supports native ELF, PE and
Mach-O programs on POSIX without provider-pinned import preparation; Windows,
raw/DOS/DOL and special pinned-language import profiles require fresh import.
REA fingerprints only the selected `.gpr`/`.rep` pair, copies it into its owned
runtime, verifies the copied content against the committed analysis profile,
and runs `-process <program> -noanalysis -readOnly`. Ghidra never opens or saves
the original database; REA reads selected files only for fingerprinting and copying.
This mode does not copy unrelated sibling projects, rerun repair scripts, or
admit bridge database edits. Cleanup removes the owned copy.
The bridge checks the program's recorded import SHA-256 against the admitted
target digest; mismatches and project changes fail explicitly. Reopen the target
to resolve a new profile after intentionally changing the source project.
The profile records the caller path, resolved project/name, program and content
fingerprint. Original analysis settings and completeness remain **unknown**;
prior annotations or edits are caller-project state, not fresh REA discoveries.
A matching recorded import digest does not claim that the database is unedited.
Saved REA seed/analyzer reports remain historical facts in retained source Evidence;
they are not interpreted as overrides applied by this session.
Project content participates in snapshot identity, so different project states
cannot reuse the same profile's cached observations.
To prepare a new project explicitly, use your existing Ghidra installation in a
new directory you own (this writes that project; REA does not save it for you):
```bash
mkdir /absolute/new-projects
GHIDRA_HEADLESS_MAXMEM=1536M JAVA_TOOL_OPTIONS=-XX:ActiveProcessorCount=2 \
"$GHIDRA_INSTALL_DIR/support/analyzeHeadless" /absolute/new-projects app-analysis \
-import /absolute/target/app -analysisTimeoutPerFile 600 -max-cpu 2
```
Check that preparation completed successfully before selecting the project.
Preparation time, disk copy/fingerprinting, engine startup and client deadlines
are separate costs; reusing a project avoids import/analysis, not all startup.
Use the [heap/CPU controls](#ghidra-heap-and-cpu-controls) appropriate to the target.
### Ghidra import language and analysis seeds
Ghidra detects the language from the executable header. To set it (for example, Borland C++ PE images):
@@ -1351,6 +1450,21 @@ current setting. For Windows PE resource analysis, the exact name is
`WindowsResourceReference`. Disabling an analyzer skips the facts it would have
produced.
Ghidra's Objective-C Message Analyzer can log
`Required Objective-C data type not found in data type manager` /
`Try adding libobjc.dylib` when a Mach-O links Objective-C runtime symbols but
defines no class metadata (thin Cocoa glue in a C++ binary is a common case).
That text is non-fatal Ghidra analyzer output: auto-analysis continues, and the
analyzer simply skips `objc_msgSend` call-target recovery. REA's headless import
does not accept a "add this library" option, and on modern macOS
`/usr/lib/libobjc.A.dylib` exists only in the dyld shared cache, so there is no
on-disk library to add. Treat the line as a coverage limitation, not an REA
failure; check the session's `failure_kind` (and related provider errors) for
any real abort. To silence that analyzer, set
`REA_GHIDRA_DISABLED_ANALYZERS="Objective-C Message Analyzer"`. For large
executables that miss the startup deadline instead, raise
`REA_GHIDRA_STARTUP_TIMEOUT_MS` and the [Ghidra heap](#ghidra-heap-and-cpu-controls).
### Ghidra heap and CPU controls
Set resource controls in the environment that launches the CLI or MCP server,
@@ -1446,12 +1560,93 @@ On a controlled Windows x64 runner, use
`npm run verify:ghidra:windows`. The verifier generates a deterministic native
PE fixture from source bytes and requires the Windows native authority before
opening the provider. The controls are implemented on main; see the
[release boundary](#released-package-and-main). The lane verifies all 26 admitted
[release boundary](#released-package-and-main). The lane verifies all 27 admitted
read-only operations, digest identity, and runtime cleanup. The separate
`verify:ghidra:windows:package` lane checks the packed CLI/MCP boundary with an
ordinary user. It requires the built Windows native bundle and an existing
Ghidra/JDK installation; neither is inferred from startup alone.
## Agent plugins and marketplaces
REA's npm package is the shared Claude Code and Codex plugin artifact. It
contains `.claude-plugin/plugin.json`, `.codex-plugin/plugin.json`, and the
canonical generated `skills/` tree. Both manifests select `./skills` and run a plain Node bootstrap pinned to
that exact package version. The client must have a supported standalone `node`
on its PATH. Claude expands its documented `CLAUDE_PLUGIN_ROOT` in the script
argument; Codex resolves `cwd: "."` from the installed plugin root before
launching the relative script. The bootstrap verifies the package version and runs its bundled runtime in
the same process, preserving stdio and REA's provider/worker cleanup. It does
not start another package runner or download a different runtime. The existing release skill
generator also pins CLI recovery commands to the same version.
The repository's single-plugin marketplaces are declared in
`.claude-plugin/marketplace.json` and `.agents/plugins/marketplace.json`.
Both select an exact `rea-agents` npm version instead of mutable source-checkout
contents. Release Please updates their selectors alongside the plugin manifests.
No plugin-only publication or generated skill files committed to Git are needed.
The qualified release archive contains a runtime-only manifest and
`npm-shrinkwrap.json` plus bundled runtime dependencies, including PTY packages
for each supported OS and CPU; development dependencies and development-only overrides
stay in the source manifest and lockfile. Both clients receive this same archive.
This distribution becomes installable after the first qualified npm release
containing these plugin manifests. Earlier published packages are not changed
by this source proposal. For local source development, run `npm ci && npm run build:cached` to generate
the runtime and packaged skill before loading the repository as a plugin.
A source plugin uses the locally built runtime and generated skill; rebuild after
source changes. Missing builds and mismatched version pins fail with an actionable
error. The authored `.agents/skills/` tree is not the plugin's shipped skill layout.
Windows source workflows that need native controls still require the
[Windows source-checkout build](https://github.com/morluto/rea/blob/main/native/windows/README.md#build).
In Claude Code:
```text
/plugin marketplace add morluto/rea
/plugin install rea@rea
```
In Codex CLI, add the marketplace and install REA:
```bash
codex plugin marketplace add morluto/rea
codex plugin add rea@rea
```
Each release updates both manifest versions and their pinned server version
together, which is when installed copies refresh the bundled skill and move to
the new server. A plugin does not run `rea setup`, so provider
configuration still follows the sections above. Use the plugin or a
`rea setup` registration for a client, not both, to avoid two `rea` servers.
`rea doctor` does not see plugin-owned state. Its client and skill checks read
only the registrations and skill locations that `rea setup` manages, so for a
plugin-only install `rea doctor --client <id>` and `rea doctor --skill` report
`missing` and recommend `rea setup`. Do not follow that remediation. Check the
plugin with the client instead (`claude plugin list` and `/mcp` in Claude
Code, `codex plugin list` in Codex).
For analysis engines, ask the connected server: have the agent call
`binary_session` and read `result.tool_availability`, which reports what the
server the plugin started can use, with reasons and remediation. See
[MCP contracts](mcp-contracts.md).
A plugin does not put `rea` on your `PATH`. To check an engine from a
terminal, use the package runner at the version the plugin pins:
<!-- x-release-please-start-version -->
```bash
npx -y rea-agents@6.8.0 doctor --provider ghidra --json
```
<!-- x-release-please-end -->
If your installed plugin is older, use the version in its manifest instead.
That report describes the terminal's environment, not the plugin server's.
The server inherits the client's environment, so a setting such as
`GHIDRA_INSTALL_DIR` that exists only in your terminal does not reach it.
## MCP Registry
REA is published in the official MCP Registry as `io.github.morluto/rea`. Registry
@@ -1462,40 +1657,45 @@ For a client that supports Registry discovery, search for `io.github.morluto/rea
and select the npm package. The published metadata launches the existing stdio
server through `npx` with the `mcp` command.
For a client that requires manual configuration, use:
For supported clients, prefer `rea setup`: it records the absolute JavaScript
runtime and entry script of the REA installation performing setup. Client starts
then use that installation directly, keeping the client's working directory
without running npm or Bun package resolution there. Registry clients control
their own package acquisition; Registry metadata cannot name local absolute paths.
<!-- x-release-please-start-version -->
For manual stdio configuration, substitute the absolute paths of an existing
installation (use the command shown in a setup dry-run):
```json
{
"mcpServers": {
"rea": {
"command": "npx",
"args": ["-y", "rea-agents@6.8.0", "mcp"]
"command": "/absolute/path/to/node",
"args": ["/absolute/path/to/rea/scripts/rea.mjs", "mcp"]
}
}
}
```
<!-- x-release-please-end -->
Run current setup to migrate recognized older `npx`/`bunx` registrations, with
backups, then restart the client. Unrelated or unidentified registrations remain
untouched. Setup does not prewarm a separate package-runner command.
Persistent registrations should use one exact package version. `rea setup`
writes the same package-runner shape, or `bunx rea-agents@<version> mcp` when
setup runs through `bunx`, and pins it to the exact version that performed
setup. Run current setup to refresh an older registration, then restart the
client.
Package runners key their package cache by the requested spec, so the entry
installed for the `@latest` invocation that ran setup cannot serve the pinned
registration. Setup therefore materializes the pinned entry once, best-effort
with a bounded timeout, before finishing. When that step cannot run, for
example offline, the first client start performs the one-time install inside
the client's MCP startup deadline and may need one more restart.
If setup itself runs from a package-runner cache, the registration depends on
that cache entry and the selected runtime remaining installed. Removing either
makes startup fail; it does not download or resolve another package. Restore the
same installation and rerun setup. Changing package requests, cache roots, or
runtimes can create a different installation identity. If the old entry cannot be
identified, restore it first or manually remove the confirmed REA registration
before running setup again. A global installation provides a more durable path.
## Package runners and global installation
A package-runner invocation can use a REA version installed in the current project. To
request the latest release explicitly, use:
Package runners can select project-local packages and read project configuration,
even for explicit version requests. Acquire REA from a trusted working directory,
outside the target project, and pass absolute target paths to analysis commands.
REA cannot validate package acquisition that happens before its entrypoint starts.
To request the latest release explicitly, use:
```bash
npx rea-agents@latest setup
@@ -1512,16 +1712,14 @@ For an intentional rollback, make the package request explicit:
npm exec --yes --package=rea-agents@2.4.0 -- rea setup
```
Setup continues to pin persistent MCP registrations to the exact version that
performed setup. Running current setup later migrates unversioned or older
managed registrations through the normal reviewed setup transaction.
Setup binds persistent MCP registrations to the installation that performed setup.
Running current setup later migrates recognized legacy package-runner registrations
through the normal reviewed setup transaction.
With Bun, `bunx rea-agents setup` (or `bunx rea-agents@latest setup`) is the
equivalent entry point. Setup run through `npx` registers
`npx -y rea-agents@<version> mcp`; setup run through `bunx` or `bun x` registers
`bunx rea-agents@<version> mcp`. On Windows, setup wraps either command in
`cmd.exe /d /c` so clients can start the runner's command shim. Neither
registration points into the runner's temporary package cache.
equivalent acquisition entry point. Managed registrations use the selected Bun
executable and REA entry script directly. Windows registrations likewise use
absolute runtime and script paths, without a package-runner command shim.
REA supports Node.js 22.x (>=22.23.4), 24.x (>=24.22.1), and 26.12.1+. Node.js 23, 25, earlier 26.x releases, and prereleases are unsupported. It uses the npm already paired with that runtime and never upgrades Node.js, npm, or Homebrew.
@@ -1555,8 +1753,9 @@ Review the plan, approve the selected client changes, then restart those clients
This registers the installed entrypoint directly; installing the global package
alone does not replace existing `npx` registrations. Each client still has its own
REA process and analysis state. Direct registrations follow the installed CLI;
use `rea update` to update it. Running setup through `npx` again selects the pinned
package-runner command. Do not register paths inside npm's temporary package cache.
use `rea update` to update it. Running setup through `npx` again selects the
installation that executes setup, potentially in npm's temporary package cache;
retain that cache entry for as long as the registration uses it.
### npm workspace errors before REA starts
+46 -1
View File
@@ -156,6 +156,21 @@ Select one literal seed kind: node ID, route, string, API, IPC channel, module,
or native export. Matching is exact or literal substring matching; regular
expressions and executable predicates are not accepted. The trace includes all
matching seeds and the complete graph reachable in the selected direction.
`both` follows relationships in either direction, except that a container
reached through `contains` from one of its children only leads further up its
containment chain, so a shared asset or artifact root does not pull in its
other children.
When a string seed has no application match and the supplied Evidence has a
semantic graph, `semantic_discovery` lists matching retained semantic node
labels and direct string call arguments using the same matching mode and case
rules. These are candidate starting
points, not application trace matches. Its graph coverage and total describe the
retained graph; missing or partial source coverage cannot establish absence.
Results follow retained node order and default to offset 0 and limit 64. Supply
`semantic_page` and follow `next_offset` for further matches. Use a returned
`trace_seed` with the same application Evidence and `trace_javascript_semantics`
to examine relationships from that node. Other typed seeds do not search labels.
The result contains the matching basis, complete reachable subgraph, terminal
paths, authority summaries, and native handoffs. A handoff binds
@@ -183,6 +198,10 @@ rereading mutable files. A seed may identify a semantic or application node,
literal, function fingerprint, property, endpoint, event, or boundary field.
For a recovered parse, coercion, or validation boundary, its field value is the
static operation's method name (for example, `Number`).
When a recovered boundary call directly supplies a scalar binding, the graph
connects the boundary to that binding; unresolved boundary calls remain
candidates. A boundary nested inside another expression or compound assignment
does not establish a direct result binding.
The query declares backward provenance, forward influence, callers, or
ownership and can restrict admitted relation kinds. REA returns every matching
seed and the complete reachable subgraph; callers do not choose node, relation,
@@ -205,6 +224,25 @@ resulting value. Deferred callback bodies do not become inputs to the enclosing
assignment. Computed method keys belong to the enclosing callable; parameter
defaults and method bodies belong to the method. Uncertain later property reads
remain opt-in through `include_ambiguous_dynamic_edges`.
Binary, logical, unary, template, conditional, and sequence expressions retain
`influences` edges from supported immediate inputs to the result, then to a
direct declaration, assignment, call argument, or return. These are static
dependencies, not aliases or proof that the expression executed; conditional
operands and logical-assignment writes carry `conditional: true`. Unsupported
operand dependencies, unmodeled receiving containers, dynamic call results,
and sequence side effects remain unknown. An applicable
unknown makes the trace status `partial` even when a seed was found. Literal
operator operands, direct call arguments and directly returned scalar literals
can also be seeds. Older graphs that only recorded a call-site literal remain
searchable. The offered per-file node capacity also bounds the producer's
expression and operand collections before graph projection.
Expression nodes and unknowns share the existing per-file graph admission
budgets; omitted facts make graph coverage truncated and the trace partial.
Consumers that previously treated `found` as compatible with a relevant
unknown should handle `partial` and inspect the returned unknowns. Retained
graphs without `influences` edges remain readable but do not gain edges until
the application is analyzed again.
Global timer, `fetch`, `WebSocket`, `JSON.parse`, and coercion calls receive
these built-in effects only when the file has no visible possible write to that
global, including a computed write through a global object. The check does not
@@ -269,7 +307,14 @@ mapped candidate, but structural reachability, semantic influence, runtime
observation, and causal proof remain separate claims.
Semantic literal nodes keep their complete value in `properties.value`; literal
queries match that field. String labels use `string literal` when that is
queries match that field. Call-site nodes also retain direct scalar arguments in
`properties.arguments`, with source argument indexes; literal queries can start
at those call sites. These are syntactic facts, not runtime values, and an index
after a spread is not necessarily the runtime argument position. Nonliteral
arguments and values not representable in JSON are omitted. The primitive byte
bound and the worker transfer record ceiling can also omit direct values; the
call-site unknown reports the applicable limit. String labels use
`string literal` when that is
shorter than the complete JSON value. A literal's `identity.role_key` commits
its canonical JSON value as `value-sha256:<digest>` when the digest key is
shorter; smaller values keep their existing JSON key. This keeps large values
+45 -7
View File
@@ -72,6 +72,18 @@ code-point order. Dependency manifests remain package observations but do not
declare Electron main or renderer entries. If only dependency manifests are
present, the inventory artifact remains the graph root.
Package observations use `renderer_declarations` to record the actual present
fields: strings, including empty strings, remain exact; non-string values use `{ "status": "non-string" }`
without copying nested browser mappings. An empty record means no such fields
were present; `null` means package metadata was invalid or unavailable. Renderer
role mechanisms and package load edges name the field that supplied the candidate,
selected as the first nonempty string from `renderer`, `browser`, then `module`.
The package load edge retains `declared_path`, `source_field`, and resolution
facts for that selection. New analyses no longer emit the derived package
`renderer` alias; consumers must read declarations for source metadata and load
edges for the selected candidate. Previously retained Evidence keeps its original
properties and remains readable without migration.
## Select sources before analysis
For a question about known entry sources, supply exact artifact-relative file
@@ -239,10 +251,12 @@ An unpacked entry whose companion bytes were not supplied remains
`unavailable`. REA continues analyzing embedded JavaScript and records the
missing native/resource bytes as unknown. The occurrence keeps
`hash_status: unavailable`; no content-addressed child artifact is created for
those missing bytes. New inventories preserve an ASAR companion declaration as
`unpacked: true`; an omitted flag in an older inventory does not establish that
unavailable bytes belonged to a companion. See [MCP integrity handling](mcp-contracts.md#integrity-record-and-continue)
for the tool-result contract.
those missing bytes. New ASAR file occurrences record `unpacked: true` for
companion files and `unpacked: false` for packed entries, including when the
file bytes are unavailable. An omitted flag in an older inventory remains
unknown; it does not establish either storage mode. See
[MCP integrity handling](mcp-contracts.md#integrity-record-and-continue) for the
tool-result contract.
JavaScript whose syntax cannot be parsed retains unavailable semantic coverage
with `incomplete-module` unknowns for each semantic family and unknown omitted
@@ -350,6 +364,13 @@ Selected bounded text is then parsed as inert data to recover:
relative to the calling module; string worker and service-worker paths use
the document base URL or Node's working directory, which static analysis
does not establish, so they keep their expression and stay unresolved);
- Vite preload dependency tables (`__vite__mapDeps`): `./` entries resolve
relative to the importing chunk; base-relative entries such as
`assets/chunk.js` carry a `vite-output:` specifier and resolve under the one
ancestor directory of the importer that holds them, the build output
directory. A file found there but not analyzed, such as a stylesheet, stays
`unavailable` with its path. Selecting only the assets directory leaves them
`not-found`;
- route, network endpoint, storage, and vendor-marker observations;
- local source-map declarations and original
source names and content digests;
@@ -426,8 +447,17 @@ and links whose callee was renamed by a minifier are not recognized.
Bundler adapters own callback roles: Webpack supplies module, exports, then
loader; esbuild CommonJS supplies exports, then module. Export extraction uses
those binding identities for assignments and declarations, so renaming either
parameter does not change the recovered names. Global property-definition
intrinsics require lexical and visible-write proof. Factory export declarations
parameter does not change the recovered names. The convention always supplies
every role argument, so a role parameter's default never runs: a defaulted
module or exports parameter keeps its role, and the default expression yields
no exports, references or chunk keys. `{exports: alias}` in the module position
binds `alias` to `module.exports`.
Other role patterns, such as rest, array, nested or computed-key patterns or a
non-identifier loader, receive no role and count as unknown findings, so the
file's analysis is partial rather than an exact empty export list. An
export-shaped write through a role binding whose value at that read cannot be
ordered against a replacement is also an unknown finding. Global
property-definition intrinsics require lexical and visible-write proof. Factory export declarations
also require the loader's `d` member to have no prior or unordered visible
replacement, including writes through lexical aliases. Unrelated loader members
do not invalidate declarations. Ordering describes declarations within one factory
@@ -530,6 +560,8 @@ alternative object. A traced invocation whose key, API object or world stays
unresolved or guarded keeps the call's own unresolved observation.
Unknown spreads, reassigned bindings, accessors,
dynamic channels and unsupported syntax do not become exact implementations.
Literal switch cases retain their selection conditions. Possible fallthrough
remains partial; dynamic case expressions remain unknown.
This pass neither executes the bundle nor proves that runtime guards pass.
An ambiguous or unresolved handler retains its channel registration but does
not acquire a path to one arbitrarily selected callback. Unknown factory
@@ -612,7 +644,13 @@ identity. This static check does
not evaluate arbitrary call side effects or runtime registration. Missing findings
do not establish that an application has no Electron boundary usage.
IPC pairing is an inference, not an observation. A renderer `invoke` pairs only
IPC pairing is an inference, not an observation. A main handler registered on an
unresolved channel may receive any literal channel, so a compatible renderer send
or `invoke` beside it is ambiguous, not unpaired. A wrapper's registration is
exempt only when every invocation is a traced direct call supplying a literal
channel, each recorded as its own finding. A guarded invocation keeps its
predicate on a call path instead, so its channel still competes without pairing.
A renderer `invoke` pairs only
with one unique `ipcMain.handle`/`handleOnce` candidate on the same exact literal
channel; a renderer send pairs only with one unique `ipcMain.on`/`once`/`addListener`
candidate. Dynamic channels are never paired, and multiple compatible handlers
+36 -4
View File
@@ -25,18 +25,50 @@ Keep the original analysis inputs in that call. For the CLI, pass the same
selection as `--view '<JSON>' --detail summary --evidence_output routes.json`.
The complete Evidence bundle is written without overwriting existing files.
Unselected delivery retains the existing complete result. A web-bundle summary
requires an explicit route view; application summaries also support the existing
requires an explicit route or web-bundle view; application summaries also support the existing
general summary when `view` is omitted.
Use the returned `normalized_result.parent_evidence_id` with
`inspect_analysis_view` on the same connection. The CLI's exported bundle can be
reopened with `inspect-evidence-bundle`; its `records` contain the complete
Evidence. To use `inspect_analysis_view`'s `evidence-file` source, extract the
selected parent record into a separate local Evidence JSON file (that source
accepts one Evidence record, not a bundle). Views do not reopen source files or
Evidence. `inspect_analysis_view`'s `evidence-file` source accepts either one
Evidence record or an exported bundle with the selected `evidence_id`.
Views do not reopen source files or
reconnect to a browser. Historical Evidence without `route_inventory` is
unmeasured, rather than an empty route set.
## Page captured endpoint observations and inferences
For `analyze_web_bundle`, select `detail: "summary"` and
`view: {kind: "web-bundle", collection: "endpoints", limit: 32}`. The CLI
accepts the same JSON through `--view`, with `--detail summary` and
`--evidence_output bundle.json`. Query the returned parent with
`inspect_analysis_view` to read `endpoints`, `inferences`, or `summary` without
recapturing the page or repeating JavaScript analysis.
Both row collections accept exact `indices`, `values`, `script_keys`, `fields`,
`offset`, and `limit`; endpoints also accept `mechanisms`, and inferences accept
`kinds`. Filters combine with AND, and an explicit empty selector matches no
rows. Every row retains its `source_index` in the original collection, including
when other fields are omitted. This identity is scoped to the parent Evidence
and collection. Original ordering and separate occurrences of duplicate values
are preserved; request endpoint `location` or inference `basis` for source details.
Follow `coverage.next_offset` until `coverage.exhausted`; those fields describe
the selected rows, independently of producer `completeness`. Each response also
preserves structured `source_unknowns`, including `affected_script_keys`, so a
filtered or value-only page cannot hide a source gap. The summary's
`limitation_count` counts distinct parent and report limitations before display
bounding. An `endpoint_candidate` remains an inference, with its original
confidence and basis, and does not prove a backend endpoint or reachability.
Pages obey the shared 1 MiB projection budget; MCP transport applies its own
wire-size guard. A byte-limited page returns a continuation; an indivisible
oversized record or metadata returns a typed resource error. Select fewer
fields or retrieve the complete retained parent through `get_evidence_bundle`,
`export_evidence_bundle`, or the CLI's exported bundle. Full Evidence is never
silently truncated.
Collections are `summary`, `routes`, `occurrences`, `sources`, and `unknowns`.
All row collections support exact batch `where.ids`, field selection, `offset`,
and `limit`. An explicit empty filter array matches nothing. Routes also support
+3 -1
View File
@@ -99,7 +99,9 @@ nodes. REA evaluates compatible static candidates conservatively:
content digest can match. Whole-asset digests and reconstructed module-factory source
digests remain distinguishable in the reported basis.
3. Without captured bytes, one unique mapped artifact path can produce a
medium-confidence location match.
medium-confidence location match. A proven factory module contained within
the located asset is not a competing whole-file location; separate assets
and independently plausible modules remain candidates.
4. Multiple candidates remain `ambiguous`; no `observed_as` edge is emitted.
With captured source and mapped candidates, only mapped content matches
qualify; unrelated content matches elsewhere are excluded.
+1 -1
View File
@@ -63,7 +63,7 @@ All four preserve target-file bytes. `open_jeb_project` selects or creates an en
- 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.
- Valid engine refusals (`success: false` envelopes) return `execution_failure` with the engine's message when available. Diagnostics preserve the original envelope, including any recovery advice, and the inputs of a refused primary request. If client metadata fails after a primary reply, that reply and the caller's inputs remain in partial Evidence. REA does not infer an unsupported target from a refusal, invoke a recovery tool, or retry the request.
- 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.
+13 -1
View File
@@ -125,7 +125,19 @@ REA writes Kuna's exports only inside `REA_KUNA_CACHE_DIR`:
- `trash/` holds retired builds and evicted exports awaiting removal.
- `home/` is Kuna's HOME.
Builds publish by one rename, so a reader sees a complete export or none. If later staging retirement fails, the typed cleanup error retains the completed export's key, directory and manifest in `published_export`. The session adopts that verified project; later queries reuse its immutable files while `project_export.cleanup_incomplete` reports the retained owner's live state. `close_binary` retries only the remaining cleanup, and a successful retry resolves prior cleanup errors. A failed export followed by failed staging cleanup retains both failures; it does not invent a publication receipt. A session keeps the export it uses from eviction only within its own REA process. If another REA process sharing the cache evicts it, the session rebuilds it; meanwhile pseudocode falls back to single-function runs. A damaged or edited export is removed and rebuilt. Staging moves to `trash/` for removal only after REA proves its Kuna process stopped. Staging of a process it cannot prove stopped is never swept; REA keeps it owned, retries the stop on `close_binary`, and reports it until the stop is proven. Failed file removal also stays bound to its export and is retried by `close_binary`; closing does not report success while that cleanup remains. `rea doctor --provider kuna` reports the cache directory without creating it.
The cache key includes the selected launcher and resolved executable paths, plus
the target's native basename: that name determines the export filenames and
appears in generated source. REA accepts one current manifest layout. Older
exports are rebuilt on demand and retired through normal owned-cache cleanup;
no manual deletion or migration is needed. Manifests must name the producer's
exact flat file layout, with matching basenames and producing inputs. Replaced
entry, project or manifest symlinks are refused before their targets are read;
an unverified `projects/` parent grants no removal authority. Warm reuse checks
the manifest's file identity as well as the export files. These refusal and
migration cases are verified with controlled Kuna-format exports; they do not
establish behavior of an independently installed Kuna release.
Builds publish by one rename, so a reader sees a complete export or none. If later staging retirement fails, the typed cleanup error retains the completed export's key, directory and manifest in `published_export`. The session adopts that verified project; later queries reuse its immutable files while `project_export.cleanup_incomplete` reports the retained owner's live state. `close_binary` retries only the remaining cleanup, and a successful retry resolves prior cleanup errors. A failed export followed by failed staging cleanup retains both failures; it does not invent a publication receipt. A session keeps the export it uses from eviction only within its own REA process. If another REA process sharing the cache evicts it, the session rebuilds it; meanwhile pseudocode falls back to single-function runs. A damaged or edited export is removed and rebuilt. REA retains the file state verified with each digest, checks it before warm-cache reuse, and checks open descriptors before and after reading text. Assembly indexes are checked against the same state; a changed file makes the whole report retry rather than mixing facets from different exports. Staging moves to `trash/` for removal only after REA proves its Kuna process stopped. Staging of a process it cannot prove stopped is never swept; REA keeps it owned, retries the stop on `close_binary`, and reports it until the stop is proven. Failed file removal also stays bound to its export and is retried by `close_binary`; closing does not report success while that cleanup remains. `rea doctor --provider kuna` reports the cache directory without creating it.
## Verify with a real Kuna
+76 -11
View File
@@ -120,6 +120,50 @@ 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.
To find specific retained members without returning their IL anchors, select
exact names and defining types, then project columns:
```json
{
"source": {
"kind": "retained-evidence",
"evidence_id": "<parent_evidence_id>"
},
"view": {
"kind": "managed-members",
"collection": "methods",
"names": ["ParseNumber", "ParseReadNumber"],
"declaring_types": ["Newtonsoft.Json.JsonTextReader"],
"fields": ["name", "declaring_type", "signature"],
"offset": 0,
"limit": 64
}
}
```
Filters are exact and case-sensitive; lists are alternatives and filters
intersect. An empty list matches nothing. Names select `name` in types,
exported types, fields, methods and member references; in call edges they select
`target_name`, and in field accesses `field_name`. Declaring-type filters select
`declaring_type` in fields/methods, `parent_name` in member references,
`target_declaring_type` in call edges and `field_declaring_type` in field accesses.
Types, exported types and user strings do not accept a declaring-type filter;
user strings do not accept a name filter. No display strings are reparsed.
`fields` accepts only columns of that collection. Omitting it preserves full
rows, including method bodies. Selecting `body` explicitly returns the full
recorded body and anchors; selecting no columns (`[]`) returns identity fields.
Projected or filtered rows add their original `source_index`; tokens and source
byte offsets remain, with defining/parent tokens or IL-site endpoints where
applicable. The page retains module/MVID, artifact digest, parent Evidence,
producer selection and source coverage. Full facts remain in the parent.
Paging offsets and totals count known matches in original order. `source_count`
counts the producer-returned collection; `unresolved_filter_rows` counts rows
that could match but lack a requested name/type. Those candidates remain unknown
and are excluded from the matched total. Exhausting the known matches does not
prove absence among unresolved or unexamined source rows.
#### CLI summary and saved member rows
The CLI accepts the same `complete` and `summary` detail choices. Omitted or
@@ -167,13 +211,17 @@ authenticates the saved bundle; the full source is retained on disk.
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 or infer a NativeAOT identity from an
ordinary native PE. It does not decode IL2CPP; use
it does not itself unpack .NET single-file hosts or infer a NativeAOT identity
from an ordinary native PE. It does not decode IL2CPP; use
[IL2CPP metadata](il2cpp-metadata.md) for the image, type and method names in a
Unity `global-metadata.dat`. Inputs without admitted CLI metadata do not
become managed assemblies through naming or routing guesses.
Inspect separately obtained components explicitly and preserve their identities.
For ordinary .NET single-file hosts, use the existing artifact tools to
[inventory and extract bundle members](dotnet-bundles.md), then inspect the
extracted assembly explicitly with the managed tools.
A valid implementation marker establishes a candidate native boundary, not
recovered native semantics or runtime behavior.
@@ -432,8 +480,18 @@ raw digest stands in. Missing or unreadable TypeDef and TypeRef operands are
reported as coverage issues. Invalid NestedClass rows retain their failure
reasons and withhold TypeDef signature identities; type names and nesting are
parsed once by their shared owner. Each current inspection records
`signature_resolution: "type-names-v1"`, even when none of its operands can be
resolved. Historical Evidence defaults this attestation to `null`. When either
`signature_resolution: "type-names-v2"`, even when none of its operands can be
resolved. Version 2 also appends readable names to signature operands, for
example `class:7772 (AnalysisJob)`. Coded indexes remain build-local references;
names are display text and do not change raw or resolved signature digests.
Nested names use `Outer/Inner`. Generic instantiations keep their decoded
arguments, for example ``class:9 (System.Collections.Generic.List`1)<string>``;
custom modifiers are named too. Valid but unresolved TypeSpecs, invalid scopes,
unreadable type names, cycles and nesting beyond the cap keep their raw operand
spelling. Invalid or missing metadata coordinates retain the existing malformed
signature result and source issue; rendering does not bypass validation.
Version 1 Evidence remains readable and compares using the same digest policy.
Historical Evidence defaults this attestation to `null`. When either
observation predates resolution, both sides compare raw digests, which pair only where type rows agree,
and the comparison reports that limitation. The signature is exact whether or
not REA decoded it, so undecoded signatures pair by that tuple too, but they
@@ -660,13 +718,15 @@ name and raw signature digest available while marking that signature malformed
and coverage partial.
A fat method header's nonzero LocalVarSigTok must name an existing StandAloneSig
row whose blob is a structurally valid LocalVarSig. REA validates its local
types and exact blob coverage but does not project their identities. An invalid
types and exact blob coverage, retaining `local_var_signature` with the raw blob
digest and whether named types, modifiers, or generic variables require metadata
or declaring context. Historical Evidence defaults this field to null. An invalid
token or malformed signature leaves decoded CIL anchors intact but marks the
body malformed and coverage partial. Unsupported local type encodings retain
the readable body with partial coverage. Zero continues to mean no locals
signature. Comparison detects whether a locals declaration is present, but raw
table tokens are not cross-build identities and local type contents are not
compared.
signature. Raw table tokens are not cross-build identities. Comparison uses
validated context-free signature digests; signatures requiring metadata or
declaring context remain unknown across artifacts.
## Decoded-CIL fingerprint
@@ -868,9 +928,14 @@ MethodDef flags or implementation flags value differs, including accessibility
or synchronization changes. Observed method-body `init_locals` and `max_stack`
differences also contribute to `metadata`, even when CIL decoding is incomplete.
For complete bodies, presence or absence of a locals signature also contributes;
the locals table token is build-local and is not compared. Local type contents
are not currently compared, so this facet does not establish equivalent locals
declarations.
the locals table token is build-local and is not compared. Different validated
context-free LocalVarSig digests report a metadata encoding difference without
asserting a semantic type change. Equal digests establish unchanged bytes only
when neither signature requires metadata or declaring context. Historical
unrecorded signatures and context-dependent signatures keep local identity
unknown, preserving any independently observed changes. The same method token
in an artifact with the same authenticated SHA-256 identifies the same local
signature bytes, including for retained historical Evidence.
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.
+339 -44
View File
@@ -26,6 +26,23 @@ can be passed directly to `compare_functions`, and `inspect_artifact` Evidence
to `compare_artifacts`. Use `get_evidence_bundle` when the task needs broader
retained session history or an explicit bundle for transfer.
`compare_artifacts` does not need that Evidence sent back. Name each side once
with a source that `inspect_analysis_view` also accepts:
`{"kind": "retained-evidence", "evidence_id": "<id>"}` for a record retained in
this session, or `{"kind": "evidence-file", "path": "/absolute/evidence.json"}`
for a saved record or bundle. Add `evidence_id` to select one record from a
bundle that holds more than one. Complete inline Evidence is still accepted as
the third form. The comparison cites the records that the sources resolve to,
so all three forms give the same comparison Evidence. A retained reference that
the session cannot resolve is refused with `evidence_integrity_mismatch` and
`details.reason: "missing"`.
`compare_artifacts` can also resolve an artifact summary to its exact retained
parent in the session, or from the authenticated bundle containing a file-selected
summary. File-local records take precedence over the session lookup. Unrelated
records are not retained by the file resolver. Supported historical summaries keep their original
Evidence identity and omissions; a missing or mismatched parent is rejected.
`analyze_function` does not deliver its complete record by default. Without
`detail`, it retains the complete dossier in the session and returns
`inspect_analysis_view` summary Evidence whose
@@ -52,13 +69,14 @@ the same Evidence authentication failures: an admitted source that fails
authentication is `evidence_integrity_mismatch`, while an authenticated source with an unsupported
workflow role or invalid selector is `invalid_request`.
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.
Ghidra inventories, measured load-image observations and function replies use
`raw_result: null` when their useful facts are already preserved in
`normalized_result`, limitations, locations and relationship coverage. Distinct
overview details, file-offset selection roles and database types supplemented
with derived metadata keep their upstream representation. Native load-image
attestation continues to use the bridge reply locally before Evidence
projection. Read function results from `normalized_result`; older retained
Evidence keeps its original representation and identity.
Artifact source-map filename relationships require a unique, identified regular
file at the sibling path. A known directory cannot be the mapped file; the map
@@ -159,8 +177,13 @@ 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
response budget, including request-specific rejected fields and reasons. Zod
input issues retain their field paths and available type and range constraints.
SDK diagnostic parts may be distributed between field issues and the main
message so each retained explanation appears once.
If their conservative projection allowance is exhausted, the response states
that field-level detail was omitted and retains the original SDK diagnostic.
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.
@@ -242,6 +265,36 @@ 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.
`procedure_address`, `procedure_callees`, `procedure_callers`,
`resolve_containing_procedure` and `get_call_graph` also accept `detail: "summary"`
(complete remains the default). The summary includes the first 64 recorded
observations, exact source parameters and provider/profile identity, relationship
coverage where recorded, and the retained complete parent's ID. Continue with
`view: {"kind":"native-observation","offset":64,"limit":64}`. Array positions
retain `source_index`; graph rows additionally retain their original `level`.
Graph pages order levels by Unicode code point and keep original row order within
each level. A recorded empty level is a `status: "empty-level"` row with
`source_index: null`; observation counts include these markers. Graph diagnostic,
limitation and reason IDs index that page's `items.messages` dictionary. Expand
those references to recover exact text, repeated messages, and absent versus
empty optional fields. Failed nodes retain their original error.
These views reference complete source context through `source_context.digest`
and caveat counts. Read it using the same parent with
`view: {"kind":"native-context","facet":"overview"}`. The other facets are
`analysis-profile`, `limitations` and `result-limitations`; all accept `offset`
and `limit`. Overview includes source subject, provider, authority, execution
environment and profile digest. Full profiles and caveat text remain accessible
without repeating them in every fact response. Context digests follow Evidence's
semantic subject identity, so caller-selected path aliases preserve context
identity while responses retain the selected display path. A null profile means
unavailable; null result-limitations means not applicable to a primitive and
is distinct from an observed empty graph limitation list. Until the source
caveats have been inspected, interpretations beyond the returned facts remain
unknown. Exhausted pages describe the recorded observations and do not establish
complete native discovery. The same views work through the CLI with historical
Evidence files or bundles and require no live provider.
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
@@ -267,6 +320,15 @@ unknown metadata. Missing omission counts remain null. Summary output carries
every matching record; actual transport admission still applies. Omitted
`detail` preserves complete canonical bundle delivery; filters require summary.
Residual-unknown mutations reject missing Evidence or unknown references and
unproven verified resolutions with nonretryable `invalid_request` diagnostics.
`details.constraint` carries the validator's `kind`, owning `unknown_id`, and
missing `evidence_id` or `related_unknown_id` where applicable. Correct the
reported input or supply the required retained Evidence; unchanged retries do
not repair these constraints. Rejected mutations leave retained state unchanged.
Revision conflicts remain retryable `revision_conflict`; broken revision histories
remain `evidence_integrity_mismatch`.
`list_unknowns` returns every matching current head by default. For a smaller
inline response, supply `offset` and `limit`, then follow `next_offset` until it
is null. `total` counts all matching heads; each page preserves complete records
@@ -286,8 +348,11 @@ When `record_unknown` or `update_unknown` commits but its complete reply exceeds
the response budget, `details.reported_limits.committed_unknown` identifies the
exact unknown ID, committed revision and mutation Evidence IDs. Its retained
Evidence reference remains available on the same connection. Export the bundle
or page `list_unknowns` to recover the result; do not repeat the committed
mutation. A delivery failure does not undo that revision.
to recover the result; do not repeat the committed mutation. A single unknown
may be too large for a `list_unknowns` page. A delivery failure does not undo
that revision. If a list response overflows, retry on the same connection with
the same filters and offset and a smaller limit; export if one head still cannot
fit.
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`.
@@ -308,6 +373,38 @@ that buffer. It does not raise REA's reserved single-string limit, which is
raise that Node ceiling. It does not change analysis coverage or retained
content. Ordinary responses keep their existing complete result contract.
### Input validation resource allowance
Both HTTP and stdio admit at most 1,024 combined array elements and object
members in one tool's arguments by default. The pinned SDK counts them before
canonical schema validation or lazy runtime materialization. Oversized calls
return a bounded, nonretryable `resource_constraint` with resource `transport`
and `reported_limits.max_input_elements`; the full element count is not claimed.
No provider or tool handler starts for a refused call. Subsequent calls remain
usable.
Set `REA_MCP_MAX_INPUT_ELEMENTS` to a positive decimal safe integer and restart
REA to select another allowance for a larger complete observation or batch.
Where a tool supports retained-Evidence or Evidence-file selectors, prefer
those selectors to resending large inline records. Admission never truncates
the caller's selected input or removes retained Evidence.
This is a configurable transport admission policy, not a per-array `maxItems`
contract or an exact heap guarantee. Missing required fields can amplify one
input element into many issues: on the pinned Evidence array schema,
1,024 empty objects produced 16,384 issues and about 26 MiB heapUsed delta
before SDK formatting. The default therefore admits at most 1,023 such objects
plus the root member, rather than extrapolating the scalar case to larger batches;
actual memory also depends on schema branches, runtime state and concurrent
work. HTTP's separate request-byte limit and the client's receive limit still
apply.
Canonical schemas and CLI/application analysis semantics remain shared and
unchanged. Admitted arguments retain the same values and ordinary validation
diagnostics. SDK embedders can select `maxToolInputElements` in the server
options; the common REA MCP server supplies the finite default to eager and
deferred registrations alike. This does not impose the separate semantic
batch-workload limit tracked in issue #5930.
### Error recovery and deadline ownership
Initialization instructions and the static JavaScript tool description teach
@@ -343,10 +440,12 @@ result's `_meta`, whether the call succeeded or failed:
```
The marker is declared once per tool contract (`returnsTargetContent`) and is
on by default: only `export_evidence_bundle` and `record_unknown`, whose
results and errors contain only REA session state or caller-supplied values,
omit it. Tools whose results or errors can include provider, launcher, or
device output stay marked, including `binary_session` (provider failure
on by default: `export_evidence_bundle`, `record_unknown`, `search_guidance`,
and `read_guidance_section` omit it. The first two contain only REA session
state or caller-supplied values; the guidance tools return REA's own installed
documentation, not text from an analysis target. Tools whose results or errors
can include provider, launcher, or device output stay marked, including
`binary_session` (provider failure
reasons and availability diagnostics), `close_binary` (provider cleanup
diagnostics with captured launcher output), `inspect_adb_client` and
`inspect_apktool_client` (version output and stderr excerpts), and
@@ -383,6 +482,9 @@ session retention refuses summary detail with `capability_unavailable`;
For `inspect_artifact`, omission also keeps the original request parameters and
complete output shape. Delivery selection never reaches the inventory engine;
the complete inspection and its atomic inventory Evidence remain retained.
A view is never more certain than its parent: a summary or other view of
`inferred` Evidence is `inferred`. Other views are `derived`, unless the
view kind itself infers, as described below.
`inspect_analysis_view` also accepts `api-surface` for retained HAR capture Evidence,
grouping request lines by method, origin and format-rule path template. Templated
@@ -498,10 +600,12 @@ reach WABT or change the original source Evidence ID.
Completed `inspect_macho` Evidence supports a summary and
`view: {kind: "macho", facet: "exports", offset: 0, limit: 64}`. Facets are
`entrypoints`, `architectures`, `build_metadata`, `load_commands`,
`dependencies`, `imports`, `exports`, `segments`, and `provenance`; pages return
the original rows. The summary keeps the selected slice, header fields and UUID,
and replaces each collection with its returned count, reported total and
`exhaustive` flag. Each page repeats the paged collection's `source_total` and
`dependencies`, `imports`, `exports`, `segments`, `encryption`, and
`provenance`; pages return the original rows. Evidence retained before
`encryption` was reported pages no encryption rows and reports that collection
as non-exhaustive with an unknown status. The summary keeps the selected
slice, header fields and UUID, and replaces each collection with its returned
count, reported total and `exhaustive` flag. Each page repeats the paged collection's `source_total` and
`source_exhaustive`; exhausting a non-exhaustive collection does not establish
that unreturned symbols are absent. Large frameworks return megabytes of
symbols (Electron Framework: 2.5 MB of imports and exports, 3.3 KB as a
@@ -583,11 +687,22 @@ capabilities. The default result contains the complete inventory in groups that
share status facts. `tool_availability.client_requirements` is the baseline for
each group; a group's optional `client_requirements` replaces that baseline for
the group's tools. Expand each group's `names` into one tool entry, carrying its
surface, availability, reason, remediation, default-mode status, modes, and
client requirements. Compare the union of group names with `tools/list` when
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.
availability, reason, remediation, default-mode status, modes, and client
requirements. Compare the union of group names with `tools/list` when 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.
`detail` selects the projection and the result echoes it. The default
`summary` keeps open state, target identity, the binding, current-route
`capabilities`, run, activity and health status, and each provider candidate's
identity, selection, and availability and target-support `status`, `code`, and
`reason`. It lists the fields it leaves out in `omitted_fields`: provider
`diagnostics`, candidate `capabilities`, and each tool group's static `surface`,
`effects`, and `annotations`. Omitted fields are not empty or false.
`detail: "complete"` returns them inline, groups tools by those flags too, and
has no `omitted_fields`. The output schema keys each result's candidate,
tool-group and omission fields by its `detail`. CLI `capabilities` and
`providers` always return complete provider facts.
`get_call_graph` and `trace_call_path` report `forward` and `backward` modes.
Each requires `procedure_address` plus `procedure_callees` or `procedure_callers`,
@@ -600,8 +715,8 @@ 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
With complete detail, 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,
or limitation false. Keep availability reasons, remediation, client-feature
requirements, and mode facts inline with the grouped tool names. The optional
@@ -632,7 +747,8 @@ identity, availability, reason, rejection code, effects, and ordered
limitations.
`binary_session.analysis_provider_candidates` is authoritative for deep-engine
discovery. Each candidate's capability sets describe that possible provider;
discovery. Each candidate's capability sets, returned with complete detail,
describe that possible provider;
they do not select it. The top-level `capabilities` describe the current route,
while `analysis_provider_binding` identifies the concrete selected route. These
fields are not interchangeable. Target-free discovery is sorted by provider ID,
@@ -645,6 +761,37 @@ 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_binary` resolves an Apple bundle directory (`.app`, `.appex`,
`.framework`, `.xpc`, `.systemextension`, `.bundle` or `.plugin`, compared
case-insensitively) to the program file its `Info.plist` names in
`CFBundleExecutable`; the Evidence subject is that program file. It reads the
macOS `Contents/` layout or the flat root layout. A framework with `Versions/`
may instead keep `Info.plist` in `Versions/Current/Resources/` with its program
file in `Versions/Current/`; a flattened framework without `Versions/`, as
Electron and Gecko apps ship it, keeps `Resources/Info.plist` beside its
program file. An app keeps its iOS-on-Mac `Wrapper` resolution. For the
other types, exactly one layout may declare the bundle, and its `Info.plist`,
program directory and program file must stay inside the bundle. Resolution
never guesses a program file. Each refusal reports one `details.constraint`:
- `bundle_info_plist_missing`, with `probed_paths` listing every layout's
`Info.plist`.
- `bundle_layout_ambiguous`, with `probed_paths` listing the `Info.plist`
files found.
- `bundle_current_version_missing`, with `probed_paths` naming
`Versions/Current`.
- `bundle_path_escapes`, with `probed_paths` naming the path that resolved
outside the bundle.
- `bundle_executable_undeclared`, with `info_plist`.
- `bundle_program_missing`, with `info_plist` and `probed_paths` naming the
declared program file.
An unreadable or malformed `Info.plist` keeps its reason without a bundle
constraint, and `details.path` names that file. A `.dext`, `.kext`,
`.qlgenerator` or `.mdimporter` directory reports `bundle_type_unsupported`. A
resource root reports its `layout` as `contents`, `root`,
`versioned-framework` or `flattened-framework`.
`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
@@ -687,6 +834,22 @@ 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.
## Initial target at startup
MCP normally starts without a target; use `open_binary` to select one during the
session. To open a target before serving MCP, set `HOPPER_TARGET_PATH` to the
selected path in REA's launch environment. `HOPPER_TARGET_KIND` accepts
`executable` (the default) or `database`. Despite the names, these are initial
session settings; the configured provider still determines how the target is
opened. If the initial open fails, REA reports the failure and exits with code 1
without serving MCP. Shutdown during startup cancels and cleans up the open as
described below.
The source-checkout helper `node scripts/print-mcp-config.mjs /path/to/target`
prints a registration containing these settings; `--kind database` selects the
database kind. The helper is not part of the installed npm package. `rea setup`
does not copy these one-shot target settings into generated registrations.
## Transports
The eager stdio runtime owns SIGINT, SIGTERM and stdin EOF before opening an
@@ -775,7 +938,12 @@ 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 an `initialize` object can replace an open session. A sessionless array containing initialize, including a one-element array, is refused with HTTP `400` before session creation or handover. Scoped
passes). A non-loopback bind requires `MCP_ALLOWED_HOSTS`, or
`--allowed-hosts` for `rea mcp --http`, listing every client host name or IP
address. Configuration validates and canonicalizes complete tokens once;
URLs, ports and empty entries are refused. Both Host and Origin checks remain
active on that declared list. The announced URL uses the bound hostname if
admitted, otherwise the first declared hostname, with the actual bound port. 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 an `initialize` object can replace an open session. A sessionless array containing initialize, including a one-element array, is refused with HTTP `400` before session creation or handover. 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
@@ -958,6 +1126,12 @@ A successful MCP initialize handshake establishes the REA connection.
that Ghidra has finished importing the target. The first Ghidra-backed query,
such as `binary_overview`, starts the engine and waits for import, default
auto-analysis, bridge connection, and health readiness before returning analysis.
With `REA_GHIDRA_PROJECT_PATH`, shared CLI/MCP configuration instead selects an
[existing project copy](installation.md#reuse-an-existing-ghidra-project), whose
content fingerprint is committed into the profile. Import, auto-analysis and
repair scripts are skipped; original analysis completeness/settings stay unknown,
and bridge database edits are unavailable. The same startup/client deadlines
still cover copy verification, engine launch and the authenticated handshake.
These deadlines have different owners:
@@ -1153,7 +1327,18 @@ attachment. Native checksum verification failures still refuse traversal;
Occurrences use normalized logical paths for identity and lookup. Optional
`source_path` retains the original path within the owning reader when Unicode
NFC or reader admission changes its spelling; it is source evidence, not an
output destination. POSIX letter-colon names such as `a:b` remain valid logical
output destination. New ASAR file occurrences explicitly record the boolean
`unpacked`: `true` identifies a companion file and `false` identifies a packed
entry. This field describes archive storage, independently of whether the bytes
were available or passed integrity verification. Older occurrences may omit it;
omission remains unknown and must not be defaulted to `false`. Consumers that
previously accepted only literal `true` must also accept `false`, while retaining
support for omitted historical values.
`compare_artifacts` reports a metadata change when both storage values are
known and differ. If only one value is known, storage comparison is unknown;
when both are omitted, storage is not compared.
POSIX letter-colon names such as `a:b` remain valid logical
names; Windows extraction refuses names its filesystem cannot materialize.
Extraction materializes regular files exposed by the active archive reader.
@@ -1180,11 +1365,22 @@ failures for such entries name this cause and the operation to rerun with
Advertised input and output schemas contain no reachable recursive references.
Input schemas inline repeated definitions before applying the selected
presentation profile. Both `full` and `compact` start from this self-contained
projection; output schemas can share schema-local definitions. Full inputs
retain nested fields, descriptions and valid literal examples. The compatibility
projection; output schemas can share schema-local definitions. Analyst-authored
full inputs retain nested fields, descriptions and valid literal examples. The compatibility
projections below can relax advertised constraints; canonical runtime validation
still enforces the complete input contract.
`compare_web_captures` declares its complete producer observations as object
operands instead of repeating their full output schemas in the input catalog.
Pass the original `inspect_web_page` normalized result in `before.inspection`
and `after.inspection`, optional complete `discover_webmcp_tools` results in
`webmcp`, or complete `capture_browser_scenario` results in the scenario fields.
Do not construct partial observations from the abbreviated declaration: the
server still validates every canonical field before comparison. Input groups
and analyst-authored normalization rules remain explicit. This presentation
changes no capture bytes, identity, completeness, or comparison semantics and
does not reduce `inspect_analysis_view` selectors or other tools' declarations.
When a host forwards input schemas to the model, their examples consume context.
REA's advertised examples therefore never copy complete producer Evidence.
An embedded Evidence record is shown as its exact `{"kind":"retained-evidence","evidence_id":"ev_..."}`
@@ -1269,6 +1465,16 @@ This addresses the emitted shape reported through a Gemini-backed gateway in
[#5201](https://github.com/morluto/rea/issues/5201). Gateway conversion and
live provider acceptance have not been verified for this projection.
Gemini function declarations accept `items` only beside the single `array`
type. Reduced array properties therefore advertise the element types their
canonical item schemas accept, such as `{"type": "object"}` for a union of
object actions, instead of an any-value type list with nested `items`. An
element whose type is unknown, a tuple, or an array alongside other types uses
the empty item schema, and a property that may be an array or another type
lists typed `anyOf` branches. A boundary test rejects any compact
advertisement that places `items` beside another type or uses an untyped item
union.
The compact profile renders the same tool set, output schemas, annotations,
and canonical server-side validation. It changes only the advertised input
JSON Schema:
@@ -1306,6 +1512,77 @@ check full-profile local-path rules. Compact MCP workflow tests verify canonical
rejection of invalid inputs before provider work, independent of how much detail
the selected advertisement retains.
### Tool family advertising scope
Agents pay context for every advertised tool schema, and clients that send
catalog payloads with each request (see the Claude Code measurements above)
can spend more context on tool definitions than on the investigation. Setting
the server's `REA_MCP_TOOL_FAMILIES` environment variable to a comma-separated
subset of the catalog's tool-family ids (the `tools.families` entries in the
product catalog) restricts the registration to those families. A selection
outside the published family ids fails server startup with the complete id
list; the setting is read at startup, so restart the server to apply changes.
Out-of-scope tools stay registered but disabled: `tools/list` omits their
names and schemas entirely, and a direct call fails with the SDK's
`Tool ... disabled` invalid-params error rather than disappearing silently.
`binary_session.tool_availability` and the provider `capabilities` sets on the
same report, including `analysis_provider_candidates`, list only operations
whose tools the registration advertises; an operation omitted from those
projections because of the scope is not callable through this registration,
and `tools/list` remains the canonical catalog. Availability is derived from
the complete provider facts before those sets are narrowed, so hiding a direct
tool does not report an advertised composed tool as unavailable. Guided
prompts follow the scope too: a workflow is advertised only when every tool in
its suggested steps belongs to a selected family, so a partially available
workflow is omitted from `prompts/list` instead of rendering a disabled call;
`prompts/get` reports it as not found. A scope can omit all guided prompts;
doctor treats a server without the prompts capability as an empty inventory.
Recovery instructions recommend runtime settings tools only when `application`
is advertised; otherwise they explain launch settings and how to widen the scope.
The server identity digest and
`rea mcp doctor` tool and prompt inventory derive from the
same selected scope, so a scoped server reports itself healthy; a scope
without the `session` family cannot serve `binary_session`, and doctor says
so explicitly instead of reporting a mismatch. Canonical server-side
validation and Evidence semantics are unchanged for
the tools that remain advertised. The default (unset) advertises the complete
catalog exactly as before. Saved registrations with an invalid selection
report `invalid` in status instead of starting a server that fails.
`rea setup --client <id> --tool-families <ids>` writes the same selection
into the `env` object of that client's `rea` entry, so the scope travels with
the registration; rerunning setup with a different selection refreshes it.
#### Choosing families for common workflows
Every investigation that opens a local binary still needs the `session`
family: it owns `open_binary`, `binary_session`, the evidence-bundle and
comparison tools, and the unknown ledger, so include it whenever the workflow
touches a binary. The `tools.families` entries in the product catalog list
each family's current inventory; the groupings below describe what a scope
covers, not a frozen tool count.
Include `application` when a workflow pages retained summaries through
`inspect_analysis_view` or changes analysis settings. `session` owns Evidence
bundle import/export; it does not include those view and settings tools.
| Workflow | Scope | Coverage |
| ------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Firmware extraction and analysis | `firmware,session,direct` | extract firmware regions, open the extracted image, inspect it with the proxied disassembly tools |
| Web investigation | `browser,pcap,session,javascript-runtime` | page, bundle and session inspection, packet captures, JS runtime observation, evidence workflow |
| Android application analysis | `android,adb,apktool,session` | class and method inspection, device bridge, resource decoding; add `frida` for dynamic instrumentation, `jeb` for JEB projects, `flutter` for Flutter builds |
| Native macOS or iOS binary | `native,artifact,session` | Mach-O, signature and property-list inspection plus container extraction |
| Managed .NET assembly | `managed,session` | managed member comparison and reconstruction against the evidence workflow |
| Electron or browser-hosted JavaScript application | `browser,electron,application,javascript-runtime,session` | runtime targets, live page inspection, bundle and capture tools, feature tracing, JavaScript semantics and reconstruction obligations |
| Evidence bookkeeping only | `session` | open and close binaries, bundles, comparisons, unknown tracking |
Scopes are additive and start narrow: begin with the families the workflow
names, then add one when a call fails with the SDK's `Tool ... disabled`
error. The error names the disabled tool; `tools.families` in the product
catalog maps it back to the family that would re-enable it, and the server
restarts with the wider scope through the same setup flag.
### Output schemas
Self-contained output schemas advertise a content-bound `$id`, including their
@@ -1315,21 +1592,39 @@ identity. Explicit schema IDs and relative external reference bases are
preserved. This keeps every tool and validation rule in discovery and does not
change the SDK's catalog invalidation or availability checks.
The server identity's tool-schema digest includes both the canonical output
contracts and the selected output-schema profile. `full` and `off` therefore
have distinct identities even though `off` keeps the same canonical output
validation on the server.
The server identity's tool-schema digest includes the selected output-schema
profile and the advertised form that profile produces. `full`, `compact`, and
`off` therefore have distinct identities. The `compact` digest covers the
bounded schemas clients receive; `off` keeps the canonical output contracts in
the digest while advertising nothing.
Some stdio hosts reject a complete `tools/list` frame before they load any
tools. The opt-in `REA_MCP_OUTPUT_SCHEMA_PROFILE=off` setting omits `outputSchema`
from the advertised catalog for hosts with a small frame limit (the measured
pi-web-ui failure and catalog breakdown are in [#2512](https://github.com/morluto/rea/issues/2512)).
The default `full` profile is unchanged. With `off`, REA validates successful
structured results against the same named canonical tool contract before
delivery; it still returns complete `structuredContent` and text results.
Only client-side schema discovery and validation are omitted, so hosts using
this profile should rely on REA's validation and retain their usual response
size limits.
tools. The opt-in `REA_MCP_OUTPUT_SCHEMA_PROFILE=compact` setting bounds every
advertised output schema to 4,096 bytes; `off` omits `outputSchema` entirely
(the measured pi-web-ui failure and catalog breakdown are in
[#2512](https://github.com/morluto/rea/issues/2512)). The default `full` profile
is unchanged. Both settings keep the same named canonical tool contract for
server-side result validation, and both still return complete
`structuredContent` and text results.
`compact` keeps the complete validation structure when it fits the budget.
Otherwise it advertises the root property shape, first-level reference-resolved
types, first-level guidance, and the root's `required`/`additionalProperties`
constraints, with nested validation detail elided. Local references are inlined
within the budget, so the advertised form is self-contained and omits the
canonical contract's content-bound `$id`. The projection only widens: a valid
canonical result still satisfies the advertised schema, but a client validating
against it can accept a result the canonical contract rejects. REA still
validates every result before delivery. On catalogs large enough that full
input schemas alone approach the frame limit, keep the input profile at its
`compact` default as well; with full input schemas the advertisement is
dominated by the input side.
The full input profile has no one-megabyte catalog-frame guarantee, including
when output schemas are omitted.
Only client-side schema discovery and validation are reduced or omitted, so
hosts using these profiles should rely on REA's validation and retain their
usual response size limits.
### Function comparison limitations
+46 -3
View File
@@ -4,6 +4,40 @@ REA exposes six provider-neutral investigation workflows through the MCP
`prompts` capability. They complement the generated tool catalog; they do not add, remove, or
invoke tools by themselves.
Clients that expose tools but not prompts can use the target-free
`guided_workflows` tool with `action: "list"` or `action: "render"`. CLI callers
can use `rea guided-workflows` to list workflows, or pass `--action render`,
`--workflow-id ID`, and `--arguments-json '{"feature":"offline search"}'` to
render one. Both paths use the same contracts and renderer as native prompts;
rendering returns guidance only and does not inspect a target, start analysis,
or change session state.
The list contains workflow identifiers, descriptions, and argument requirements;
render returns only the selected workflow's text. Unknown argument names and
non-string values are rejected with field paths. `action: "list"` accepts no
workflow identifier or arguments. The MCP adapter respects the same
`REA_MCP_TOOL_FAMILIES` scope as native prompts, including render requests.
To find a section in the installed guidance bundle by analyst question, use
`search_guidance` and pass a returned locator to `read_guidance_section`. The
CLI equivalent is `rea guidance --query "exact JavaScript module"`, followed
by `rea guidance --action read --locator LOCATOR`. Search is limited to the
packaged managed skill files, works without providers or a target, and returns
deterministically paged matches. Every non-generic query word must occur in the
section; generic-only queries return no matches. Results are documentation; locators
are bound to the installed bundle and report stale or unavailable guidance without
returning cached section content. A no-match result says nothing about analysis
capability availability.
Search returns at most 20 matches per page with 500-code-unit context excerpts.
Read retrieves the complete selected section. Admission permits 1 MiB per file,
4 MiB per bundle, 4,096 sections, and 25,165,824 expanded UTF-16 code units before
section text is materialized. Unreadable or oversized bundles return
`bundle_unavailable`, with no partial index or inferred absence. Cleanup failures
remain errors with their retained retry owner. The bundle and complete section
are bound by fixed-size hashes in locators, so a long heading does not make its own
locator unreadable.
## Prompt inventory
| Prompt | Purpose |
@@ -15,6 +49,13 @@ invoke tools by themselves.
| `audit_residual_unknowns` | Audit current residual-unknown heads and evidence-qualified resolution. |
| `prepare_bounded_process_capture` | Design a bounded controlled process experiment before execution. |
A `REA_MCP_TOOL_FAMILIES` scope advertises a workflow only when every tool in
its suggested steps belongs to a selected family. Partially available
workflows are omitted from `prompts/list` — `prompts/get` reports them as not
found — so a rendered prompt never directs the agent to a disabled call. The
server identity digest and `rea mcp doctor` prompt inventory follow the same
scope.
Every rendered prompt provides optional starting points using current REA tool
names. Agents can call tools directly, skip irrelevant suggestions, and inspect
provider or target state only when it helps answer the request or a tool
@@ -30,9 +71,11 @@ directly to `analyze_javascript_application` with `input_path`; it does not
require `open_binary`. When that Evidence, or `inspect_binary_layout` Evidence,
is already retained, it suggests `inspect_analysis_view` before tracing a
feature seed. The CLI equivalent is `rea analyze <directory>`.
`open_binary` and the doctor target check admit files and macOS app bundles.
A directory outside that opening route is reported with an available analysis
action; this does not establish support for every directory format.
`open_binary` and the doctor target check admit files and Apple bundle
directories (`.app`, `.appex`, `.framework`, `.xpc`, `.systemextension`,
`.bundle` and `.plugin`). Another Apple bundle type is refused as unsupported,
and another directory is reported with an available analysis action; this does
not establish support for every directory format.
For target paths in `compare_application_versions`, the prompt suggests
opening each target before calling `inspect_artifact`; inspection operates on
+29 -4
View File
@@ -117,12 +117,37 @@ 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.
Representation admission is bounded before cloning selected observations
and expanding matching indexes and repeated per-function source links. Each
inventory row is charged before parsing for the member it becomes, including the
report and Evidence copies that member is serialized into, so an oversized side
is refused before its rows are parsed. Inline Evidence and bundle records are
charged for the copies their authentication or loading creates. An exact
session reference to retained Evidence is borrowed without a copy, so only
what matching derives from it is charged; the inventory's own Evidence ID is
charged once, not per function. Selected observations are charged in full.
Measured under the 96 MiB default with Ghidra-shaped rows, about 20-character
names and no observations, about 22,000 rows per side fit through retained
`list_procedures` references, and about 10,000 through inline Evidence or CLI
`source_bundle` inputs. Work yields to
cancellation. No worker/provider concurrency is introduced; this budget is not
a bound on total process RSS.
The allowance defaults to 96 MiB and is the runtime setting
`native.matching_representation_bytes`, from 1 byte to 1 GiB. On MCP, call
`update_analysis_settings` with that setting and retry; it applies to the next
operation without restarting REA. For CLI or future REA processes, set
`REA_NATIVE_MATCHING_REPRESENTATION_BYTES` in the launch environment; `rea
setup` copies it into client registrations. An invalid launch value is refused
by matching only, and a runtime value repairs it. A refusal carries
`details.limit` with the effective value, its source and bounds. Raising the
allowance lets matching retain more in the REA process. The 1 GiB maximum is
an REA policy, not a host-capacity claim, and peak heap during a request can
exceed the allowance.
Summary delivery happens after complete matching Evidence is constructed and
retained. It reduces the initial reply, but does not avoid that construction or
raise the allowance. There is no runtime override. Repeated provenance remains
raise the allowance. Repeated provenance remains
part of the complete member contract; splitting inventories into separate matches
would change global name/body uniqueness and is not an equivalent workaround.
+147 -32
View File
@@ -14,6 +14,10 @@ device platform. A chained-import row ending in `+0x...` is ambiguous in
dyld's text output: it may be an addend or part of a literal symbol name. REA
keeps the full expression in `raw_name`, sets `name` and `addend` to null, and
marks `name_status: "ambiguous"`; it does not synthesize a symbol identity.
Each import and export `name` is the exact symbol-table spelling, such as
`_main`; `runtime_name` is the derived name LLDB and `dlsym` use, such as `main`,
and is null when `name` is null. See [native call observation](#native-call-observation) for
breakpoint names.
## Start with a function
@@ -123,7 +127,11 @@ rea inspect-native-data-type <binary> --address <typed-data-address> --provider
Instruction facts include bytes, length, decoder text, ordered register/scalar/
address tokens, typed references and flow destinations. Mid-instruction, data,
outside-memory and undecodable addresses have separate outcomes. Effective
outside-memory and unlisted addresses have separate outcomes. For Ghidra,
`not-in-listing` means the address is in memory without a listed instruction or
defined data. REA does not attempt a decode there: the memory may be uninitialized
or contain valid instructions. Older Evidence may report `undecodable` for this
same ambiguous case; it does not establish that a decode failed. Effective
memory base/index/displacement roles remain unavailable. Ghidra reports its program
language variant in `mode`; other providers retain their own mode label. Ghidra
MIPS results additionally expose `decoder_context`
@@ -134,7 +142,7 @@ that do not expose this facet. The context is an analysis observation, not proof
of a runtime processor state.
`inspect_native_instruction` also returns `incoming_references` to the exact
queried address, including data, interior-instruction and undecodable addresses.
queried address, including data, interior-instruction and unlisted addresses.
Ghidra enumerates its ReferenceManager, excludes synthetic entry-point
references, and returns deterministic source-address ordering while retaining
distinct operand references from the same source. `[]` means that enumeration
@@ -328,10 +336,34 @@ 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.
Literal mode retains Python Unicode full case folding, which can expand a
character into a sequence: for example, `ss` matches `ß`. This differs from
REA's Unicode simple case folding used by other native search providers and
Hopper regex mode.
## Bounded static traces
Hopper caller queries, incoming procedure references and function dossiers
reconcile reported reverse relationships with forward call observations. Each
standalone query or composed workflow scans the current document in pages of at
most 64 procedures and retains at most 4 MiB of encoded scan results. A composed
workflow reuses its own index and clears it when the workflow finishes. The
default cooperative scan budget is
2,000 ms; set `REA_HOPPER_CALLER_SCAN_BUDGET_MS` to a positive integer number of
milliseconds before starting REA to change it. The default limits additional
work on the serial Hopper bridge; larger documents may need a higher setting.
Results report the examined procedure count and any budget interruption.
An individual page, native caller list, and target instruction list each have
a 512 KiB encoded allowance. Hitting one reports the incomplete observation.
Cancellation is checked between pages, but cannot interrupt a Hopper API call
already executing; Hopper's native API itself materializes its reference arrays
before REA can bound their copies. Hopper exposes no document revision token, so scans are not
reused across workflows and coverage and consistency during a live scan remain
unknown even when every procedure was examined.
Hopper observations are re-observed rather than replayed from snapshots because
the provider has no document revision token. Safe observations may still be
retained as Evidence.
`trace_native_ui_action` / `rea trace-native-ui-action <target> <seed>` accepts
one authored selector/object ID, native symbol or exact function address. It
joins UI wiring to uniquely matched class/selector implementations and follows
@@ -480,8 +512,10 @@ output-budget omissions remain omissions.
Source input is limited to 64 MiB. Binary and direct XML decoding reserve an
estimated 64 MiB decode budget before parsing; this is not a hard process-memory
bound. JSON decode memory has not been measured and has no equivalent decode
estimate. A refused input reports non-retryable `resource_constraint` with
bound. The XML estimate charges every element and every text, comment or CDATA
node of the decoder's DOM at a measured upper bound, so a plist made of many
small elements reaches it at a few MiB of source. JSON decode memory has not
been measured and has no equivalent decode estimate. A refused input reports non-retryable `resource_constraint` with
`reported_limits.maximum_input_bytes` or `maximum_decoded_bytes` as applicable.
Ordinary direct-source decoding has a ceiling of 998 source nesting levels,
derived from the existing 1000-level JSON result capacity by reserving one level
@@ -526,7 +560,21 @@ support for core-dump analysis, historical FVMLIB layouts, or unobserved native
diagnostic spellings. Unknown or contradictory header values and signalled
commands remain failures.
`inspect_macho.selected_architecture` identifies the exact selected lipo slice
`inspect_macho` reads load-command framing and fields from the selected Mach-O
bytes. It does not use line-delimited tool output to decide where a command,
section, or embedded string begins. Names whose bytes are not valid UTF-8 have
a null text value and retain their original bytes as lowercase hexadecimal in
`name_bytes_hex`, `segment_bytes_hex`, or `path_bytes_hex`; fixed-width names
stop at the first NUL, and command paths exclude their NUL terminator. Older
retained Evidence may omit the byte fields. Large binary sizes and offsets that
cannot be represented as safe JSON integers retain an exact hexadecimal field;
the corresponding numeric field is null. A section alignment too large to
represent in bytes retains `alignment_exponent` instead.
Unknown or partially decoded commands retain their selected-slice-relative
offset and size. Their unexamined fields are described in load-command coverage
limitations; an exhaustive command inventory does not by itself establish that
every payload field was decoded. `inspect_macho.selected_architecture` identifies the exact selected lipo slice
and its `container_file_offset` in the input file. A thin Mach-O has a known
offset of zero; an unknown universal-slice offset stays null. The Evidence
subject format describes the input container: `mach-o-universal` for FAT files,
@@ -534,15 +582,49 @@ including those with one slice. The normalized result also reports the container
in `format`; `selected_architecture` identifies the selected Mach-O image.
Architecture `file_offset` values are container-relative. Entrypoint, segment
and section `file_offset` values retain their source meaning and are relative
to the selected Mach-O slice. Raw load-command fields retain their original values.
A field otool prints more than once, such as each `LC_BUILD_VERSION` tool, is
keyed `name #n` in print order. Each `LC_LINKER_OPTION` string is keyed
`string #n` and checked against the declared `count`. Evidence locations map the LC_MAIN entrypoint and nonempty file-backed segment
to the selected Mach-O slice. Decoded load-command fields retain their original
values. Repeated fields, such as each `LC_BUILD_VERSION` tool, are keyed
`name #n` in order. Each decoded `LC_LINKER_OPTION` string is keyed `string #n`
and checked against the declared `count`. Evidence locations map the LC_MAIN entrypoint and nonempty file-backed segment
ranges to container offsets by adding the observed slice offset. Zero-fill
segments do not produce file ranges. When the selected slice's container offset
is unknown, those mapped locations are omitted with an explicit limitation;
architecture inventory locations remain available.
`inspect_macho.encryption` reports the `LC_ENCRYPTION_INFO(_64)` state of every
slice, not only the selected one. It decodes only the FAT table, slice headers
and load commands. Like every Mach-O container read, a `0xcafebabe` input of at
most 16 MiB is first read whole to rule out a JVM class file, so that read
includes code bytes; larger inputs and thin images read only the structures
above. A slice is `encrypted` when its single encryption command has a nonzero
`cryptid`, `not-encrypted` when `cryptid` is zero, and `absent` only when every
load command was read and none was an encryption command. A command whose width
or `cmdsize` contradicts the image, more than one such command, or a range past
the slice is `malformed`; a slice whose commands could not be fully read is
`malformed` or `unknown` with a reason, keeping any commands seen before the
failure. A slice with more than two encryption commands keeps the first two
and states the count in its reason. Range mapping in all slices shares one
budget of segment and section records (16,384, a sixteenth of the native
output budget); a slice past it keeps its status and reports its mapping as
`unknown` with that reason. Framing caps retained segment commands before decoding.
Only a successful mapping consumes the shared allowance; failed mappings leave
it available to later slices. Each slice's `range` is end-exclusive in slice and input-file
coordinates and maps to file-backed segment fragments, VM addresses and the
overlapping nonempty sections; bytes outside every segment remain unmapped
fragments. A segment with no VM size keeps its file bytes as fragments with
null VM addresses, and a segment whose file size exceeds its VM size or whose
VM range leaves the address space makes the mapping `unknown` with a reason
while the slice keeps its encryption status. `architecture` is the lipo name of the record at the same offset,
size and CPU identity, and is null when no single record matches. A ciphertext
range adds a limitation naming its input-file bytes, because disassembly,
decompilation, strings and references derived from them do not describe
program code. Encryption is read through the same regular-file descriptor
that `inspect_macho` binds for its load-command reads, whose SHA-256 must match
the session target before and after the native tools run, or the call reports
`artifact_changed`. A target that cannot be opened, or a symlinked, non-regular
or changing target, fails the call instead of reporting tool facts without an
encryption status.
Hopper's `address_to_file_offset` combines the native image-relative mapping with
original-file coordinates only after checking the source against the session's
SHA-256. FAT tables and embedded Mach-O headers come from that same hashing pass.
@@ -579,6 +661,9 @@ complete observation.
undecodable filenames and skipped symlinks, as partial coverage. Known
executable roots remain available; unexamined names and symlink targets
cannot establish an empty root set or the absence of other roots.
A dependency symlink whose target is not valid UTF-8 is undetermined, with
its stored target bytes in the limitation and partial coverage; a selected
root crossing such a symlink is refused with the same bytes in its diagnostic.
- `inspect_asset_catalog` / `rea inspect-asset-catalog <app>` reads compiled
`Assets.car` metadata through macOS `assetutil --info`. Catalog digests, raw
rendition fields, pagination and exact UI resource-name matches are returned.
@@ -637,11 +722,10 @@ complete observation.
outcome instead of rounded reference identities.
UID 0 cannot distinguish conditional nil from ordinary nil. Limits are
64 MiB of input, 200,000 objects/references and 128 nesting levels.
XML dictionary entries decoded as `__proto__` are omitted with an explicit
count because REA results cannot represent that key. XML tag whitespace and
comments do not change that handling. XML key names combine their text and
CDATA segments without trimming or expanding literal CDATA entities. Other
values and the original archive digest are preserved.
XML, OpenStep and binary dictionary entries retain their source keys,
including `__proto__`, through archive projection and CLI/MCP results.
XML key names combine their text and CDATA segments without trimming or
expanding literal CDATA entities. The original archive digest is preserved.
Symbol fallback accepts complete Objective-C class/metaclass symbol leaves,
including qualified names. Pointer/string labels that merely contain a class
marker do not establish classes. Provider namespace method labels are not
@@ -697,10 +781,16 @@ complete observation.
release their representation reservation for later documents.
Repeated NIBArchive fields retain all serialized values in order. Array
outlet connections resolve each serialized member and retain the collection
object ID and member position on the outlet observation. AppKit object-parent
registries use paired keys and parents; objects paired with `NSRoot` are
top-level, while nested objects keep their recorded parent. Conflicting or
unreadable registry pairs remain incomplete hierarchy evidence.
object ID and member position on the outlet observation. NIB hierarchy uses
recognized child fields, reverse `NSSuperview` links and window content links.
AppKit registry pairs with a resolvable `NSRoot` owner establish top-level
membership; other registry associations alone do not establish visual
parentage and leave hierarchy coverage partial. Known non-view cell ownership
and control-view backreferences remain raw facts. Conflicting explicit parents
remain unknown rather than choosing an archive-order winner. Retained objects
keep their decoded fields; uncertain registry diagnostics retain the source
registry, child and value IDs. Missing, malformed or repeated registry
declarations also qualify hierarchy coverage.
`NSString` objects with the [recognized `NS.bytes` representation](https://github.com/swiftlang/swift-corelibs-foundation/blob/main/Sources/Foundation/NSString.swift#L201-L215) are decoded
as UTF-8 without substituting malformed bytes. A failed conversion retains
the source string object ID and `nibValues.NS.bytes` base64 data; dependent
@@ -727,6 +817,11 @@ complete observation.
files and universal slices before metadata decoding. CPU subtypes and
capability bits remain source facts; an `arm64` request may select an
`arm64e` image under the existing slice preference policy.
Objective-C class, protocol and category lists require eight-byte entries;
Swift type and conformance sections require four-byte entries. Misaligned
section lengths and unsupported non-PowerPC big-endian CPU declarations return
`unsupported_target` with the selected path and precise reason. Recovery
selects a well-formed or supported artifact and reopens that target.
The byte reader holds the whole selected file in memory, so it admits files up
to 64 MiB / 67108864 bytes by default. Select a larger budget with
`max_input_bytes` (CLI `--max-input-bytes`), at most 1 GiB / 1073741824
@@ -821,7 +916,11 @@ complete observation.
and `__objc_catlist` categories are also decoded. Categories record the
extended class, local or external, plus
their methods, protocols and properties; category methods appear as
implementations with a `category`. Swift field-offset globals that are only
implementations with a `category`. A category whose class reference is null,
or is bound to a symbol other than `_OBJC_CLASS_$_`, such as the `_$s…CN`
metadata symbol of another module's Swift class, keeps a null class, and
`objc_properties_categories` coverage names that reference. Swift
field-offset globals that are only
initialized at runtime stay unresolved. Generic, resilient, async and
coroutine tables, and inherited overrides, have explicit unsupported or
partial coverage. Other providers retain the
@@ -916,15 +1015,22 @@ missing LLDB. `duration_ms` controls the later target observation window.
rea observe-native-calls /Applications/Example.app '{"breakpoints":[{"kind":"objc-method","class_name":"NSURLSession","selector":"dataTaskWithRequest:completionHandler:"},{"kind":"function","name":"open","module":"libsystem_kernel.dylib"}],"duration_ms":5000,"backtrace_frames":4}' --json
```
Function names select LLDB runtime symbols. On Darwin, a C function reported as
`_main` by `inspect_macho` or `nm` can resolve as `main` in LLDB. REA preserves the
exact selected name; it does not remove underscores or translate static names.
Use `{"kind":"function","name":"main","module":"Example"}` to limit that
runtime symbol to the executable image named `Example`, then inspect the reported
locations and image paths. Omitting `module` deliberately matches every loaded
image, including system libraries. A match outside the executable is valid for
that request and does not by itself make coverage partial. This C naming example
does not establish a translation rule for Swift, C++ or other mangled symbols.
Function names select LLDB runtime symbols. On Darwin, the Mach-O symbol table
spells language-level symbols with one leading underscore, which LLDB and `dlsym`
omit: `_main` is `main`, C++ `__ZN3rea3addEii` is `_ZN3rea3addEii`, and Swift
`_$s…` is `$s…`. Names without that underscore, such as `-[Class selector]`, are
unchanged. `inspect_macho` keeps each export and import `name` exactly as the
symbol table spells it and derives its `runtime_name`; pass `runtime_name` as the
breakpoint `name`. `observe_native_calls` preserves the exact selected name; it
does not remove underscores or translate static names, so `_main` selects a
different runtime symbol. Use `{"kind":"function","name":"main","module":"Example"}`
to limit that runtime symbol to the executable image named `Example`, then inspect
the reported locations and image paths. Omitting `module` deliberately matches
every loaded image, including system libraries. A match outside the executable is
valid for that request and does not by itself make coverage partial. Event and
location `symbol` values are LLDB display names, which are demangled for C++ and
Swift; join them to `inspect_macho` through `breakpoint_index` and the request
`name`, or through `file_address` and the export `address`.
Each event is an observation: thread, image, symbol, load and file address,
the raw integer argument registers, optional caller frames and, for an
@@ -995,7 +1101,7 @@ is present. A denied trace reports the `debugger-attach-denied` reason.
## Provider and verification boundaries
Install a Ghidra 12.1.x release and the 64-bit full JDK it declares, then configure REA to
Install a Ghidra 12.x (>=12.1) release and the 64-bit full JDK it declares, then configure REA to
use them. Ghidra analysis supports Linux x64/arm64 and macOS x64/arm64; each installation requires
the matching native decompiler. Experimental Windows x64 P0 admits native
x86, x86-64, ARMNT (Thumb-2) and ARM64 PE applications and DLLs, plus explicitly selected
@@ -1058,8 +1164,17 @@ counted as known archive omissions. Recognized symlinked `.nib` entries are
not followed; they retain their paths and reader limitations as counted archive
omissions. Either gap makes `archive_decode` partial and the graph truncated
while preserving decoded documents. Its `examined` count remains actual decode
attempts, and asset-catalog UI joins retain their existing incomplete-graph
qualification.
attempts. `archive_object_decode` separately reports whether archive selection
and decoding examined the object sources; hierarchy-only and connection-only
unknowns do not make that facet partial. Asset-catalog resource-key joins use
this source coverage together with document and object projection coverage.
Incomplete hierarchy or synthetic hierarchy-node limits alone do not qualify
otherwise complete resource-key joins; omitted archives or resource objects do.
Archive omission reasons are counted independently of the bounded path samples.
A UID outside the exact supported range reports `unsupported_uid_exact_range`,
not budget exhaustion. Mixed source failures report `multiple_archive_decode_causes`;
limitations retain omission counts by cause even when individual paths exceed
the reporting allowance.
UI dispatch joins use the authored receiver's class independently of its
presentation kind (controller, view, control or another object). An unresolved
+8
View File
@@ -53,6 +53,14 @@ An unset fuse with a present blob is reported as a limitation. These are static
sentinel observations, not proof of runtime activation: sentinel-like text in
script or asset bytes also participates in the scan.
Artifact comparison uses each member's runtime role and exact source key as
semantic metadata. Unicode-normalized graph paths do not erase differences in
runtime asset keys. For members paired at the same logical path, a directory
index change alone does not change the member. Ordinal-based fallback paths can
change when entries are reordered. When only one observation records member
metadata, the complete runtime member declaration remains unavailable. Original
source fields remain available in the retained Evidence.
## Supported layout and limits
The decoder follows the 64-bit little-endian layout in Node
+18 -3
View File
@@ -81,9 +81,13 @@ Its separate inferred truncation lengths do not replace that limit; an unset
file-header limit remains `null`.
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
DNS address attribution requires one question in one response and complete,
consistent RR owner/type and section counts. Only answer-section A/AAAA records
matching that question (or its unambiguous answer-section CNAME chain) are
associated, with the requested address type respected. Authority, additional,
unrelated, malformed, and ambiguous addresses remain in the unattributed
inventory and make coverage partial. These packet-local relationships do not
prove final resolution or destination authenticity. Protocol distribution counts
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
@@ -102,6 +106,17 @@ URI leaves coverage partial. The HTTP URI profile covers HTTP/1 and HTTP/2;
HTTP/3 URI semantics are unexamined. All admitted URI fields share the same
credential exclusion and source-value retention rules.
Counts preserve distinct observed source URIs before omission or coalescing.
Failed capture-summary TShark commands apply the same HTTP URI policy to
retained JSON diagnostics, including cancellation, output-limit and cleanup
failures. JSON spelling outside the excluded credential spans is preserved.
An unfinished or malformed JSON token and its following suffix are withheld,
with `captured_output.truncated: true`; complete preceding fields remain
available. Diagnostic byte counts and output allowances describe original
producer input, before credential exclusion. Caller-selected packet-field tools
continue to return their selected recorded values.
Origin-form request targets and HTTP/2 `:path` values retain path semantics,
including leading double slashes and userinfo-like text within the path.
`coverage: "partial"` records unresolved DNS attribution or URI item loss;
component credential exclusion is also counted explicitly. Diagnostics retain
both tool stderr streams. Recorded fields do not establish decrypted payloads,
+11 -1
View File
@@ -40,6 +40,12 @@ signer identifier facts. A signer identified by subject key identifier reports
that value as `subject_key_identifier_hex`. Other certificate types keep
`pkcs7` null.
Each signer reports `unsigned_attribute_oids`: null means the field was absent,
and an array lists the types when present. Older retained Evidence may omit the
field. Unsigned attribute contents, including nested signatures and timestamp
tokens, are not decoded; their presence makes coverage partial and adds a
limitation. Certificate and signer counts refer to the outer SignedData.
A missing table is observed absence of that directory. It is not proof the
image is unsigned in every catalog or overlay sense.
@@ -54,7 +60,11 @@ fails the same way. SignedData must contain at least one `SignerInfo`, and
each `SignerInfo` must carry a non-empty signature value. Each embedded X.509
certificate must include `subjectPublicKeyInfo` and `signatureValue`. Decoded
certificate name text, serials, validity spellings, and subject key identifiers
share a 64 KiB budget per PKCS#7 payload. Unsupported certificate name
share a 64 KiB budget per PKCS#7 payload, and each payload decodes at most
16,384 ASN.1 values. Exhausting either fixed allowance returns a nonretryable
`resource_constraint` error naming it, not an invalid-input error; this release
has no runtime override, and `max_file_bytes` and `max_entries` do not raise
it. Unsupported certificate name
encodings, including GeneralString, fail explicitly. TeletexString (T.61)
values are rendered with the ISO-8859-1 compatibility mapping used by OpenSSL;
this is not a full T.61 decoder, so the result includes a limitation whenever
+54 -6
View File
@@ -224,11 +224,42 @@ child output. Child output remains in the capture Evidence on stdout.
resource limits, and normalization settings have defaults; see
`processScenarioSchema` for the exact contract. Event times are milliseconds
from launch, must be ordered, and must fall within `timeout_ms`. Inputs marked
`sensitive` are sent to the process but persisted as a byte-count placeholder.
`sensitive` are sent to the process but persisted with empty `data`,
`sensitive: true`, and `input_bytes`. Exact nonempty CR/LF-separated input
literals are removed from retained terminal text, including cross-chunk and
VT-styled echoes. Rendering uses that redacted stream, so intermediate terminal
states and serialized state cannot restore removed bytes. Normalized text is
checked again. Encoded, transformed, or arbitrarily edited values are not a
secret-detection contract; their privacy remains unknown. Unmarked inputs and
caller-selected environment values remain evidence.
The capture-local matcher admits at most 65,536 prefix states and 8,388,608
construction work units. Projection uses at most 32 MiB of reusable position
indexes and 67,108,864 work units across one capture. Capacity failures return a
non-retryable resource error and withhold terminal text in partial observations.
If output admission leaves gaps, the sensitive capture withholds retained
terminal text rather than interpreting separated fragments as a complete stream.
`raw_terminal.redacted_bytes` reports bytes removed from admitted original
chunks; these bytes still consume `output_bytes` alongside retained safe bytes.
Private display effects remain unknown, with frame order and provenance retained.
This changes the sensitive-input Evidence representation: consumers of the old
`<redacted-input:N-bytes>` placeholder must read `input_bytes` instead. Existing
saved captures remain readable and are not rewritten; old files may still
contain previously echoed input. A private-input comparison policy version
separates old and new captures; reacquire both sides for comparable observations.
Environment overrides are recorded in the scenario commitment; inherited
values are not copied into Evidence.
Terminal dimensions must satisfy `columns × (rows + scrollback) ≤ 1,000,000`.
A bare executable name uses the scenario's `PATH` override, then the inherited
`PATH`. When neither supplies `PATH`, lookup uses `/usr/bin:/bin`, matching
[Node's Unix default](https://nodejs.org/api/child_process.html#child-process).
An explicitly empty `PATH` searches only the working directory. Executable,
working-directory, and observation paths preserve native `symlink/..` traversal.
Terminal width must be at least two columns: the pinned xterm renderer cannot
represent a one-column screen. This applies to the initial size and every resize.
Terminal dimensions must also satisfy `columns × (rows + scrollback) ≤ 1,000,000`.
Every scheduled resize uses the same selected scrollback and must fit this
working-buffer budget. REA rejects oversized scenarios before launching the
command; it never clamps the requested dimensions. This limit is independent
@@ -288,7 +319,8 @@ own classification until its exact resources are released.
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
otherwise `data` is already that text. For sensitive captures, both fields
contain only the safe projection; no unredacted backup is retained. Older captures may lack the
original text for changed chunks. Both values participate in Evidence identity,
while comparisons and trace assertions use the normalized text. Retaining the
original adds at most `limits.output_bytes` of text, because it comes from the
@@ -323,9 +355,12 @@ recapture both sides with the same observation version before comparison.
When path normalization is enabled, aliases apply to selected path identities
at clear text delimiters. A selected executable path does not alias a longer
sibling filename such as `tool-helper`; selected parent directories still
normalize within descendant paths. The comparison contract records these rules as
`path-component-boundaries-v2`, so captures made with the earlier prefix rules
cannot be compared as if the text had the same meaning.
normalize within descendant paths, including when the working directory or an
observation path is spelled with a trailing `/` or `/.`. A selected filesystem
root `/` also aliases descendant paths, without rewriting URL separators or
HTML closing tags. The comparison contract
records these rules as `path-component-boundaries-v3`, so captures made with the
earlier rules cannot be compared as if the text had the same meaning.
Rendered frame `lines` hold the visible rows after normalization, with trailing
U+0020 spaces removed. Blank rows and internal spaces remain. `columns` records
@@ -494,6 +529,11 @@ Every capture requires `truncation_details`, with separate accounting for:
An unreadable directory is recorded in `enumeration_omissions` with its
root-aliased path and operating-system error code. Entries observed before
that directory remain available, while descendants beneath it stay unknown.
A basename that is not valid UTF-8 is never looked up through replacement
characters. It consumes entry capacity and records an `unrepresentable_name`
omission at its containing directory, with exact basename bytes in
`raw_name_hex` and a null `system_code`. That root's enumeration remains
incomplete, so missing paths beneath it remain unknown.
Each retained regular file without a digest has an aliased path, size,
remaining budget and reason: `file_bytes_budget`,
`file_changed_or_short_read`, or `file_unavailable`. Its `system_code` is
@@ -657,3 +697,11 @@ REA then preserves ownership uncertainty and can report `cleanup_incomplete`;
it does not disable verification to continue. A sandbox that explicitly allows
this read-only process inspector is a separate prerequisite from the compiler
and cache settings.
Symlink observations preserve their stored target bytes in `symlink_target_hex`
(lowercase hexadecimal). `symlink_target` retains valid UTF-8 text and is `null`
when the target bytes cannot be decoded as UTF-8. Filesystem effects compare
these exact bytes without resolving the link. Older captures without the hex
field still parse; a legacy target containing U+FFFD has ambiguous byte identity,
so matching target text alone produces an `unknown` effect. Symlink descendants
remain outside filesystem observation regardless of target encoding.
+49 -6
View File
@@ -20,7 +20,7 @@
**[الموقع](https://rea.tools/ar/) · [الأدلة](https://rea.tools/ar/guides/) · [دراسات الحالة](https://rea.tools/ar/showcase/)**
[البدء السريع](#البدء-السريع) · [كيف يعمل REA](#كيف-يعمل-rea) · [ما الذي يمكنك تحليله](#ما-الذي-يمكنك-تحليله) · [دراسات الحالة](#دراسات-الحالة) · [الأسئلة الشائعة](#الأسئلة-الشائعة) · [أدوات GNU objdump وRizin](../reverse-engineering-tools.md) · [التوثيق](#التوثيق)
[البدء السريع](#البدء-السريع) · [كيف يعمل REA](#كيف-يعمل-rea) · [ما الذي يمكنك تحليله](#ما-الذي-يمكنك-تحليله) · [دراسات الحالة](#دراسات-الحالة) · [إنشاء بيئات التعلم المعزز](#build-rl-environments) · [الأسئلة الشائعة](#الأسئلة-الشائعة) · [أدوات GNU objdump وRizin](../reverse-engineering-tools.md) · [التوثيق](#التوثيق)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@
يربط REA وكيلك بأدوات لفحص الملفات الثنائية للشيفرة الأصلية، وتطبيقات JavaScript وElectron، وتجميعات .NET، والمواقع. يمكنك أيضًا استخدام الأدوات نفسها من الطرفية. يجري التحليل محليًا، وتتضمن النتائج الأدلة والقيود التي تستند إليها كل خلاصة.
يسجّل الإعداد REA لدى وكيلك ويثبّت تعليمات العمل المطابقة. يمكن للتحليل الأصلي استخدام Hopper أو Ghidra أو IDA المثبّت مسبقًا؛ ويمكن تثبيت Hopper بعد موافقتك. لا يحتاج التحليل الثابت لـ JavaScript إلى محرك تحليل أصلي.
يسجّل الإعداد REA لدى وكيلك ويثبّت تعليمات العمل المطابقة. يمكن للتحليل الأصلي استخدام Hopper أو Ghidra أو IDA أو Kuna المثبّت مسبقًا؛ ويمكن تثبيت Hopper بعد موافقتك. لا يحتاج التحليل الثابت لـ JavaScript إلى محرك تحليل أصلي.
> **[زر موقع REA](https://rea.tools/ar/)** للاطلاع على تعليمات الإعداد والأدلة المصوّرة ودراسات الحالة الفعلية.
@@ -151,7 +151,7 @@ npx rea-agents@latest setup
| الهدف | ما يعيده REA | المتطلبات والدليل |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| الملفات الثنائية للشيفرة الأصلية | شيفرة شبه برمجية، وتعليمات تجميع، وسلاسل نصية، ورموز، واستدعاءات، ومراجع | Hopper أو Ghidra أو IDA؛ [تحليل الشيفرة الأصلية](../native-investigation.md) |
| الملفات الثنائية للشيفرة الأصلية | شيفرة شبه برمجية، وتعليمات تجميع، وسلاسل نصية، ورموز، واستدعاءات، ومراجع | Hopper أو Ghidra أو IDA أو Kuna؛ [تحليل الشيفرة الأصلية](../native-investigation.md) |
| بنية ELF دون تشغيل | الأقسام والمقاطع والرموز ومعلومات إعادة التموضع الأصلية، وآليات الحماية المحتملة المستدلّ عليها بالفحص الثابت | pwntools يوفّره المستدعي على Linux x64؛ [تشخيص الملفات الثنائية](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
@@ -225,8 +225,51 @@ npx rea-agents@latest setup
[اقرأ دراسة الحالة](https://rea.tools/ar/showcase/th04/) ·
[مستودع إعادة البناء](https://github.com/N0zoM1z0/th04)
### إنشاء بيئات التعلم المعزز باستخدام REA
سجّل جلسة لتطبيق ويب، وحوّل API إلى أدوات، وصدّر بيئة يستطيع وكيل الذكاء الاصطناعي استخدامها. شغّلها باستخدام AgentEnv، ثم أضف المهام وفحوص المكافآت للتدريب بالتعلم المعزز أو التقييم.
[دليل إنشاء بيئة](https://rea.tools/guides/rl-environments/) ·
[شاهد العرض على X](https://x.com/reatools/status/2112574822584918075?s=20)
إذا استخدمت REA لفحص هدف مثير للاهتمام، فنود الاطلاع عليه. شارك حالتك في [issue](https://github.com/morluto/rea/issues) أو [pull request](https://github.com/morluto/rea/pulls)، مع ذكر الهدف، وسؤالك، وكيف ساعدك REA، وما توصلت إليه.
<a id="build-rl-environments"></a>
## إنشاء بيئات التعلم المعزز
أنشئ بيئة محلية يتدرب فيها وكيل الذكاء الاصطناعي على مهام مثل البحث عن مشكلة أو إنشاء مجلد، دون تشغيل التطبيق الأصلي. استخدمها للتعلم المعزز (RL) أو لاختبار قدرة الوكيل على إنجاز المهام.
يحوّل REA طلبات API والردود المسجلة إلى أدوات يمكن للوكيل استدعاؤها. تستخدم البيئة البيانات المسجلة ولا تدعم التغييرات إلا عندما يؤكد التسجيل آثارها.
بعد إعداد REA في وكيلك، استبدل رابط المثال ومهام المجلدات بما يناسب تطبيقك:
```text
استخدم REA لإنشاء بيئة تعلم معزز من تطبيق الويب الاختباري لدي على
http://127.0.0.1:3000
غطّ عرض المجلدات وإنشاءها وإعادة تسميتها وحذفها. يمكنك إنشاء مجلدات اختبار
وحذفها، لكن لا تغيّر البيانات الموجودة.
احفظ البيئة في مجلد باسم my-env، وتحقق من العمليات المتاحة وأخبرني كيف أشغّلها.
```
<details>
<summary>استخدام سطر الأوامر</summary>
استخدم هذه الأوامر إذا كان لديك ملف يسجل طلبات التطبيق وردوده في المتصفح. يتطلب تشغيل النتيجة أيضًا AgentEnv وDocker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
يصدّر REA بيئة قابلة للتشغيل مع اختبار أساسي يتحقق من بدء تشغيلها واستجابتها. استخدمها مع إطار التعلم المعزز لتحديد أهداف المهام وإضافة فحوص المكافآت وتشغيل التدريب.
[دليل إنشاء بيئة](https://rea.tools/guides/rl-environments/) ·
[مرجع البيئات](../agent-environments.md) ·
[شاهد العرض على X](https://x.com/reatools/status/2112574822584918075?s=20)
## الأسئلة الشائعة
<details>
@@ -237,9 +280,9 @@ npx rea-agents@latest setup
</details>
<details>
<summary><strong>هل أحتاج إلى Hopper أو Ghidra أو IDA؟</strong></summary>
<summary><strong>هل أحتاج إلى Hopper أو Ghidra أو IDA أو Kuna؟</strong></summary>
يستخدم تحليل الشيفرة الأصلية المتعمق أحدها. يعمل الفحص الثابت لـ JavaScript و.NET دون محرك لتحليل الشيفرة الأصلية. يستطيع الإعداد تثبيت Hopper بعد الموافقة؛ أما Ghidra وIDA فيستخدمان تثبيتاتك الموجودة. راجع [إعداد الموفّرين](../installation.md#hopper).
يستخدم تحليل الشيفرة الأصلية المتعمق أحدها. يعمل الفحص الثابت لـ JavaScript و.NET دون محرك لتحليل الشيفرة الأصلية. يستطيع الإعداد تثبيت Hopper بعد الموافقة؛ أما Ghidra وIDA وKuna فتستخدم تثبيتاتك الموجودة. راجع [إعداد الموفّرين](../installation.md#hopper).
</details>
@@ -307,7 +350,7 @@ npx rea-agents@latest setup
## سجل النجوم
🎉 **300,000 نجمة على GitHub — شكرًا لكم!**
🎉 **400,000 نجمة على GitHub — شكرًا لكم!**
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
+51 -6
View File
@@ -20,7 +20,7 @@
**[Website](https://rea.tools/de/) · [Anleitungen](https://rea.tools/de/guides/) · [Fallstudien](https://rea.tools/de/showcase/)**
[Schnellstart](#schnellstart) · [So funktioniert REA](#so-funktioniert-rea) · [Was du analysieren kannst](#was-du-analysieren-kannst) · [Fallstudien](#fallstudien) · [Häufige Fragen](#häufige-fragen) · [GNU-objdump- und Rizin-Tools](../reverse-engineering-tools.md) · [Dokumentation](#dokumentation)
[Schnellstart](#schnellstart) · [So funktioniert REA](#so-funktioniert-rea) · [Was du analysieren kannst](#was-du-analysieren-kannst) · [Fallstudien](#fallstudien) · [RL-Umgebungen erstellen](#build-rl-environments) · [Häufige Fragen](#häufige-fragen) · [Dokumentation](#dokumentation)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@ Du hast in einer App eine Funktion entdeckt, die du in dein eigenes Produkt übe
REA verbindet deinen Agenten mit Werkzeugen zum Untersuchen nativer Binärdateien, von JavaScript- und Electron-Apps, .NET-Assemblies und Websites. Dieselben Werkzeuge kannst du auch im Terminal nutzen. Die Analyse läuft lokal; die Ergebnisse enthalten die Belege und Einschränkungen hinter jeder Schlussfolgerung.
Die Einrichtung registriert REA bei deinem Agenten und installiert passende Workflow-Anweisungen. Native Analysen nutzen eine vorhandene Installation von Hopper, Ghidra oder IDA; nach Zustimmung kann die Einrichtung Hopper installieren. Statische JavaScript-Analysen benötigen keine native Analyse-Engine.
Die Einrichtung registriert REA bei deinem Agenten und installiert passende Workflow-Anweisungen. Native Analysen nutzen eine vorhandene Installation von Hopper, Ghidra, IDA oder Kuna; nach Zustimmung kann die Einrichtung Hopper installieren. Statische JavaScript-Analysen benötigen keine native Analyse-Engine.
> **[Besuche die REA-Website](https://rea.tools/de/)** für Einrichtungshinweise, bebilderte Anleitungen und echte Fallstudien.
@@ -151,7 +151,7 @@ REA benötigt Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) oder 26+ (>=26.12.1) so
| Ziel | Was REA zurückgibt | Voraussetzungen und Anleitung |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Native Binärdateien | Pseudocode, Assemblercode, Zeichenketten, Symbole, Aufrufe und Verweise | Hopper, Ghidra oder IDA; [native Analyse](../native-investigation.md) |
| Native Binärdateien | Pseudocode, Assemblercode, Zeichenketten, Symbole, Aufrufe und Verweise | Hopper, Ghidra, IDA oder Kuna; [native Analyse](../native-investigation.md) |
| Offline-ELF-Struktur | Sektionen, Segmente, ursprüngliche Symbole/Relokationen und mögliche Schutzmaßnahmen aus statischer Analyse | Vom Aufrufer bereitgestelltes pwntools unter Linux x64; [Binärdiagnostik](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
@@ -190,6 +190,8 @@ REA benötigt Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) oder 26+ (>=26.12.1) so
Statische JavaScript- und .NET-Untersuchungen lesen die bereitgestellten Dateien, ohne die Anwendung auszuführen. Laufzeitaufzeichnungen führen das gewählte Ziel mit deinen Benutzerrechten aus oder interagieren damit; die jeweiligen Anleitungen beschreiben die Auswirkungen.
Für die Offline-Untersuchung nativer Binärdateien unterstützt REA auch GNU objdump und Rizin, die du selbst bereitstellst. Der [Leitfaden zu Reverse-Engineering-Tools](../reverse-engineering-tools.md) beschreibt die Einrichtung der Provider, CLI-Befehle und Einschränkungen der Evidence. REA installiert oder aktualisiert keinen der beiden Provider.
<a id="choosing-a-deep-analysis-provider"></a>
Bei großen Binärdateien kannst du die Startfrist mit `REA_GHIDRA_STARTUP_TIMEOUT_MS` oder `REA_HOPPER_STARTUP_TIMEOUT_MS` erhöhen.
@@ -223,8 +225,51 @@ Untersuche die 16-Bit-Anweisungen des ursprünglichen PC-98-Spiels, rekonstruier
[Fallstudie lesen](https://rea.tools/de/showcase/th04/) · [Rekonstruktionsrepository](https://github.com/N0zoM1z0/th04)
### RL-Umgebungen mit REA erstellen
Zeichne eine Webanwendungssitzung auf, verwandle ihre API in Werkzeuge und exportiere eine Umgebung für einen KI-Agenten. Starte sie mit AgentEnv und ergänze Aufgaben und Belohnungsprüfungen für RL-Training oder Bewertung.
[Anleitung zum Erstellen einer Umgebung](https://rea.tools/guides/rl-environments/) ·
[Demo auf X ansehen](https://x.com/reatools/status/2112574822584918075?s=20)
Wenn du mit REA etwas Interessantes untersucht hast, würden wir es gern sehen. Teile deine Fallstudie in einem [Issue](https://github.com/morluto/rea/issues) oder [Pull Request](https://github.com/morluto/rea/pulls) und beschreibe das Ziel, deine Frage, wie REA geholfen hat und was du herausgefunden hast.
<a id="build-rl-environments"></a>
## RL-Umgebungen erstellen
Erstelle eine lokale Umgebung, in der ein KI-Agent Aufgaben wie das Finden eines Issues oder das Anlegen eines Ordners üben kann, ohne die ursprüngliche App auszuführen. Nutze sie für Reinforcement Learning (RL) oder um zu testen, wie gut ein Agent Aufgaben erledigt.
REA wandelt aufgezeichnete API-Anfragen und Antworten in Werkzeuge um, die der Agent aufrufen kann. Die Umgebung nutzt die aufgezeichneten Daten und unterstützt Änderungen nur, wenn die Aufzeichnung deren Wirkung bestätigt.
Richte REA in deinem Agenten ein und ersetze die Beispiel-URL und die Ordneraufgaben durch deine eigenen:
```text
Erstelle mit REA eine RL-Umgebung aus meiner Test-Web-App unter
http://127.0.0.1:3000.
Decke das Auflisten, Erstellen, Umbenennen und Löschen von Ordnern ab.
Du darfst Testordner anlegen und entfernen. Lass bestehende Daten unverändert.
Speichere sie in einem Ordner namens my-env, prüfe die verfügbaren Operationen und erkläre mir den Start.
```
<details>
<summary>Stattdessen die Befehlszeile verwenden</summary>
Nutze diese Befehle, wenn du bereits eine Datei mit aufgezeichneten Browseranfragen und Antworten der App hast. Zum Ausführen des Ergebnisses brauchst du außerdem AgentEnv und Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA exportiert eine lauffähige Umgebung mit einem einfachen Test, der prüft, ob sie startet und antwortet. Nutze sie mit deinem RL-Framework, um Aufgabenziele und Belohnungsprüfungen festzulegen und das Training auszuführen.
[Anleitung zum Erstellen einer Umgebung](https://rea.tools/guides/rl-environments/) ·
[Umgebungsreferenz](../agent-environments.md) ·
[Demo auf X ansehen](https://x.com/reatools/status/2112574822584918075?s=20)
## Häufige Fragen
<details>
@@ -235,9 +280,9 @@ Jeder Agent, der lokale MCP-Server unterstützt. Die Einrichtung konfiguriert di
</details>
<details>
<summary><strong>Brauche ich Hopper, Ghidra oder IDA?</strong></summary>
<summary><strong>Brauche ich Hopper, Ghidra, IDA oder Kuna?</strong></summary>
Für tiefgehende native Analysen wird eines dieser Programme verwendet. Statische JavaScript- und .NET-Untersuchungen funktionieren ohne native Analyse-Engine. Die Einrichtung kann Hopper nach Zustimmung installieren; Ghidra und IDA nutzen deine vorhandenen Installationen. Siehe [Provider-Einrichtung](../installation.md#hopper).
Für tiefgehende native Analysen wird eines dieser Programme verwendet. Statische JavaScript- und .NET-Untersuchungen funktionieren ohne native Analyse-Engine. Die Einrichtung kann Hopper nach Zustimmung installieren; Ghidra, IDA und Kuna nutzen deine vorhandenen Installationen. Siehe [Provider-Einrichtung](../installation.md#hopper).
</details>
@@ -305,7 +350,7 @@ Melde Sicherheitslücken gemäß [SECURITY.md](../../SECURITY.md).
## Sternverlauf
🎉 **300.000 GitHub-Sterne – vielen Dank!**
🎉 **400.000 GitHub-Sterne – vielen Dank!**
Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds testen und Fehlerbehebungen beitragen.
+49 -6
View File
@@ -19,7 +19,7 @@
**[Ιστότοπος](https://rea.tools/) · [Οδηγοί](https://rea.tools/guides/) · [Μελέτες περίπτωσης](https://rea.tools/showcase/)**
[Γρήγορη εκκίνηση](#γρήγορη-εκκίνηση) · [Πώς λειτουργεί το REA](#πώς-λειτουργεί-το-rea) · [Τι μπορείς να αναλύσεις](#τι-μπορείς-να-αναλύσεις) · [Μελέτες περίπτωσης](#μελέτες-περίπτωσης) · [Συχνές ερωτήσεις](#συχνές-ερωτήσεις) · [Τεκμηρίωση](#τεκμηρίωση)
[Γρήγορη εκκίνηση](#γρήγορη-εκκίνηση) · [Πώς λειτουργεί το REA](#πώς-λειτουργεί-το-rea) · [Τι μπορείς να αναλύσεις](#τι-μπορείς-να-αναλύσεις) · [Μελέτες περίπτωσης](#μελέτες-περίπτωσης) · [Δημιουργία περιβαλλόντων RL](#build-rl-environments) · [Συχνές ερωτήσεις](#συχνές-ερωτήσεις) · [Τεκμηρίωση](#τεκμηρίωση)
<code>npx rea-agents setup</code>
@@ -62,7 +62,7 @@
Το REA συνδέει τον πράκτορά σου με εργαλεία εξέτασης δυαδικών αρχείων με κώδικα μηχανής, εφαρμογών JavaScript και Electron, assemblies .NET και ιστοτόπων. Μπορείς να χρησιμοποιήσεις τα ίδια εργαλεία και από το τερματικό. Η ανάλυση εκτελείται τοπικά και τα αποτελέσματα περιλαμβάνουν τα τεκμήρια και τους περιορισμούς στους οποίους βασίζεται κάθε συμπέρασμα.
Η διαδικασία εγκατάστασης καταχωρίζει το REA στον agent σου και εγκαθιστά τις αντίστοιχες οδηγίες εργασίας. Για ανάλυση κώδικα μηχανής μπορείς να χρησιμοποιήσεις μια υπάρχουσα εγκατάσταση του Hopper, του Ghidra ή του IDA. Η διαδικασία εγκατάστασης μπορεί επίσης να εγκαταστήσει το Hopper, εφόσον το εγκρίνεις. Η στατική ανάλυση JavaScript δεν χρειάζεται μηχανή ανάλυσης κώδικα μηχανής.
Η διαδικασία εγκατάστασης καταχωρίζει το REA στον agent σου και εγκαθιστά τις αντίστοιχες οδηγίες εργασίας. Για ανάλυση κώδικα μηχανής μπορείς να χρησιμοποιήσεις μια υπάρχουσα εγκατάσταση του Hopper, του Ghidra, του IDA ή του Kuna. Η διαδικασία εγκατάστασης μπορεί επίσης να εγκαταστήσει το Hopper, εφόσον το εγκρίνεις. Η στατική ανάλυση JavaScript δεν χρειάζεται μηχανή ανάλυσης κώδικα μηχανής.
> **[Επισκέψου τον ιστότοπο του REA](https://rea.tools/)** για οδηγίες εγκατάστασης, εικονογραφημένους οδηγούς και πραγματικές μελέτες περίπτωσης.
@@ -151,7 +151,7 @@ npx rea-agents@latest setup
| Στόχος | Τι επιστρέφει το REA | Απαιτήσεις και οδηγός |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Δυαδικά αρχεία με κώδικα μηχανής | Ψευδοκώδικα, κώδικα assembly, συμβολοσειρές, σύμβολα, κλήσεις και αναφορές | Hopper, Ghidra ή IDA· [ανάλυση κώδικα μηχανής](../native-investigation.md) |
| Δυαδικά αρχεία με κώδικα μηχανής | Ψευδοκώδικα, κώδικα assembly, συμβολοσειρές, σύμβολα, κλήσεις και αναφορές | Hopper, Ghidra, IDA ή Kuna· [ανάλυση κώδικα μηχανής](../native-investigation.md) |
| Δομή ELF χωρίς εκτέλεση | Ενότητες, τμήματα, αρχικά σύμβολα/εγγραφές μετεγκατάστασης και ενδείξεις πιθανών μέτρων προστασίας από στατική ανάλυση | pwntools που παρέχει ο χρήστης σε Linux x64· [διαγνωστικά δυαδικών αρχείων](../binary-diagnostics.md) |
| Δυαδικά αρχεία Go | Ενσωματωμένη έκδοση μεταγλωττιστή, modules, αντικαταστάσεις και ρυθμίσεις μεταγλώττισης | Ενσωματωμένη στατική εξέταση ELF/PE/thin Mach-O· δεν απαιτείται εγκατάσταση του Go |
| Δυαδικά αρχεία Rust | Ενσωματωμένα ονόματα, εκδόσεις, πηγές και σχέσεις εξάρτησης των crates από το cargo-auditable | Ενσωματωμένη στατική εξέταση ELF/PE/thin Mach-O· [δυαδικά αρχεία Rust](../rust-binaries.md) |
@@ -227,8 +227,51 @@ npx rea-agents@latest setup
[Διάβασε τη μελέτη περίπτωσης](https://rea.tools/showcase/th04/) · [Αποθετήριο ανακατασκευής](https://github.com/N0zoM1z0/th04)
### Δημιουργία περιβαλλόντων RL με το REA
Καταγράψτε μια συνεδρία εφαρμογής ιστού, μετατρέψτε το API της σε εργαλεία και εξαγάγετε ένα περιβάλλον για πράκτορα AI. Εκτελέστε το με το AgentEnv και προσθέστε εργασίες και ελέγχους ανταμοιβής για εκπαίδευση RL ή αξιολόγηση.
[Οδηγός δημιουργίας περιβάλλοντος](https://rea.tools/guides/rl-environments/) ·
[Δείτε το demo στο X](https://x.com/reatools/status/2112574822584918075?s=20)
Αν χρησιμοποίησες το REA για κάτι ενδιαφέρον, θα θέλαμε να το δούμε. Μοιράσου τη μελέτη σου σε ένα [issue](https://github.com/morluto/rea/issues) ή [pull request](https://github.com/morluto/rea/pulls), αναφέροντας τον στόχο, το ερώτημά σου, πώς βοήθησε το REA και τι ανακάλυψες.
<a id="build-rl-environments"></a>
## Δημιουργία περιβαλλόντων RL
Δημιουργήστε ένα τοπικό περιβάλλον όπου ένας πράκτορας AI εξασκείται σε εργασίες όπως η εύρεση ενός issue ή η δημιουργία φακέλου, χωρίς να εκτελείται η αρχική εφαρμογή. Χρησιμοποιήστε το για ενισχυτική μάθηση (RL) ή για να ελέγξετε πόσο καλά ολοκληρώνει εργασίες ο πράκτορας.
Το REA μετατρέπει καταγεγραμμένα αιτήματα και απαντήσεις API σε εργαλεία που μπορεί να καλεί ο πράκτορας. Το περιβάλλον χρησιμοποιεί τα καταγεγραμμένα δεδομένα και υποστηρίζει αλλαγές μόνο όταν η καταγραφή επιβεβαιώνει τα αποτελέσματά τους.
Ρυθμίστε το REA στον πράκτορά σας και προσαρμόστε το URL και τις εργασίες φακέλων του παραδείγματος:
```text
Χρησιμοποίησε το REA για να δημιουργήσεις περιβάλλον RL από τη δοκιμαστική εφαρμογή μου:
http://127.0.0.1:3000
Κάλυψε προβολή, δημιουργία, μετονομασία και διαγραφή φακέλων. Μπορείς να δημιουργείς
και να αφαιρείς δοκιμαστικούς φακέλους, αλλά μην αλλάξεις τα υπάρχοντα δεδομένα.
Αποθήκευσέ το σε φάκελο my-env, έλεγξε τις διαθέσιμες λειτουργίες και πες μου πώς εκτελείται.
```
<details>
<summary>Χρήση της γραμμής εντολών</summary>
Χρησιμοποιήστε αυτές τις εντολές αν έχετε ήδη αρχείο με τα καταγεγραμμένα αιτήματα και τις απαντήσεις της εφαρμογής στο πρόγραμμα περιήγησης. Η εκτέλεση χρειάζεται επίσης AgentEnv και Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
Το REA εξάγει ένα εκτελέσιμο περιβάλλον με μια βασική δοκιμή εκκίνησης και απόκρισης. Συνδέστε το στο πλαίσιο RL για να ορίσετε στόχους, να προσθέσετε ελέγχους ανταμοιβής και να εκτελέσετε εκπαίδευση.
[Οδηγός δημιουργίας περιβάλλοντος](https://rea.tools/guides/rl-environments/) ·
[Αναφορά περιβαλλόντων](../agent-environments.md) ·
[Δείτε το demo στο X](https://x.com/reatools/status/2112574822584918075?s=20)
## Συχνές ερωτήσεις
<details>
@@ -239,9 +282,9 @@ npx rea-agents@latest setup
</details>
<details>
<summary><strong>Χρειάζομαι Hopper, Ghidra ή IDA;</strong></summary>
<summary><strong>Χρειάζομαι Hopper, Ghidra, IDA ή Kuna;</strong></summary>
Η εις βάθος ανάλυση κώδικα μηχανής χρησιμοποιεί ένα από αυτά. Η στατική εξέταση JavaScript και .NET λειτουργεί χωρίς μηχανή ανάλυσης κώδικα μηχανής. Η διαδικασία εγκατάστασης μπορεί να εγκαταστήσει το Hopper μετά την έγκρισή σου· το Ghidra και το IDA χρησιμοποιούν τις υπάρχουσες εγκαταστάσεις σου. Δες τη [ρύθμιση παρόχων ανάλυσης](../installation.md#hopper).
Η εις βάθος ανάλυση κώδικα μηχανής χρησιμοποιεί ένα από αυτά. Η στατική εξέταση JavaScript και .NET λειτουργεί χωρίς μηχανή ανάλυσης κώδικα μηχανής. Η διαδικασία εγκατάστασης μπορεί να εγκαταστήσει το Hopper μετά την έγκρισή σου· το Ghidra, το IDA και το Kuna χρησιμοποιούν τις υπάρχουσες εγκαταστάσεις σου. Δες τη [ρύθμιση παρόχων ανάλυσης](../installation.md#hopper).
</details>
@@ -309,7 +352,7 @@ npx rea-agents@latest setup
## Ιστορικό αστεριών
🎉 **300.000 αστέρια στο GitHub — σας ευχαριστούμε!**
🎉 **400.000 αστέρια στο GitHub — σας ευχαριστούμε!**
Ευχαριστούμε όλους όσοι χρησιμοποιούν το REA, αναφέρουν σφάλματα, ζητούν νέες λειτουργίες, δοκιμάζουν builds και συνεισφέρουν διορθώσεις.
+51 -6
View File
@@ -20,7 +20,7 @@
**[Sitio web](https://rea.tools/es/) · [Guías](https://rea.tools/es/guides/) · [Casos prácticos](https://rea.tools/es/showcase/)**
[Inicio rápido](#inicio-rápido) · [Cómo funciona REA](#cómo-funciona-rea) · [Qué puedes analizar](#qué-puedes-analizar) · [Casos prácticos](#casos-prácticos) · [Preguntas frecuentes](#preguntas-frecuentes) · [Herramientas GNU objdump y Rizin](../reverse-engineering-tools.md) · [Documentación](#documentación)
[Inicio rápido](#inicio-rápido) · [Cómo funciona REA](#cómo-funciona-rea) · [Qué puedes analizar](#qué-puedes-analizar) · [Casos prácticos](#casos-prácticos) · [Crear entornos de RL](#build-rl-environments) · [Preguntas frecuentes](#preguntas-frecuentes) · [Documentación](#documentación)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@
REA conecta tu agente con herramientas para inspeccionar binarios nativos, aplicaciones JavaScript y Electron, ensamblados .NET y sitios web. También puedes usar las mismas herramientas desde la terminal. El análisis se ejecuta localmente y los resultados incluyen las pruebas y limitaciones que sustentan cada conclusión.
La configuración registra REA con tu agente e instala las instrucciones de trabajo correspondientes. El análisis nativo puede usar Hopper, Ghidra o IDA ya instalados; la configuración puede instalar Hopper con tu aprobación. El análisis estático de JavaScript no requiere un motor de análisis nativo.
La configuración registra REA con tu agente e instala las instrucciones de trabajo correspondientes. El análisis nativo puede usar Hopper, Ghidra, IDA o Kuna ya instalados; la configuración puede instalar Hopper con tu aprobación. El análisis estático de JavaScript no requiere un motor de análisis nativo.
> **[Visita el sitio web de REA](https://rea.tools/es/)** para encontrar instrucciones de configuración, guías ilustradas y casos reales.
@@ -151,7 +151,7 @@ REA requiere Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), adem
| Objetivo | Qué devuelve REA | Requisitos y guía |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Binarios nativos | Pseudocódigo, ensamblador, cadenas, símbolos, llamadas y referencias | Hopper, Ghidra o IDA; [análisis nativo](../native-investigation.md) |
| Binarios nativos | Pseudocódigo, ensamblador, cadenas, símbolos, llamadas y referencias | Hopper, Ghidra, IDA o Kuna; [análisis nativo](../native-investigation.md) |
| Estructura ELF sin ejecutar | Secciones, segmentos, símbolos/reubicaciones originales y posibles medidas de mitigación detectadas mediante análisis estático | pwntools proporcionado por quien llama, en Linux x64; [diagnóstico de binarios](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
@@ -190,6 +190,8 @@ REA requiere Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), adem
La inspección estática de JavaScript y .NET lee los archivos suministrados sin ejecutar la aplicación. La captura en ejecución inicia el objetivo seleccionado o interactúa con él con los permisos de tu usuario; cada guía describe sus efectos.
Para inspeccionar binarios nativos sin conexión, REA también admite GNU objdump y Rizin, que debes proporcionar por tu cuenta. La [guía de herramientas de ingeniería inversa](../reverse-engineering-tools.md) explica la configuración de los proveedores, los comandos de la CLI y las limitaciones de Evidence. REA no instala ni actualiza ninguno de estos proveedores.
<a id="choosing-a-deep-analysis-provider"></a>
Para binarios grandes, aumenta el plazo de inicio mediante `REA_GHIDRA_STARTUP_TIMEOUT_MS` o `REA_HOPPER_STARTUP_TIMEOUT_MS`.
@@ -223,8 +225,51 @@ Inspecciona las instrucciones de 16 bits del juego original para PC-98, recupera
[Lee el caso práctico](https://rea.tools/es/showcase/th04/) · [Repositorio de reconstrucción](https://github.com/N0zoM1z0/th04)
### Crear entornos de RL con REA
Graba una sesión de una aplicación web, convierte su API en herramientas y exporta un entorno que un agente de IA pueda usar. Ejecútalo con AgentEnv y añade tareas y comprobaciones de recompensa para entrenamiento RL o evaluación.
[Guía para crear un entorno](https://rea.tools/guides/rl-environments/) ·
[Ver la demo en X](https://x.com/reatools/status/2112574822584918075?s=20)
Si has usado REA para investigar algo interesante, nos gustaría verlo. Comparte tu caso en una [issue](https://github.com/morluto/rea/issues) o una [pull request](https://github.com/morluto/rea/pulls), incluyendo el objetivo, tu pregunta, cómo te ayudó REA y qué encontraste.
<a id="build-rl-environments"></a>
## Crear entornos de RL
Crea un entorno local donde un agente de IA pueda practicar tareas como buscar un issue o crear una carpeta, sin ejecutar la aplicación original. Úsalo para aprendizaje por refuerzo (RL) o para comprobar cómo completa las tareas un agente.
REA convierte las solicitudes y respuestas de API grabadas en herramientas que el agente puede llamar. El entorno usa los datos grabados y solo admite cambios cuyos efectos confirma la grabación.
Configura REA en tu agente y sustituye la URL y las tareas de carpetas del ejemplo por las tuyas:
```text
Usa REA para crear un entorno de RL a partir de mi aplicación web de prueba en
http://127.0.0.1:3000.
Incluye listar, crear, renombrar y borrar carpetas. Puedes crear y borrar
carpetas de prueba, pero no modifiques los datos existentes.
Guárdalo en una carpeta llamada my-env, comprueba qué operaciones funcionan y dime cómo ejecutarlo.
```
<details>
<summary>Usar la línea de comandos</summary>
Usa estos comandos si ya tienes un archivo con las solicitudes y respuestas de la aplicación grabadas en el navegador. Para ejecutar el resultado también necesitas AgentEnv y Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA exporta un entorno ejecutable con una prueba básica que comprueba que arranca y responde. Úsalo con tu framework de RL para definir objetivos, añadir comprobaciones de recompensa y ejecutar el entrenamiento.
[Guía para crear un entorno](https://rea.tools/guides/rl-environments/) ·
[Referencia de entornos](../agent-environments.md) ·
[Ver la demo en X](https://x.com/reatools/status/2112574822584918075?s=20)
## Preguntas frecuentes
<details>
@@ -235,9 +280,9 @@ Cualquier agente que admita servidores MCP locales. La configuración prepara lo
</details>
<details>
<summary><strong>¿Necesito Hopper, Ghidra o IDA?</strong></summary>
<summary><strong>¿Necesito Hopper, Ghidra, IDA o Kuna?</strong></summary>
El análisis nativo en profundidad utiliza uno de ellos. La inspección estática de JavaScript y .NET funciona sin un motor de análisis nativo. La configuración puede instalar Hopper después de tu aprobación; Ghidra e IDA usan las instalaciones que ya tienes. Consulta [configuración de proveedores](../installation.md#hopper).
El análisis nativo en profundidad utiliza uno de ellos. La inspección estática de JavaScript y .NET funciona sin un motor de análisis nativo. La configuración puede instalar Hopper después de tu aprobación; Ghidra, IDA y Kuna usan las instalaciones que ya tienes. Consulta [configuración de proveedores](../installation.md#hopper).
</details>
@@ -305,7 +350,7 @@ Informa de vulnerabilidades siguiendo [SECURITY.md](../../SECURITY.md).
## Historial de estrellas
🎉 **300.000 estrellas en GitHub: ¡gracias!**
🎉 **400.000 estrellas en GitHub: ¡gracias!**
Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban compilaciones y contribuyen con correcciones.
+51 -6
View File
@@ -20,7 +20,7 @@
**[وب‌سایت](https://rea.tools/fa/) · [راهنماها](https://rea.tools/fa/guides/) · [نمونه‌های عملی](https://rea.tools/fa/showcase/)**
[شروع سریع](#شروع-سریع) · [REA چگونه کار می‌کند؟](#rea-چگونه-کار-می‌کند) · [چه چیزهایی را میتوان تحلیل کرد؟](#چه-چیزهایی-را-می‌توان-تحلیل-کرد) · [نمونه‌های عملی](#نمونه‌های-عملی) · [پرسش‌های متداول](#پرسش‌های-متداول) · [ابزارهای GNU objdump و Rizin](../reverse-engineering-tools.md) · [مستندات](#مستندات)
[شروع سریع](#شروع-سریع) · [REA چگونه کار می‌کند؟](#rea-چگونه-کار-می‌کند) · [چه چیزهایی را میتوان تحلیل کرد؟](#چه-چیزهایی-را-می‌توان-تحلیل-کرد) · [نمونه‌های عملی](#نمونه‌های-عملی) · [ساخت محیط‌های RL](#build-rl-environments) · [پرسش‌های متداول](#پرسش‌های-متداول) · [مستندات](#مستندات)
<code>npx rea-agents setup</code>
@@ -52,7 +52,7 @@
REA ایجنت شما را به ابزارهایی برای بررسی باینری‌های بومی، برنامه‌های JavaScript و Electron، اسمبلی‌های .NET و وب‌سایت‌ها متصل می‌کند. همین ابزارها از ترمینال نیز قابل استفاده‌اند. تحلیل به‌صورت محلی انجام می‌شود و نتایج شامل شواهد و محدودیت‌های پشت هر نتیجه‌گیری هستند.
راه‌اندازی، REA را در ایجنت ثبت و دستورالعمل‌های متناظر را نصب می‌کند. تحلیل بومی می‌تواند از Hopper، Ghidra یا IDA موجود استفاده کند؛ نصب Hopper پس از تأیید شما ممکن است. تحلیل ایستای JavaScript به موتور تحلیل بومی نیاز ندارد.
راه‌اندازی، REA را در ایجنت ثبت و دستورالعمل‌های متناظر را نصب می‌کند. تحلیل بومی می‌تواند از Hopper، Ghidra، IDA یا Kuna موجود استفاده کند؛ نصب Hopper پس از تأیید شما ممکن است. تحلیل ایستای JavaScript به موتور تحلیل بومی نیاز ندارد.
> برای دستورالعمل‌های راه‌اندازی، راهنماهای تصویری و مطالعات موردی واقعی، **[به وب‌سایت REA مراجعه کنید](https://rea.tools/fa/)**.
@@ -143,7 +143,7 @@ REA به Node.js 22.x (>=22.23.4)، 24.x (>=24.22.1) یا 26+ (>=26.12.1)، به
| هدف | خروجی REA | پیش‌نیازها و راهنما |
| ---------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| باینری‌های بومی | شبه‌کد، اسمبلی، رشته‌ها، نمادها، فراخوانی‌ها و ارجاعات | Hopper، Ghidra یا IDA؛ [تحلیل بومی](../native-investigation.md) |
| باینری‌های بومی | شبه‌کد، اسمبلی، رشته‌ها، نمادها، فراخوانی‌ها و ارجاعات | Hopper، Ghidra، IDA یا Kuna؛ [تحلیل بومی](../native-investigation.md) |
| ساختار ELF آفلاین | بخش‌ها، سگمنت‌ها، نمادها و relocationهای اصلی و گزینه‌های احتمالی کاهش آسیب‌پذیری ایستا | pwntools تأمین‌شده توسط فراخواننده روی Linux x64؛ [تشخیص باینری](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
@@ -182,6 +182,8 @@ REA به Node.js 22.x (>=22.23.4)، 24.x (>=24.22.1) یا 26+ (>=26.12.1)، به
بررسی ایستای JavaScript و .NET فایل‌های ارائه‌شده را بدون اجرای برنامه می‌خواند. ضبط زمان اجرا، هدف انتخاب‌شده را با مجوزهای کاربری شما اجرا می‌کند یا با آن تعامل دارد؛ آثار این عملیات در راهنمای مربوط به هر نوع ضبط توضیح داده شده‌اند.
برای بررسی آفلاین فایل‌های باینری بومی، REA از GNU objdump و Rizin نیز پشتیبانی می‌کند؛ این ابزارها را باید خودتان فراهم کنید. [راهنمای ابزارهای مهندسی معکوس](../reverse-engineering-tools.md) تنظیم ارائه‌دهندگان، فرمان‌های CLI و محدودیت‌های Evidence را توضیح می‌دهد. REA هیچ‌یک از این دو ارائه‌دهنده را نصب یا به‌روزرسانی نمی‌کند.
<a id="choosing-a-deep-analysis-provider"></a>
برای باینری‌های بزرگ، مهلت شروع را با `REA_GHIDRA_STARTUP_TIMEOUT_MS` یا `REA_HOPPER_STARTUP_TIMEOUT_MS` افزایش دهید.
@@ -215,8 +217,51 @@ API کلیپ‌بورد در renderer را پیدا کنید، مسیر آن ر
[مطالعهٔ موردی](https://rea.tools/fa/showcase/th04/) · [مخزن بازسازی](https://github.com/N0zoM1z0/th04)
### ساخت محیط‌های RL با REA
یک نشست برنامهٔ وب را ضبط کنید، API آن را به ابزار تبدیل کنید و محیطی برای عامل هوش مصنوعی صادر کنید. آن را با AgentEnv اجرا کنید و کارها و بررسی پاداش را برای آموزش RL یا ارزیابی اضافه کنید.
[راهنمای ساخت محیط](https://rea.tools/guides/rl-environments/) ·
[نمایش را در X ببینید](https://x.com/reatools/status/2112574822584918075?s=20)
اگر از REA برای بررسی موضوع جالبی استفاده کرده‌اید، خوشحال می‌شویم آن را به اشتراک بگذارید. یک [issue](https://github.com/morluto/rea/issues) یا [pull request](https://github.com/morluto/rea/pulls) ثبت کنید و هدف، پرسش خود، نقش REA و یافته‌هایتان را توضیح دهید.
<a id="build-rl-environments"></a>
## ساخت محیط‌های RL
محیطی محلی بسازید تا عامل هوش مصنوعی بدون اجرای برنامهٔ اصلی، کارهایی مثل پیدا کردن یک مسئله یا ساخت پوشه را تمرین کند. از آن برای یادگیری تقویتی (RL) یا سنجش توانایی عامل در انجام کارها استفاده کنید.
REA درخواست‌ها و پاسخ‌های ضبط‌شدهٔ API را به ابزارهایی تبدیل می‌کند که عامل می‌تواند فراخوانی کند. محیط از داده‌های ضبط‌شده استفاده می‌کند و فقط تغییراتی را پشتیبانی می‌کند که اثرشان در ضبط تأیید شده باشد.
پس از راه‌اندازی REA در عامل، نشانی نمونه و کارهای مربوط به پوشه را با موارد خودتان جایگزین کنید:
```text
با REA از برنامهٔ وب آزمایشی من در این نشانی یک محیط RL بساز:
http://127.0.0.1:3000
فهرست کردن، ساختن، تغییر نام و حذف پوشه‌ها را پوشش بده. می‌توانی پوشه‌های
آزمایشی بسازی و حذف کنی، اما داده‌های موجود را تغییر نده.
در پوشه‌ای به نام my-env ذخیره کن، عملیات قابل استفاده را بررسی کن و روش اجرا را بگو.
```
<details>
<summary>استفاده از خط فرمان</summary>
اگر فایل ضبط درخواست‌ها و پاسخ‌های برنامه در مرورگر را دارید، از این فرمان‌ها استفاده کنید. اجرای نتیجه به AgentEnv و Docker هم نیاز دارد.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA محیطی آمادهٔ اجرا همراه با یک آزمون ساده برای بررسی شروع به کار و پاسخ‌گویی آن صادر می‌کند. آن را به چارچوب RL متصل کنید تا اهداف کارها و بررسی پاداش را تعریف و آموزش را اجرا کنید.
[راهنمای ساخت محیط](https://rea.tools/guides/rl-environments/) ·
[مرجع محیط‌ها](../agent-environments.md) ·
[نمایش را در X ببینید](https://x.com/reatools/status/2112574822584918075?s=20)
## پرسش‌های متداول
<details><summary><strong>کدام ایجنت‌ها می‌توانند از REA استفاده کنند؟</strong></summary>
@@ -225,9 +270,9 @@ API کلیپ‌بورد در renderer را پیدا کنید، مسیر آن ر
</details>
<details><summary><strong>آیا به Hopper، Ghidra یا IDA نیاز دارم؟</strong></summary>
<details><summary><strong>آیا به Hopper، Ghidra، IDA یا Kuna نیاز دارم؟</strong></summary>
تحلیل عمیق بومی به یکی از آن‌ها نیاز دارد. بررسی ایستای JavaScript و .NET بدون موتور تحلیل بومی کار می‌کند. setup می‌تواند با تأیید شما Hopper را نصب کند؛ Ghidra و IDA از نصب‌های موجود شما استفاده می‌کنند. [راه‌اندازی ارائه‌دهنده](../installation.md#hopper) را ببینید.
تحلیل عمیق بومی به یکی از آن‌ها نیاز دارد. بررسی ایستای JavaScript و .NET بدون موتور تحلیل بومی کار می‌کند. setup می‌تواند با تأیید شما Hopper را نصب کند؛ Ghidra، IDA و Kuna از نصب‌های موجود شما استفاده می‌کنند. [راه‌اندازی ارائه‌دهنده](../installation.md#hopper) را ببینید.
</details>
@@ -290,7 +335,7 @@ npx rea-agents@latest setup
## تاریخچهٔ ستاره‌ها
🎉 **۳۰۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
🎉 **۴۰۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
از همهٔ کسانی که از REA استفاده می‌کنند، خطاها را گزارش می‌دهند، قابلیت‌های جدید پیشنهاد می‌کنند، buildها را آزمایش می‌کنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
+51 -6
View File
@@ -20,7 +20,7 @@
**[Site web](https://rea.tools/fr/) · [Guides](https://rea.tools/fr/guides/) · [Études de cas](https://rea.tools/fr/showcase/)**
[Démarrage rapide](#démarrage-rapide) · [Comment fonctionne REA](#comment-fonctionne-rea) · [Ce que vous pouvez analyser](#ce-que-vous-pouvez-analyser) · [Études de cas](#études-de-cas) · [Questions fréquentes](#questions-fréquentes) · [Outils GNU objdump et Rizin](../reverse-engineering-tools.md) · [Documentation](#documentation)
[Démarrage rapide](#démarrage-rapide) · [Comment fonctionne REA](#comment-fonctionne-rea) · [Ce que vous pouvez analyser](#ce-que-vous-pouvez-analyser) · [Études de cas](#études-de-cas) · [Créer des environnements RL](#build-rl-environments) · [Questions fréquentes](#questions-fréquentes) · [Documentation](#documentation)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@ Vous avez repéré dans une application une fonctionnalité que vous aimeriez av
REA connecte votre agent à des outils d'inspection de binaires natifs, d'applications JavaScript et Electron, d'assemblys .NET et de sites web. Les mêmes outils sont aussi disponibles depuis votre terminal. L'analyse s'exécute localement, et chaque conclusion s'accompagne des preuves et des limites sur lesquelles elle repose.
Setup enregistre REA auprès de votre agent et installe les instructions de workflow correspondantes. L'analyse native peut utiliser une installation existante de Hopper, de Ghidra ou d'IDA ; Setup peut aussi installer Hopper après votre accord. L'analyse statique JavaScript ne nécessite aucun moteur d'analyse natif.
Setup enregistre REA auprès de votre agent et installe les instructions de workflow correspondantes. L'analyse native peut utiliser une installation existante de Hopper, de Ghidra, d'IDA ou de Kuna ; Setup peut aussi installer Hopper après votre accord. L'analyse statique JavaScript ne nécessite aucun moteur d'analyse natif.
> **[Visitez le site web de REA](https://rea.tools/fr/)** pour les instructions d'installation, des guides illustrés et des études de cas réelles.
@@ -150,7 +150,7 @@ REA nécessite Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), ai
| Cible | Ce que REA renvoie | Prérequis et guide |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Binaires natifs | Pseudo-code, assembleur, chaînes, symboles, appels et références | Hopper, Ghidra ou IDA ; [analyse native](../native-investigation.md) |
| Binaires natifs | Pseudo-code, assembleur, chaînes, symboles, appels et références | Hopper, Ghidra, IDA ou Kuna ; [analyse native](../native-investigation.md) |
| Structure ELF hors ligne | Sections, segments, symboles et relocations d'origine, et protections statiques candidates | pwntools fourni par l'utilisateur sous Linux x64 ; [diagnostics binaires](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
@@ -189,6 +189,8 @@ REA nécessite Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), ai
L'inspection statique JavaScript et .NET lit les fichiers fournis sans exécuter l'application. La capture à l'exécution lance la cible choisie ou interagit avec elle avec vos permissions utilisateur ; chaque guide d'exécution décrit ses effets.
Pour inspecter les binaires natifs hors ligne, REA prend aussi en charge GNU objdump et Rizin, que vous devez fournir vous-même. Le [guide des outils de rétro-ingénierie](../reverse-engineering-tools.md) décrit la configuration des fournisseurs, les commandes CLI et les limites des Evidence. REA n’installe ni ne met à jour ces deux fournisseurs.
<a id="choosing-a-deep-analysis-provider"></a>
Les formats natifs et les hôtes pris en charge varient selon le fournisseur. Consultez [la configuration de Hopper et Ghidra](../installation.md#hopper), le [guide IDA](../ida-provider.md), [Kuna](../kuna-provider.md) et [la prise en charge expérimentale de Ghidra sous Windows](../windows-ghidra-p0.md). Ghidra prend aussi en charge [l'analyse DOS 16 bits](../ghidra-dos.md). Pour les gros binaires, augmentez son délai de démarrage avec `REA_GHIDRA_STARTUP_TIMEOUT_MS` / `REA_HOPPER_STARTUP_TIMEOUT_MS`. Pour le choix du fournisseur, consultez le [guide CLI](../cli.md#choose-a-provider). Vérifiez la [disponibilité dans les versions publiées](../installation.md#released-package-and-main) pour les fonctionnalités ajoutées depuis la dernière version npm.
@@ -220,8 +222,51 @@ Inspectez les instructions 16 bits du jeu PC-98 d'origine, retrouvez les calculs
[Lire l'étude de cas](https://rea.tools/fr/showcase/th04/) · [Dépôt de la reconstruction](https://github.com/N0zoM1z0/th04)
### Créer des environnements RL avec REA
Enregistrez une session d’application web, transformez son API en outils et exportez un environnement utilisable par un agent IA. Exécutez-le avec AgentEnv, puis ajoutez des tâches et des vérifications de récompense pour l’entraînement RL ou l’évaluation.
[Guide de création d’un environnement](https://rea.tools/guides/rl-environments/) ·
[Voir la démo sur X](https://x.com/reatools/status/2112574822584918075?s=20)
Si vous avez utilisé REA sur un projet intéressant, nous serions ravis de le découvrir. Partagez votre cas dans une [issue](https://github.com/morluto/rea/issues) ou une [pull request](https://github.com/morluto/rea/pulls), en précisant la cible, votre question, la manière dont REA vous a aidé et ce que vous avez découvert.
<a id="build-rl-environments"></a>
## Créer des environnements RL
Créez un environnement local où un agent IA peut s’exercer à des tâches comme trouver un ticket ou créer un dossier, sans exécuter l’application d’origine. Utilisez-le pour l’apprentissage par renforcement (RL) ou pour tester la capacité d’un agent à accomplir des tâches.
REA transforme les requêtes et réponses API enregistrées en outils que l’agent peut appeler. L’environnement utilise les données enregistrées et ne prend en charge des modifications que si l’enregistrement confirme leurs effets.
Configurez REA dans votre agent, puis adaptez l’URL et les tâches sur les dossiers à votre application :
```text
Utilise REA pour créer un environnement RL à partir de mon application web de test à
http://127.0.0.1:3000.
Couvre la liste, la création, le renommage et la suppression de dossiers.
Tu peux créer et supprimer des dossiers de test. Ne modifie pas les données existantes.
Enregistre-le dans un dossier nommé my-env, vérifie les opérations disponibles et explique-moi comment le lancer.
```
<details>
<summary>Utiliser la ligne de commande</summary>
Utilisez ces commandes si vous disposez déjà d’un fichier contenant les requêtes et réponses de l’application enregistrées dans le navigateur. L’exécution du résultat nécessite aussi AgentEnv et Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA exporte un environnement exécutable avec un test de base qui vérifie qu’il démarre et répond. Utilisez-le avec votre framework RL pour définir les objectifs, ajouter les vérifications de récompense et lancer l’entraînement.
[Guide de création d’un environnement](https://rea.tools/guides/rl-environments/) ·
[Référence des environnements](../agent-environments.md) ·
[Voir la démo sur X](https://x.com/reatools/status/2112574822584918075?s=20)
## Questions fréquentes
<details>
@@ -232,9 +277,9 @@ Tout agent compatible avec les serveurs MCP locaux. Setup configure les [agents
</details>
<details>
<summary><strong>Ai-je besoin de Hopper, Ghidra ou IDA ?</strong></summary>
<summary><strong>Ai-je besoin de Hopper, Ghidra, IDA ou Kuna ?</strong></summary>
L'analyse native approfondie utilise l'un d'eux. L'inspection statique JavaScript et .NET fonctionne sans moteur d'analyse native. Setup peut installer Hopper après votre accord ; Ghidra et IDA utilisent vos installations existantes. Consultez [la configuration des fournisseurs](../installation.md#hopper).
L'analyse native approfondie utilise l'un d'eux. L'inspection statique JavaScript et .NET fonctionne sans moteur d'analyse native. Setup peut installer Hopper après votre accord ; Ghidra, IDA et Kuna utilisent vos installations existantes. Consultez [la configuration des fournisseurs](../installation.md#hopper).
</details>
@@ -302,7 +347,7 @@ Signalez les vulnérabilités via [SECURITY.md](../../SECURITY.md).
## Historique des étoiles
🎉 **300 000 étoiles GitHub — merci !**
🎉 **400 000 étoiles GitHub — merci !**
Merci à toutes les personnes qui utilisent REA, signalent des bugs, proposent des fonctionnalités, testent les builds et contribuent des correctifs.
+54 -9
View File
@@ -20,7 +20,7 @@
**[Situs Web](https://rea.tools/id/) · [Panduan](https://rea.tools/id/guides/) · [Contoh Penggunaan](https://rea.tools/id/showcase/)**
[Mulai Cepat](#mulai-cepat) · [Cara Kerja REA](#cara-kerja-rea) · [Hal yang Dapat Anda Analisis](#hal-yang-dapat-anda-analisis) · [Contoh Penggunaan](#contoh-penggunaan) · [FAQ](#faq) · [Alat GNU objdump dan Rizin](../reverse-engineering-tools.md) · [Dokumentasi](#dokumentasi)
[Mulai Cepat](#mulai-cepat) · [Cara Kerja REA](#cara-kerja-rea) · [Hal yang Dapat Anda Analisis](#hal-yang-dapat-anda-analisis) · [Contoh Penggunaan](#contoh-penggunaan) · [Membangun lingkungan RL](#build-rl-environments) · [FAQ](#faq) · [Dokumentasi](#dokumentasi)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@ Melihat fitur dalam suatu aplikasi yang ingin Anda hadirkan di produk sendiri? M
REA menghubungkan agen Anda dengan berbagai alat untuk memeriksa biner native, aplikasi JavaScript dan Electron, assembly .NET, serta situs web. Anda juga dapat menggunakan alat yang sama dari terminal. Analisis dijalankan secara lokal, dan hasilnya mencakup bukti serta keterbatasan yang mendasari setiap kesimpulan.
Proses penyiapan mendaftarkan REA ke agen Anda dan memasang instruksi alur kerja yang sesuai. Analisis native dapat menggunakan instalasi Hopper, Ghidra, atau IDA yang sudah ada. Proses penyiapan juga dapat memasang Hopper secara opsional setelah mendapatkan persetujuan. Analisis JavaScript statis tidak memerlukan mesin analisis native.
Proses penyiapan mendaftarkan REA ke agen Anda dan memasang instruksi alur kerja yang sesuai. Analisis native dapat menggunakan instalasi Hopper, Ghidra, IDA, atau Kuna yang sudah ada. Proses penyiapan juga dapat memasang Hopper secara opsional setelah mendapatkan persetujuan. Analisis JavaScript statis tidak memerlukan mesin analisis native.
> **[Kunjungi situs web REA](https://rea.tools/id/)** untuk mendapatkan petunjuk penyiapan, panduan bergambar, dan studi kasus nyata.
@@ -153,18 +153,18 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
| Target | Hasil yang diberikan REA | Persyaratan dan panduan |
| -------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Biner native | Pseudocode, assembly, string, simbol, pemanggilan, dan referensi | Hopper, Ghidra, atau IDA; [analisis native](../native-investigation.md) |
| Biner native | Pseudocode, assembly, string, simbol, pemanggilan, dan referensi | Hopper, Ghidra, IDA, atau Kuna; [analisis native](../native-investigation.md) |
| Tata letak ELF offline | Bagian, segmen, simbol/relokasi asli, dan kandidat mitigasi statis | pwntools yang disediakan pemanggil pada Linux x64; [diagnostik biner](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
| Artefak WASM | Validasi, bagian, bentuk WAT import/ekspor yang tepat, dan WAT yang didekode | WABT 1.0.42 yang disediakan pemanggil; `inspect_wasm_artifact` |
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal; [panduan EVM offline](../evm-bytecode.md) |
| Bytecode EVM | Selector dispatch, offset byte, argumen yang disimpulkan, dan sifat mutabilitas | Pembawa data raw/hex lokal di Linux x64; [panduan EVM offline](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.md) |
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.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) |
| Crash Linux yang direkam | Catatan mentah, register/sinyal setiap thread yang direkam, dan kandidat pemetaan opsional | pwntools yang disediakan pemanggil di Linux x64; 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); Linux: procps `ps` |
| Situs web | Struktur halaman, skrip, pengamatan jaringan, dan tangkapan layar yang diminta | Peramban berbasis Chrome; [analisis peramban](../browser-observation.md) |
@@ -192,6 +192,8 @@ Alat tambahan dan dukungan sistem host bergantung pada target yang dianalisis:
Pemeriksaan JavaScript dan .NET statis membaca berkas yang disediakan tanpa menjalankan aplikasinya. Perekaman runtime menjalankan atau berinteraksi dengan target yang dipilih menggunakan izin pengguna Anda. Setiap panduan runtime menjelaskan dampaknya.
Untuk pemeriksaan biner native secara offline, REA juga mendukung GNU objdump dan Rizin yang Anda sediakan sendiri. [Panduan alat rekayasa balik](../reverse-engineering-tools.md) menjelaskan penyiapan penyedia, perintah CLI, dan keterbatasan Evidence. REA tidak menginstal atau memperbarui kedua penyedia tersebut.
<a id="choosing-a-deep-analysis-provider"></a>
Format native dan dukungan sistem host berbeda-beda menurut penyedia. Lihat [penyiapan Hopper dan Ghidra](../installation.md#hopper), [panduan IDA](../ida-provider.md), [Kuna](../kuna-provider.md), dan [dukungan eksperimental Ghidra di Windows](../windows-ghidra-p0.md).
@@ -231,8 +233,51 @@ Periksa instruksi 16-bit dari gim PC-98 asli, pulihkan perhitungan sudut tetap d
[Baca studi kasus](https://rea.tools/id/showcase/th04/) · [Repositori rekonstruksi](https://github.com/N0zoM1z0/th04)
### Bangun lingkungan RL dengan REA
Rekam sesi aplikasi web, ubah API menjadi alat, lalu ekspor lingkungan yang dapat digunakan agen AI. Jalankan dengan AgentEnv dan tambahkan tugas serta pemeriksaan reward untuk pelatihan RL atau evaluasi.
[Panduan membangun lingkungan](https://rea.tools/guides/rl-environments/) ·
[Tonton demo di X](https://x.com/reatools/status/2112574822584918075?s=20)
Jika Anda telah menggunakan REA untuk menganalisis sesuatu yang menarik, kami ingin melihat hasilnya. Bagikan kasus Anda melalui [issue](https://github.com/morluto/rea/issues) atau [pull request](https://github.com/morluto/rea/pulls), sertakan target, pertanyaan Anda, bagaimana REA membantu, dan apa yang Anda temukan.
<a id="build-rl-environments"></a>
## Membangun lingkungan RL
Buat lingkungan lokal agar agen AI dapat berlatih tugas seperti mencari issue atau membuat folder tanpa menjalankan aplikasi aslinya. Gunakan untuk pembelajaran penguatan (RL) atau menguji kemampuan agen menyelesaikan tugas.
REA mengubah permintaan dan respons API yang direkam menjadi alat yang dapat dipanggil agen. Lingkungan memakai data rekaman dan hanya mendukung perubahan yang dampaknya dikonfirmasi oleh rekaman.
Setelah menyiapkan REA di agen, ganti URL contoh dan tugas folder di bawah sesuai aplikasi Anda:
```text
Gunakan REA untuk membuat lingkungan RL dari aplikasi web uji saya di
http://127.0.0.1:3000.
Cakup daftar, pembuatan, penggantian nama, dan penghapusan folder. Boleh membuat
dan menghapus folder uji, tetapi jangan ubah data yang sudah ada.
Simpan dalam folder bernama my-env, periksa operasi yang berfungsi, dan beri tahu cara menjalankannya.
```
<details>
<summary>Gunakan baris perintah</summary>
Gunakan perintah ini jika Anda sudah punya file rekaman permintaan dan respons aplikasi di browser. Untuk menjalankan hasilnya, Anda juga perlu AgentEnv dan Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA mengekspor lingkungan yang dapat dijalankan dengan uji dasar untuk memeriksa bahwa lingkungan mulai dan merespons. Hubungkan ke framework RL untuk menetapkan tujuan tugas, menambahkan pemeriksaan reward, dan menjalankan pelatihan.
[Panduan membangun lingkungan](https://rea.tools/guides/rl-environments/) ·
[Referensi lingkungan](../agent-environments.md) ·
[Tonton demo di X](https://x.com/reatools/status/2112574822584918075?s=20)
## FAQ
<details>
@@ -243,11 +288,11 @@ Agen apa pun yang mendukung server MCP lokal dapat menggunakan REA. Proses penyi
</details>
<details>
<summary><strong>Apakah saya memerlukan Hopper, Ghidra, atau IDA?</strong></summary>
<summary><strong>Apakah saya memerlukan Hopper, Ghidra, IDA, atau Kuna?</strong></summary>
Analisis native mendalam menggunakan salah satu dari ketiganya. Pemeriksaan JavaScript dan .NET statis dapat dilakukan tanpa mesin analisis native.
Analisis native mendalam menggunakan salah satu dari keempatnya. Pemeriksaan JavaScript dan .NET statis dapat dilakukan tanpa mesin analisis native.
Proses penyiapan dapat memasang Hopper setelah memperoleh persetujuan. Ghidra dan IDA menggunakan instalasi yang sudah tersedia. Lihat [penyiapan penyedia](../installation.md#hopper).
Proses penyiapan dapat memasang Hopper setelah memperoleh persetujuan. Ghidra, IDA, dan Kuna menggunakan instalasi yang sudah tersedia. Lihat [penyiapan penyedia](../installation.md#hopper).
</details>
@@ -323,7 +368,7 @@ Laporkan kerentanan melalui [SECURITY.md](../../SECURITY.md).
## Riwayat Bintang
🎉 **300.000 bintang GitHub, terima kasih!**
🎉 **400.000 bintang GitHub, terima kasih!**
Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fitur, menguji build, dan berkontribusi dalam perbaikan.
+53 -8
View File
@@ -20,7 +20,7 @@
**[Sito web](https://rea.tools/it/) · [Guide](https://rea.tools/it/guides/) · [Showcase](https://rea.tools/it/showcase/)**
[Avvio rapido](#avvio-rapido) · [Come funziona REA](#come-funziona-rea) · [Cosa puoi analizzare](#cosa-puoi-analizzare) · [Showcase](#showcase) · [FAQ](#faq) · [Strumenti GNU objdump e Rizin](../reverse-engineering-tools.md) · [Documentazione](#documentazione)
[Avvio rapido](#avvio-rapido) · [Come funziona REA](#come-funziona-rea) · [Cosa puoi analizzare](#cosa-puoi-analizzare) · [Showcase](#showcase) · [Creare ambienti RL](#build-rl-environments) · [FAQ](#faq) · [Documentazione](#documentazione)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@ Hai visto una funzionalità in un'app che vorresti nel tuo prodotto? Chiedi al t
REA collega il tuo agente a strumenti per ispezionare binari nativi, app JavaScript ed Electron, assembly .NET e siti web. Puoi usare gli stessi strumenti anche dal terminale. L'analisi viene eseguita localmente e i risultati includono le prove e i limiti dietro ogni conclusione.
La configurazione registra REA con il tuo agente e installa le istruzioni di workflow corrispondenti. L'analisi nativa può usare un'installazione esistente di Hopper, Ghidra o IDA; la configurazione può installare opzionalmente Hopper previa approvazione. L'analisi statica JavaScript non richiede alcun motore di analisi nativo.
La configurazione registra REA con il tuo agente e installa le istruzioni di workflow corrispondenti. L'analisi nativa può usare un'installazione esistente di Hopper, Ghidra, IDA o Kuna; la configurazione può installare opzionalmente Hopper previa approvazione. L'analisi statica JavaScript non richiede alcun motore di analisi nativo.
> **[Visita il sito web di REA](https://rea.tools/it/)** per istruzioni di configurazione, guide illustrate e veri casi studio.
@@ -150,18 +150,18 @@ REA richiede Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), oltre
| Obiettivo | Cosa restituisce REA | Requisiti e guida |
| ---------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Binari nativi | Pseudocodice, assembly, stringhe, simboli, chiamate e riferimenti | Hopper, Ghidra o IDA; [analisi nativa](../native-investigation.md) |
| Binari nativi | Pseudocodice, assembly, stringhe, simboli, chiamate e riferimenti | Hopper, Ghidra, IDA o Kuna; [analisi nativa](../native-investigation.md) |
| Layout ELF offline | Sezioni, segmenti, simboli/relocazioni originali e candidati mitigazioni statiche | pwntools fornito dal chiamante su Linux x64; [diagnostica binaria](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
| Artefatto WASM | Convalida, sezioni, forme WAT di import/export esatte e WAT decodificato | WABT 1.0.42 fornito dal chiamante; `inspect_wasm_artifact` |
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale; [guida EVM offline](../evm-bytecode.md) |
| Bytecode EVM | Selettori di dispatch, offset dei byte, argomenti inferiti e mutabilità | Carrier raw/hex locale su Linux x64; [guida EVM offline](../evm-bytecode.md) |
| Rust binaries | Embedded cargo-auditable dependency list | [Rust binaries](../rust-binaries.md) |
| ELF notes | PT_NOTE/SHT_NOTE owners, types, GNU build-id and ABI-tag fields | Built-in static ELF inspection; [ELF notes](../elf-notes.md) |
| Linux kernel modules | .modinfo keys, __versions CRCs, this_module presence, and signature trailer | Built-in static ELF inspection; [kernel modules](../kernel-modules.md) |
| Erlang BEAM | IFF chunks, atoms, exports, and tables | Built-in static BEAM inspection; [Erlang BEAM](../erlang-beam.md) |
| Apple IPS crashes | .ips metadata, threads, images, registers and crash classes | Built-in static JSON inspection; [Apple IPS](../apple-ips.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) |
| Crash Linux registrati | Note grezze, registri/segnai di ogni thread registrato e candidati mapping opzionali | pwntools fornito dal chiamante su Linux x64; 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); Linux: procps `ps` |
| Siti web | Struttura della pagina, script, osservazioni di rete e screenshot richiesti | Un browser della famiglia Chrome; [analisi browser](../browser-observation.md) |
@@ -189,6 +189,8 @@ REA richiede Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) o 26+ (>=26.12.1), oltre
L'ispezione statica di JavaScript e .NET legge i file forniti senza eseguire l'applicazione. La cattura a runtime esegue o interagisce con il bersaglio selezionato usando i tuoi permessi utente; ogni guida runtime descrive i suoi effetti.
Per ispezionare offline i binari nativi, REA supporta anche GNU objdump e Rizin, che devi fornire autonomamente. La [guida agli strumenti di reverse engineering](../reverse-engineering-tools.md) descrive la configurazione dei provider, i comandi CLI e i limiti di Evidence. REA non installa né aggiorna questi due provider.
<a id="choosing-a-deep-analysis-provider"></a>
I formati nativi e il supporto host variano in base al provider. Vedi la [configurazione di Hopper e Ghidra](../installation.md#hopper), la [guida IDA](../ida-provider.md), [Kuna](../kuna-provider.md) e il [supporto sperimentale Windows Ghidra](../windows-ghidra-p0.md). Ghidra supporta anche l'[analisi DOS a 16 bit](../ghidra-dos.md). Per binari di grandi dimensioni, aumenta il timeout di avvio con `REA_GHIDRA_STARTUP_TIMEOUT_MS` / `REA_HOPPER_STARTUP_TIMEOUT_MS`. Per la selezione del provider, vedi la [guida CLI](../cli.md#choose-a-provider). Controlla la [disponibilità delle release](../installation.md#released-package-and-main) per le funzionalità aggiunte dall'ultima release npm.
@@ -220,8 +222,51 @@ Ispeziona le istruzioni a 16 bit del gioco PC-98 originale, recupera i calcoli d
[Leggi il case study](https://rea.tools/it/showcase/th04/) · [Repository di ricostruzione](https://github.com/N0zoM1z0/th04)
### Creare ambienti RL con REA
Registra una sessione di un’app web, trasforma la sua API in strumenti ed esporta un ambiente utilizzabile da un agente IA. Eseguilo con AgentEnv, poi aggiungi attività e controlli sulle ricompense per l’addestramento RL o la valutazione.
[Guida alla creazione di un ambiente](https://rea.tools/guides/rl-environments/) ·
[Guarda la demo su X](https://x.com/reatools/status/2112574822584918075?s=20)
Se hai usato REA su qualcosa di interessante, ci piacerebbe vederlo. Condividi il tuo caso in una [issue](https://github.com/morluto/rea/issues) o in una [pull request](https://github.com/morluto/rea/pulls), includendo il bersaglio, la tua domanda, come REA ti ha aiutato e cosa hai scoperto.
<a id="build-rl-environments"></a>
## Creare ambienti RL
Crea un ambiente locale in cui un agente IA possa esercitarsi in attività come cercare una issue o creare una cartella, senza eseguire l’app originale. Usalo per l’apprendimento per rinforzo (RL) o per verificare come l’agente completa le attività.
REA trasforma le richieste e le risposte API registrate in strumenti che l’agente può chiamare. L’ambiente usa i dati registrati e supporta modifiche solo quando la registrazione ne conferma gli effetti.
Configura REA nel tuo agente, poi sostituisci l’URL e le attività sulle cartelle dell’esempio con i tuoi:
```text
Usa REA per creare un ambiente RL dalla mia app web di prova su
http://127.0.0.1:3000.
Includi elenco, creazione, rinomina ed eliminazione delle cartelle. Puoi creare
e rimuovere cartelle di prova, ma non modificare i dati esistenti.
Salvalo in una cartella chiamata my-env, verifica le operazioni disponibili e spiegami come eseguirlo.
```
<details>
<summary>Usare la riga di comando</summary>
Usa questi comandi se hai già un file con le richieste e le risposte dell’app registrate nel browser. Per eseguire il risultato servono anche AgentEnv e Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA esporta un ambiente eseguibile con un test di base che ne verifica l’avvio e le risposte. Usalo con il tuo framework RL per definire gli obiettivi, aggiungere controlli sulle ricompense ed eseguire l’addestramento.
[Guida alla creazione di un ambiente](https://rea.tools/guides/rl-environments/) ·
[Riferimento degli ambienti](../agent-environments.md) ·
[Guarda la demo su X](https://x.com/reatools/status/2112574822584918075?s=20)
## FAQ
<details>
@@ -232,9 +277,9 @@ Qualsiasi agente che supporti server MCP locali. La configurazione configura gli
</details>
<details>
<summary><strong>Ho bisogno di Hopper, Ghidra o IDA?</strong></summary>
<summary><strong>Ho bisogno di Hopper, Ghidra, IDA o Kuna?</strong></summary>
L'analisi nativa profonda ne usa uno. L'ispezione statica di JavaScript e .NET funziona senza un motore di analisi nativo. La configurazione può installare Hopper previa approvazione; Ghidra e IDA usano le tue installazioni esistenti. Vedi [configurazione provider](../installation.md#hopper).
L'analisi nativa profonda ne usa uno. L'ispezione statica di JavaScript e .NET funziona senza un motore di analisi nativo. La configurazione può installare Hopper previa approvazione; Ghidra, IDA e Kuna usano le tue installazioni esistenti. Vedi [configurazione provider](../installation.md#hopper).
</details>
@@ -302,7 +347,7 @@ Segnala vulnerabilità tramite [SECURITY.md](../../SECURITY.md).
## Cronologia delle stelle
🎉 **300.000 stelle su GitHub — grazie!**
🎉 **400.000 stelle su GitHub — grazie!**
Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, testano le build e contribuiscono con correzioni.
+51 -6
View File
@@ -20,7 +20,7 @@
**[ウェブサイト](https://rea.tools/ja/) · [ガイド](https://rea.tools/ja/guides/) · [事例](https://rea.tools/ja/showcase/)**
[クイックスタート](#クイックスタート) · [REA の仕組み](#rea-の仕組み) · [分析できる対象](#分析できる対象) · [事例](#事例) · [よくある質問](#よくある質問) · [GNU objdump・Rizin ツール](../reverse-engineering-tools.md) · [ドキュメント](#ドキュメント)
[クイックスタート](#クイックスタート) · [REA の仕組み](#rea-の仕組み) · [分析できる対象](#分析できる対象) · [事例](#事例) · [RL 環境を構築する](#build-rl-environments) · [よくある質問](#よくある質問) · [ドキュメント](#ドキュメント)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@
REA はエージェントを分析ツールにつなぎ、ネイティブバイナリ、JavaScript や Electron のアプリ、.NET アセンブリ、ウェブサイトを調べられるようにします。同じツールをターミナルからも使えます。分析はローカルで実行され、結果には各結論を裏付ける根拠と制限事項が含まれます。
セットアップはエージェントに REA を登録し、対応するワークフロー指示をインストールします。ネイティブ解析には既存の Hopper、Ghidra、IDA を使用でき、承認すれば Hopper をインストールできます。静的 JavaScript 解析にネイティブ解析エンジンは不要です。
セットアップはエージェントに REA を登録し、対応するワークフロー指示をインストールします。ネイティブ解析には既存の Hopper、Ghidra、IDA、Kuna を使用でき、承認すれば Hopper をインストールできます。静的 JavaScript 解析にネイティブ解析エンジンは不要です。
> **[REA のウェブサイト](https://rea.tools/ja/)**で、セットアップ手順、図解ガイド、実際の事例を確認できます。
@@ -151,7 +151,7 @@ REA には Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)、または 26+ (>=
| 対象 | REA が返すもの | 要件とガイド |
| -------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、または IDA;[ネイティブ分析](../native-investigation.md) |
| ネイティブバイナリ | 疑似コード、アセンブリ、文字列、シンボル、呼び出し、参照 | Hopper、Ghidra、IDA、または Kuna;[ネイティブ分析](../native-investigation.md) |
| オフライン ELF レイアウト | セクション、セグメント、元のシンボル/再配置情報、静的解析によるセキュリティ対策の候補 | Linux x64 で利用者が用意する pwntools;[バイナリ診断](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
@@ -190,6 +190,8 @@ REA には Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)、または 26+ (>=
静的な JavaScript と .NET の検査は、指定されたファイルを読み取り、アプリケーションを実行しません。実行時キャプチャは、あなたのユーザー権限で対象を実行したり、対象とやり取りしたりします。それぞれの実行時ガイドに、どのような操作が行われるかを記載しています。
ネイティブバイナリのオフライン検査では、利用者が用意した GNU objdump と Rizin も使用できます。[リバースエンジニアリングツールのガイド](../reverse-engineering-tools.md)では、プロバイダーのセットアップ、CLI コマンド、Evidence の制約を説明しています。REA はどちらのプロバイダーもインストールや更新を行いません。
<a id="choosing-a-deep-analysis-provider"></a>
大きなバイナリでは `REA_GHIDRA_STARTUP_TIMEOUT_MS` または `REA_HOPPER_STARTUP_TIMEOUT_MS` でプロバイダーの起動期限を延長できます。
@@ -225,8 +227,51 @@ REA には Node.js 22.x(>=22.23.4)、24.x(>=24.22.1)、または 26+ (>=
[事例を読む](https://rea.tools/ja/showcase/th04/) ·
[再構築リポジトリ](https://github.com/N0zoM1z0/th04)
### REA で RL 環境を構築する
Web アプリのセッションを記録し、API をツールに変換して、AI エージェントが使える環境をエクスポートします。AgentEnv で実行し、タスクと報酬のチェックを追加して、RL の学習や評価に使えます。
[環境構築ガイド](https://rea.tools/guides/rl-environments/) ·
[X でデモを見る](https://x.com/reatools/status/2112574822584918075?s=20)
REA で興味深い対象を調べたら、ぜひ共有してください。[issue](https://github.com/morluto/rea/issues) または [pull request](https://github.com/morluto/rea/pulls) に、対象、調べたかったこと、REA がどう役立ったか、何が分かったかを記載してください。
<a id="build-rl-environments"></a>
## RL 環境を構築する
元のアプリを動かさずに、AI エージェントが issue の検索やフォルダーの作成などを練習できるローカル環境を構築します。強化学習(RL)や、エージェントのタスク遂行能力のテストに使えます。
REA は記録した API のリクエストと応答を、エージェントが呼び出せるツールに変換します。環境は記録したデータを使い、記録で効果が確認された変更だけをサポートします。
エージェントに REA を設定したら、次の URL とフォルダー操作を自分の環境に合わせて変更してください。
```text
REA を使い、次のテスト用 Web アプリから RL 環境を構築してください。
http://127.0.0.1:3000
フォルダーの一覧表示、作成、名前変更、削除を対象にしてください。
テスト用フォルダーの作成と削除は許可します。既存のデータは変更しないでください。
my-env というフォルダーに保存し、使える操作を確認して実行方法を教えてください。
```
<details>
<summary>コマンドラインを使う場合</summary>
アプリのブラウザーリクエストと応答を記録したファイルがあれば、このコマンドを使えます。作成した環境の実行には AgentEnv と Docker も必要です。
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA は実行可能な環境と、起動して応答することを確認する基本テストをエクスポートします。RL フレームワークに接続して、タスクの目標や報酬のチェックを定義し、学習を実行できます。
[環境構築ガイド](https://rea.tools/guides/rl-environments/) ·
[環境リファレンス](../agent-environments.md) ·
[X でデモを見る](https://x.com/reatools/status/2112574822584918075?s=20)
## よくある質問
<details>
@@ -237,9 +282,9 @@ REA で興味深い対象を調べたら、ぜひ共有してください。[iss
</details>
<details>
<summary><strong>Hopper、Ghidra、IDA は必要ですか?</strong></summary>
<summary><strong>Hopper、Ghidra、IDA、Kuna は必要ですか?</strong></summary>
深いネイティブ分析には、そのいずれかを使います。静的な JavaScript と .NET の検査には、ネイティブ分析エンジンは必要ありません。セットアップは承認後に Hopper をインストールできます。Ghidra と IDA は既存のインストールを使います。[プロバイダーのセットアップ](../installation.md#hopper)を参照してください。
深いネイティブ分析には、そのいずれかを使います。静的な JavaScript と .NET の検査には、ネイティブ分析エンジンは必要ありません。セットアップは承認後に Hopper をインストールできます。Ghidra、IDA、Kuna は既存のインストールを使います。[プロバイダーのセットアップ](../installation.md#hopper)を参照してください。
</details>
@@ -307,7 +352,7 @@ npx rea-agents@latest setup
## スター履歴
🎉 **GitHub スター 300,000 件、ありがとうございます!**
🎉 **GitHub スター 400,000 件、ありがとうございます!**
REA の利用、バグ報告、機能の要望、ビルドのテスト、修正への貢献に感謝します。
+49 -6
View File
@@ -20,7 +20,7 @@
**[웹사이트](https://rea.tools/ko/) · [가이드](https://rea.tools/ko/guides/) · [사례](https://rea.tools/ko/showcase/)**
[빠른 시작](#빠른-시작) · [REA의 작동 방식](#rea의-작동-방식) · [분석할 수 있는 대상](#분석할-수-있는-대상) · [사례](#사례) · [자주 묻는 질문](#자주-묻는-질문) · [문서](#문서)
[빠른 시작](#빠른-시작) · [REA의 작동 방식](#rea의-작동-방식) · [분석할 수 있는 대상](#분석할-수-있는-대상) · [사례](#사례) · [RL 환경 만들기](#build-rl-environments) · [자주 묻는 질문](#자주-묻는-질문) · [문서](#문서)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@
REA는 에이전트를 분석 도구에 연결해 네이티브 바이너리, JavaScript와 Electron 앱, .NET 어셈블리, 웹사이트를 검사할 수 있게 합니다. 터미널에서도 같은 도구를 사용할 수 있습니다. 분석은 로컬에서 실행되며, 결과에는 각 결론의 근거와 한계가 포함됩니다.
설정 과정은 에이전트에 REA를 등록하고 해당 버전에 맞는 워크플로 지침을 설치합니다. 네이티브 분석에는 기존 Hopper, Ghidra 또는 IDA 설치를 사용할 수 있습니다. 승인하면 설정 과정에서 Hopper를 설치할 수도 있습니다. 정적 JavaScript 분석에는 네이티브 분석 엔진이 필요하지 않습니다.
설정 과정은 에이전트에 REA를 등록하고 해당 버전에 맞는 워크플로 지침을 설치합니다. 네이티브 분석에는 기존 Hopper, Ghidra, IDA 또는 Kuna 설치를 사용할 수 있습니다. 승인하면 설정 과정에서 Hopper를 설치할 수도 있습니다. 정적 JavaScript 분석에는 네이티브 분석 엔진이 필요하지 않습니다.
> <strong>[REA 웹사이트](https://rea.tools/ko/)</strong>에서 설정 방법, 그림으로 설명한 가이드, 실제 사례를 확인하세요.
@@ -151,7 +151,7 @@ REA에는 Node.js 22.x(>=22.23.4), 24.x(>=24.22.1) 또는 26+ (>=26.12.1)와 npm
| 대상 | REA가 반환하는 내용 | 요구 사항 및 가이드 |
| ---------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra 또는 IDA; [네이티브 분석](../native-investigation.md) |
| 네이티브 바이너리 | 의사 코드, 어셈블리, 문자열, 심볼, 호출, 참조 | Hopper, Ghidra, IDA 또는 Kuna; [네이티브 분석](../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) |
@@ -225,8 +225,51 @@ REA에는 Node.js 22.x(>=22.23.4), 24.x(>=24.22.1) 또는 26+ (>=26.12.1)와 npm
[사례 읽기](https://rea.tools/ko/showcase/th04/) ·
[재구현 저장소](https://github.com/N0zoM1z0/th04)
### REA로 RL 환경 만들기
웹 앱 세션을 기록하고 API를 도구로 바꿔 AI 에이전트가 사용할 수 있는 환경을 내보냅니다. AgentEnv로 실행한 뒤 작업과 보상 검사를 추가해 RL 학습이나 평가에 사용하세요.
[환경 만들기 가이드](https://rea.tools/guides/rl-environments/) ·
[X에서 데모 보기](https://x.com/reatools/status/2112574822584918075?s=20)
REA로 흥미로운 대상을 분석했다면 알려 주세요. [issue](https://github.com/morluto/rea/issues) 또는 [pull request](https://github.com/morluto/rea/pulls)에 대상, 조사하려던 질문, REA가 어떻게 도움이 되었는지, 무엇을 알아냈는지를 담아 공유하세요.
<a id="build-rl-environments"></a>
## RL 환경 만들기
원래 앱을 실행하지 않고도 AI 에이전트가 이슈 찾기나 폴더 만들기 같은 작업을 연습할 수 있는 로컬 환경을 만듭니다. 강화 학습(RL)이나 에이전트의 작업 수행 능력 평가에 사용할 수 있습니다.
REA는 기록한 API 요청과 응답을 에이전트가 호출할 수 있는 도구로 바꿉니다. 환경은 기록된 데이터를 사용하며, 기록에서 효과가 확인된 변경만 지원합니다.
에이전트에 REA를 설정한 뒤 아래 예시 URL과 폴더 작업을 자신의 환경에 맞게 바꾸세요.
```text
REA를 사용해 다음 테스트 웹 앱에서 RL 환경을 만들어 주세요.
http://127.0.0.1:3000
폴더 목록 조회, 생성, 이름 변경, 삭제를 포함해 주세요.
테스트 폴더를 만들고 삭제해도 됩니다. 기존 데이터는 변경하지 마세요.
my-env라는 폴더에 저장하고, 사용 가능한 작업을 확인한 뒤 실행 방법을 알려 주세요.
```
<details>
<summary>명령줄을 사용하는 경우</summary>
앱의 브라우저 요청과 응답을 기록한 파일이 이미 있으면 이 명령을 사용할 수 있습니다. 생성된 환경을 실행하려면 AgentEnv와 Docker도 필요합니다.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA는 실행 가능한 환경과 시작 및 응답 여부를 확인하는 기본 테스트를 내보냅니다. RL 프레임워크에 연결해 작업 목표와 보상 검사를 정의하고 학습을 실행할 수 있습니다.
[환경 만들기 가이드](https://rea.tools/guides/rl-environments/) ·
[환경 참조 문서](../agent-environments.md) ·
[X에서 데모 보기](https://x.com/reatools/status/2112574822584918075?s=20)
## 자주 묻는 질문
<details>
@@ -237,9 +280,9 @@ REA로 흥미로운 대상을 분석했다면 알려 주세요. [issue](https://
</details>
<details>
<summary><strong>Hopper, Ghidra 또는 IDA가 필요한가요?</strong></summary>
<summary><strong>Hopper, Ghidra, IDA 또는 Kuna가 필요한가요?</strong></summary>
심층 네이티브 분석에는 이 중 하나를 사용합니다. 정적 JavaScript 및 .NET 검사에는 네이티브 분석 엔진이 필요하지 않습니다. 설정 과정에서 승인 후 Hopper를 설치할 수 있으며, Ghidra와 IDA는 기존 설치를 사용합니다. [제공자 설정](../installation.md#hopper)을 참고하세요.
심층 네이티브 분석에는 이 중 하나를 사용합니다. 정적 JavaScript 및 .NET 검사에는 네이티브 분석 엔진이 필요하지 않습니다. 설정 과정에서 승인 후 Hopper를 설치할 수 있으며, Ghidra, IDA, Kuna는 기존 설치를 사용합니다. [제공자 설정](../installation.md#hopper)을 참고하세요.
</details>
@@ -307,7 +350,7 @@ npx rea-agents@latest setup
## 스타 기록
🎉 **GitHub 스타 300,000개, 감사합니다!**
🎉 **GitHub 스타 400,000개, 감사합니다!**
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
+49 -6
View File
@@ -20,7 +20,7 @@
**[വെബ്സൈറ്റ്](https://rea.tools/) · [ഗൈഡുകൾ](https://rea.tools/guides/) · [ഉദാഹരണങ്ങൾ](https://rea.tools/showcase/)**
[ദ്രുതാരംഭം](#ദ്രുതാരംഭം) · [REA എങ്ങനെ പ്രവർത്തിക്കുന്നു](#rea-എങ്ങനെ-പ്രവർത്തിക്കുന്നു) · [എന്തൊക്കെ വിശകലനം ചെയ്യാം](#എന്തൊക്കെ-വിശകലനം-ചെയ്യാം) · [ഉദാഹരണങ്ങൾ](#ഉദാഹരണങ്ങൾ) · [പതിവുചോദ്യങ്ങൾ](#പതിവുചോദ്യങ്ങൾ) · [ഡോക്യുമെന്റേഷൻ](#ഡോക്യുമെന്റേഷൻ)
[ദ്രുതാരംഭം](#ദ്രുതാരംഭം) · [REA എങ്ങനെ പ്രവർത്തിക്കുന്നു](#rea-എങ്ങനെ-പ്രവർത്തിക്കുന്നു) · [എന്തൊക്കെ വിശകലനം ചെയ്യാം](#എന്തൊക്കെ-വിശകലനം-ചെയ്യാം) · [ഉദാഹരണങ്ങൾ](#ഉദാഹരണങ്ങൾ) · [RL പരിതസ്ഥിതികൾ നിർമ്മിക്കുക](#build-rl-environments) · [പതിവുചോദ്യങ്ങൾ](#പതിവുചോദ്യങ്ങൾ) · [ഡോക്യുമെന്റേഷൻ](#ഡോക്യുമെന്റേഷൻ)
<code>npx rea-agents setup</code>
@@ -62,7 +62,7 @@
Native binaries, JavaScript, Electron apps, .NET assemblies, websites എന്നിവ പരിശോധിക്കുന്നതിനുള്ള tools-ലേക്ക് REA നിങ്ങളുടെ agent-നെ ബന്ധിപ്പിക്കുന്നു. ഇതേ tools നിങ്ങളുടെ terminal-ൽ നിന്നും ഉപയോഗിക്കാം. വിശകലനം local ആയി നടക്കുന്നു; ഓരോ നിഗമനത്തിനും പിന്നിലെ തെളിവുകളും പരിമിതികളും ഫലങ്ങളിൽ ഉൾപ്പെടുന്നു.
Setup നിങ്ങളുടെ agent-ിൽ REA രജിസ്റ്റർ ചെയ്യുകയും അനുയോജ്യമായ workflow നിർദ്ദേശങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്യുകയും ചെയ്യുന്നു. Native analysis-നായി നിലവിലുള്ള Hopper, Ghidra, അല്ലെങ്കിൽ IDA installation ഉപയോഗിക്കാം; അനുമതി നൽകിയാൽ setup-ന് Hopper ഇൻസ്റ്റാൾ ചെയ്യാനും കഴിയും. Static JavaScript analysis-ന് native analysis engine ആവശ്യമില്ല.
Setup നിങ്ങളുടെ agent-ിൽ REA രജിസ്റ്റർ ചെയ്യുകയും അനുയോജ്യമായ workflow നിർദ്ദേശങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്യുകയും ചെയ്യുന്നു. Native analysis-നായി നിലവിലുള്ള Hopper, Ghidra, IDA, അല്ലെങ്കിൽ Kuna installation ഉപയോഗിക്കാം; അനുമതി നൽകിയാൽ setup-ന് Hopper ഇൻസ്റ്റാൾ ചെയ്യാനും കഴിയും. Static JavaScript analysis-ന് native analysis engine ആവശ്യമില്ല.
> **[REA വെബ്സൈറ്റ് സന്ദർശിക്കുക](https://rea.tools/)** — setup നിർദ്ദേശങ്ങൾക്കും ചിത്രങ്ങളോടുകൂടിയ ഗൈഡുകൾക്കും യഥാർത്ഥ case study-കൾക്കും.
@@ -151,7 +151,7 @@ REA-യ്ക്ക് Node.js 22.x (>=22.23.4), 24.x (>=24.22.1), അല്ല
| Target | REA നൽകുന്ന ഫലങ്ങൾ | ആവശ്യകതകളും ഗൈഡും |
| ---------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Native binaries | Pseudocode, assembly, strings, symbols, calls, references | Hopper, Ghidra അല്ലെങ്കിൽ IDA; [native analysis](../native-investigation.md) |
| Native binaries | Pseudocode, assembly, strings, symbols, calls, references | Hopper, Ghidra, IDA അല്ലെങ്കിൽ Kuna; [native analysis](../native-investigation.md) |
| Offline ELF layout | Sections, segments, യഥാർത്ഥ symbols/relocations, static mitigation candidates | Linux x64-ൽ caller നൽകുന്ന pwntools; [binary diagnostics](../binary-diagnostics.md) |
| Go binaries | ഉൾച്ചേർത്ത compiler version, modules, replacements, build settings | Built-in static ELF/PE/thin Mach-O പരിശോധന; Go installation ആവശ്യമില്ല |
| Rust binaries | ഉൾച്ചേർത്ത cargo-auditable crate പേരുകൾ, versions, sources, dependency edges | Built-in static ELF/PE/thin Mach-O പരിശോധന; [Rust binaries](../rust-binaries.md) |
@@ -229,8 +229,51 @@ Renderer-ന്റെ clipboard API കണ്ടെത്തി, അതിനെ
[Case study വായിക്കുക](https://rea.tools/showcase/th04/) ·
[പുനർനിർമ്മാണ repository](https://github.com/N0zoM1z0/th04)
### REA ഉപയോഗിച്ച് RL പരിതസ്ഥിതികൾ നിർമ്മിക്കുക
വെബ് ആപ്പ് സെഷൻ റെക്കോർഡ് ചെയ്ത് API ടൂളുകളാക്കി AI ഏജന്റിന് ഉപയോഗിക്കാവുന്ന പരിതസ്ഥിതി എക്‌സ്‌പോർട്ട് ചെയ്യുക. AgentEnv ഉപയോഗിച്ച് പ്രവർത്തിപ്പിച്ച ശേഷം RL പരിശീലനത്തിനോ മൂല്യനിർണയത്തിനോ ടാസ്‌ക്കുകളും റിവാർഡ് പരിശോധനകളും ചേർക്കുക.
[പരിതസ്ഥിതി നിർമ്മാണ മാർഗ്ഗദർശി](https://rea.tools/guides/rl-environments/) ·
[X-ൽ ഡെമോ കാണുക](https://x.com/reatools/status/2112574822584918075?s=20)
REA ഉപയോഗിച്ച് നിങ്ങൾ രസകരമായ എന്തെങ്കിലും പരിശോധിച്ചിട്ടുണ്ടെങ്കിൽ അത് കാണാൻ ഞങ്ങൾ ആഗ്രഹിക്കുന്നു. പരിശോധിച്ച target, നിങ്ങളുടെ ചോദ്യം, REA എങ്ങനെ സഹായിച്ചു, നിങ്ങൾ കണ്ടെത്തിയത് എന്നിവ ഉൾപ്പെടുത്തി [issue](https://github.com/morluto/rea/issues) അല്ലെങ്കിൽ [pull request](https://github.com/morluto/rea/pulls) വഴി നിങ്ങളുടെ case പങ്കിടുക.
<a id="build-rl-environments"></a>
## RL പരിതസ്ഥിതികൾ നിർമ്മിക്കുക
യഥാർഥ ആപ്പ് പ്രവർത്തിപ്പിക്കാതെ issue കണ്ടെത്തൽ, ഫോൾഡർ സൃഷ്ടിക്കൽ തുടങ്ങിയ ജോലികൾ AI ഏജന്റിന് പരിശീലിക്കാൻ ഒരു പ്രാദേശിക പരിതസ്ഥിതി നിർമ്മിക്കുക. റീഇൻഫോഴ്‌സ്‌മെന്റ് ലേണിംഗിനോ (RL) ഏജന്റ് ജോലികൾ എത്ര നന്നായി പൂർത്തിയാക്കുന്നു എന്ന് പരിശോധിക്കാനോ ഇത് ഉപയോഗിക്കാം.
REA റെക്കോർഡ് ചെയ്ത API അഭ്യർത്ഥനകളും പ്രതികരണങ്ങളും ഏജന്റിന് വിളിക്കാവുന്ന ടൂളുകളാക്കുന്നു. പരിതസ്ഥിതി റെക്കോർഡ് ചെയ്ത ഡാറ്റ ഉപയോഗിക്കുന്നു. റെക്കോർഡ് ഫലം സ്ഥിരീകരിക്കുന്ന മാറ്റങ്ങൾ മാത്രമാണ് പിന്തുണയ്ക്കുന്നത്.
ഏജന്റിൽ REA സജ്ജീകരിച്ച ശേഷം ഉദാഹരണത്തിലെ URL-ഉം ഫോൾഡർ ജോലികളും നിങ്ങളുടെ ആപ്പിന് അനുസരിച്ച് മാറ്റുക:
```text
എന്റെ പരീക്ഷണ വെബ് ആപ്പിൽ നിന്ന് REA ഉപയോഗിച്ച് RL പരിതസ്ഥിതി നിർമ്മിക്കുക:
http://127.0.0.1:3000
ഫോൾഡറുകൾ പട്ടികപ്പെടുത്തൽ, സൃഷ്ടിക്കൽ, പേരുമാറ്റൽ, ഇല്ലാതാക്കൽ എന്നിവ ഉൾപ്പെടുത്തുക.
പരീക്ഷണ ഫോൾഡറുകൾ സൃഷ്ടിക്കാനും നീക്കാനും അനുമതിയുണ്ട്. നിലവിലുള്ള ഡാറ്റ മാറ്റരുത്.
my-env എന്ന ഫോൾഡറിൽ സംരക്ഷിച്ച് ഏതെല്ലാം പ്രവർത്തനങ്ങൾ ലഭ്യമാണെന്നും എങ്ങനെ പ്രവർത്തിപ്പിക്കണമെന്നും പറയുക.
```
<details>
<summary>കമാൻഡ് ലൈൻ ഉപയോഗിക്കുക</summary>
ബ്രൗസറിലെ ആപ്പിന്റെ അഭ്യർത്ഥനകളും പ്രതികരണങ്ങളും റെക്കോർഡ് ചെയ്ത ഫയൽ ഉണ്ടെങ്കിൽ ഈ കമാൻഡുകൾ ഉപയോഗിക്കാം. ഫലം പ്രവർത്തിപ്പിക്കാൻ AgentEnv-ഉം Docker-ഉം വേണം.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
പ്രവർത്തനം തുടങ്ങുന്നതും പ്രതികരിക്കുന്നതും പരിശോധിക്കുന്ന അടിസ്ഥാന ടെസ്റ്റിനൊപ്പം പ്രവർത്തിപ്പിക്കാവുന്ന പരിതസ്ഥിതി REA എക്‌സ്‌പോർട്ട് ചെയ്യുന്നു. ടാസ്‌ക് ലക്ഷ്യങ്ങളും റിവാർഡ് പരിശോധനകളും നിർവചിക്കാനും പരിശീലനം നടത്താനും RL ഫ്രെയിംവർക്കുമായി ബന്ധിപ്പിക്കുക.
[പരിതസ്ഥിതി നിർമ്മാണ മാർഗ്ഗദർശി](https://rea.tools/guides/rl-environments/) ·
[പരിതസ്ഥിതി റഫറൻസ്](../agent-environments.md) ·
[X-ൽ ഡെമോ കാണുക](https://x.com/reatools/status/2112574822584918075?s=20)
## പതിവുചോദ്യങ്ങൾ
<details>
@@ -241,9 +284,9 @@ Local MCP servers പിന്തുണയ്ക്കുന്ന ഏത് age
</details>
<details>
<summary><strong>Hopper, Ghidra അല്ലെങ്കിൽ IDA ആവശ്യമാണോ?</strong></summary>
<summary><strong>Hopper, Ghidra, IDA അല്ലെങ്കിൽ Kuna ആവശ്യമാണോ?</strong></summary>
ആഴത്തിലുള്ള native analysis-ന് ഇവയിൽ ഒന്ന് ആവശ്യമാണ്. Static JavaScript, .NET പരിശോധനകൾ native analysis engine ഇല്ലാതെയും പ്രവർത്തിക്കും. അനുമതി ലഭിച്ചാൽ setup-ന് Hopper ഇൻസ്റ്റാൾ ചെയ്യാം; Ghidra, IDA എന്നിവയ്ക്കായി നിങ്ങളുടെ നിലവിലുള്ള installations ഉപയോഗിക്കുന്നു. [Provider setup](../installation.md#hopper) കാണുക.
ആഴത്തിലുള്ള native analysis-ന് ഇവയിൽ ഒന്ന് ആവശ്യമാണ്. Static JavaScript, .NET പരിശോധനകൾ native analysis engine ഇല്ലാതെയും പ്രവർത്തിക്കും. അനുമതി ലഭിച്ചാൽ setup-ന് Hopper ഇൻസ്റ്റാൾ ചെയ്യാം; Ghidra, IDA, Kuna എന്നിവയ്ക്കായി നിങ്ങളുടെ നിലവിലുള്ള installations ഉപയോഗിക്കുന്നു. [Provider setup](../installation.md#hopper) കാണുക.
</details>
@@ -312,7 +355,7 @@ npx rea-agents@latest setup
## Star ചരിത്രം
🎉 **250,000 GitHub stars — നന്ദി!**
🎉 **400,000 GitHub stars — നന്ദി!**
REA ഉപയോഗിക്കുന്നവർക്കും, bugs റിപ്പോർട്ട് ചെയ്യുന്നവർക്കും, features ആവശ്യപ്പെടുന്നവർക്കും, builds പരിശോധിക്കുന്നവർക്കും, fixes സംഭാവന ചെയ്യുന്നവർക്കും നന്ദി.
+51 -6
View File
@@ -20,7 +20,7 @@
**[Strona internetowa](https://rea.tools/pl/) · [Przewodniki](https://rea.tools/pl/guides/) · [Przykłady zastosowań](https://rea.tools/pl/showcase/)**
[Szybki start](#szybki-start) · [Jak działa REA](#jak-działa-rea) · [Co możesz analizować](#co-możesz-analizować) · [Przykłady zastosowań](#przykłady-zastosowań) · [FAQ](#faq) · [Narzędzia GNU objdump i Rizin](../reverse-engineering-tools.md) · [Dokumentacja](#dokumentacja)
[Szybki start](#szybki-start) · [Jak działa REA](#jak-działa-rea) · [Co możesz analizować](#co-możesz-analizować) · [Przykłady zastosowań](#przykłady-zastosowań) · [Tworzenie środowisk RL](#build-rl-environments) · [FAQ](#faq) · [Dokumentacja](#dokumentacja)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@ Widzisz w aplikacji funkcję, którą chcesz mieć we własnym produkcie? Popro
REA łączy Twojego agenta z narzędziami do analizy natywnych plików binarnych, aplikacji JavaScript i Electron, zestawów .NET oraz stron internetowych. Z tych samych narzędzi możesz korzystać w terminalu. Analiza odbywa się lokalnie, a wyniki zawierają dowody i ograniczenia stojące za każdym wnioskiem.
Konfigurator rejestruje REA w Twoim agencie i instaluje pasujące instrukcje pracy. Analiza kodu natywnego może korzystać z istniejącej instalacji Hoppera lub Ghidry; konfigurator może też zainstalować Hoppera po uzyskaniu zgody. Statyczna analiza JavaScript nie wymaga żadnego z tych silników.
Konfigurator rejestruje REA w Twoim agencie i instaluje pasujące instrukcje pracy. Analiza kodu natywnego może korzystać z istniejącej instalacji Hoppera, Ghidry, IDA lub Kuna; konfigurator może też zainstalować Hoppera po uzyskaniu zgody. Statyczna analiza JavaScript nie wymaga żadnego z tych silników.
> **[Odwiedź stronę REA](https://rea.tools/pl/)**, aby znaleźć instrukcje konfiguracji, ilustrowane przewodniki i rzeczywiste studia przypadków.
@@ -151,7 +151,7 @@ REA wymaga Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) lub 26+ (>=26.12.1) oraz n
| Cel | Co zwraca REA | Wymagania i przewodnik |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| Natywne pliki binarne | Pseudokod, kod asemblera, ciągi znaków, symbole, wywołania i odwołania | Hopper, Ghidra lub IDA; [analiza kodu natywnego](../native-investigation.md) |
| Natywne pliki binarne | Pseudokod, kod asemblera, ciągi znaków, symbole, wywołania i odwołania | Hopper, Ghidra, IDA lub Kuna; [analiza kodu natywnego](../native-investigation.md) |
| Układ pliku ELF w trybie offline | Sekcje, segmenty, oryginalne symbole/relokacje i potencjalne mechanizmy zabezpieczeń wskazane przez analizę statyczną | pwntools dostarczone przez użytkownika w systemie Linux x64; [diagnostyka plików binarnych](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
@@ -190,6 +190,8 @@ REA wymaga Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) lub 26+ (>=26.12.1) oraz n
Statyczna analiza JavaScript i .NET odczytuje dostarczone pliki bez uruchamiania aplikacji. Przechwytywanie w czasie wykonywania uruchamia wybrany cel lub wchodzi z nim w interakcje z uprawnieniami Twojego użytkownika; skutki opisano w odpowiednich przewodnikach.
Do analizy offline natywnych plików binarnych REA obsługuje również GNU objdump i Rizin, które musisz dostarczyć samodzielnie. [Przewodnik po narzędziach inżynierii wstecznej](../reverse-engineering-tools.md) opisuje konfigurację dostawców, polecenia CLI i ograniczenia Evidence. REA nie instaluje ani nie aktualizuje żadnego z tych dostawców.
<a id="choosing-a-deep-analysis-provider"></a>
Dla dużych plików zwiększ czas uruchomienia przez `REA_GHIDRA_STARTUP_TIMEOUT_MS` lub `REA_HOPPER_STARTUP_TIMEOUT_MS`.
@@ -223,8 +225,51 @@ Sprawdź 16-bitowe instrukcje oryginalnej gry na PC-98, odtwórz obliczenia kąt
[Przeczytaj studium przypadku](https://rea.tools/pl/showcase/th04/) · [Repozytorium odtworzonej implementacji](https://github.com/N0zoM1z0/th04)
### Twórz środowiska RL z REA
Nagraj sesję aplikacji internetowej, zamień jej API w narzędzia i wyeksportuj środowisko dla agenta AI. Uruchom je za pomocą AgentEnv, a następnie dodaj zadania i sprawdzanie nagród do treningu RL lub oceny.
[Przewodnik tworzenia środowiska](https://rea.tools/guides/rl-environments/) ·
[Obejrzyj demo w X](https://x.com/reatools/status/2112574822584918075?s=20)
Jeśli użyłeś REA do czegoś ciekawego, chętnie to zobaczymy. Opisz swój przypadek w [zgłoszeniu](https://github.com/morluto/rea/issues) lub [pull requeście](https://github.com/morluto/rea/pulls), podając cel analizy, pytanie, sposób, w jaki REA pomogło, i swoje ustalenia.
<a id="build-rl-environments"></a>
## Tworzenie środowisk RL
Stwórz lokalne środowisko, w którym agent AI może ćwiczyć zadania, takie jak wyszukiwanie zgłoszenia lub tworzenie folderu, bez uruchamiania oryginalnej aplikacji. Użyj go do uczenia ze wzmocnieniem (RL) lub sprawdzania, jak agent wykonuje zadania.
REA zamienia nagrane żądania i odpowiedzi API w narzędzia, które agent może wywoływać. Środowisko używa nagranych danych i obsługuje zmiany tylko wtedy, gdy nagranie potwierdza ich efekty.
Skonfiguruj REA w agencie, a następnie zastąp przykładowy URL i zadania dotyczące folderów własnymi:
```text
Za pomocą REA zbuduj środowisko RL z mojej testowej aplikacji internetowej:
http://127.0.0.1:3000
Uwzględnij wyświetlanie listy folderów, tworzenie, zmianę nazwy i usuwanie.
Możesz tworzyć i usuwać foldery testowe. Nie zmieniaj istniejących danych.
Zapisz w folderze my-env, sprawdź dostępne operacje i powiedz mi, jak uruchomić środowisko.
```
<details>
<summary>Użyj wiersza poleceń</summary>
Użyj tych poleceń, jeśli masz już plik z nagranymi żądaniami i odpowiedziami aplikacji w przeglądarce. Do uruchomienia wyniku potrzebujesz też AgentEnv i Dockera.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA eksportuje gotowe do uruchomienia środowisko z podstawowym testem uruchamiania i odpowiedzi. Połącz je ze swoim frameworkiem RL, aby określić cele zadań, dodać sprawdzanie nagród i uruchomić trening.
[Przewodnik tworzenia środowiska](https://rea.tools/guides/rl-environments/) ·
[Dokumentacja środowisk](../agent-environments.md) ·
[Obejrzyj demo w X](https://x.com/reatools/status/2112574822584918075?s=20)
## FAQ
<details>
@@ -235,9 +280,9 @@ Każdy agent obsługujący lokalne serwery MCP. Konfigurator konfiguruje [obsłu
</details>
<details>
<summary><strong>Czy potrzebuję Hoppera, Ghidry lub IDA?</strong></summary>
<summary><strong>Czy potrzebuję Hoppera, Ghidry, IDA lub Kuna?</strong></summary>
Dogłębna analiza kodu natywnego używa jednego z nich. Statyczna analiza JavaScript i .NET działa bez silnika analizy natywnej. Konfigurator może zainstalować Hoppera po uzyskaniu zgody; Ghidra i IDA korzystają z istniejących instalacji. Zobacz [konfigurację dostawców analizy](../installation.md#hopper).
Dogłębna analiza kodu natywnego używa jednego z nich. Statyczna analiza JavaScript i .NET działa bez silnika analizy natywnej. Konfigurator może zainstalować Hoppera po uzyskaniu zgody; Ghidra, IDA i Kuna korzystają z istniejących instalacji. Zobacz [konfigurację dostawców analizy](../installation.md#hopper).
</details>
@@ -305,7 +350,7 @@ Zgłaszaj podatności zgodnie z [SECURITY.md](../../SECURITY.md).
## Historia gwiazdek
🎉 **300 000 gwiazdek na GitHubie — dziękujemy!**
🎉 **400 000 gwiazdek na GitHubie — dziękujemy!**
Dziękujemy wszystkim, którzy używają REA, zgłaszają błędy, proponują nowe funkcje, testują kompilacje i przesyłają poprawki.
+51 -6
View File
@@ -20,7 +20,7 @@
**[Site](https://rea.tools/pt-BR/) · [Guias](https://rea.tools/pt-BR/guides/) · [Casos de uso](https://rea.tools/pt-BR/showcase/)**
[Início rápido](#início-rápido) · [Como o REA funciona](#como-o-rea-funciona) · [O que você pode analisar](#o-que-você-pode-analisar) · [Casos de uso](#casos-de-uso) · [Perguntas frequentes](#perguntas-frequentes) · [Ferramentas GNU objdump e Rizin](../reverse-engineering-tools.md) · [Documentação](#documentação)
[Início rápido](#início-rápido) · [Como o REA funciona](#como-o-rea-funciona) · [O que você pode analisar](#o-que-você-pode-analisar) · [Casos de uso](#casos-de-uso) · [Criar ambientes de RL](#build-rl-environments) · [Perguntas frequentes](#perguntas-frequentes) · [Documentação](#documentação)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@ Viu uma funcionalidade em um aplicativo que gostaria de ter no seu próprio prod
O REA conecta seu agente a ferramentas para inspecionar binários nativos, aplicativos JavaScript e Electron, assemblies .NET e sites. Você também pode usar as mesmas ferramentas pelo terminal. A análise acontece localmente, e os resultados incluem as evidências e limitações por trás de cada conclusão.
A configuração registra o REA no seu agente e instala as instruções de trabalho correspondentes. A análise nativa pode usar Hopper, Ghidra ou IDA já instalados; o Hopper pode ser instalado após sua aprovação. A análise estática de JavaScript não precisa de um mecanismo de análise nativa.
A configuração registra o REA no seu agente e instala as instruções de trabalho correspondentes. A análise nativa pode usar Hopper, Ghidra, IDA ou Kuna já instalados; o Hopper pode ser instalado após sua aprovação. A análise estática de JavaScript não precisa de um mecanismo de análise nativa.
> **[Visite o site do REA](https://rea.tools/pt-BR/)** para instruções de configuração, guias ilustrados e estudos de caso reais.
@@ -151,7 +151,7 @@ O REA requer Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), alé
| Alvo | O que o REA retorna | Requisitos e guia |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Binários nativos | Pseudocódigo, assembly, strings, símbolos, chamadas e referências | Hopper, Ghidra ou IDA; [análise nativa](../native-investigation.md) |
| Binários nativos | Pseudocódigo, assembly, strings, símbolos, chamadas e referências | Hopper, Ghidra, IDA ou Kuna; [análise nativa](../native-investigation.md) |
| Estrutura ELF sem execução | Seções, segmentos, símbolos/relocações originais e possíveis mecanismos de mitigação identificados por análise estática | pwntools fornecido pelo chamador no Linux x64; [diagnóstico de binários](../binary-diagnostics.md) |
| PE certificates | Authenticode WIN_CERTIFICATE entries and PKCS#7 signer/X.509 identity fields | Built-in static PE inspection; [PE certificates](../pe-certificates.md) |
| PE imports | Import and delay-load DLL names, ordinals, IAT RVAs and pefile import hash | Built-in static PE inspection; [PE imports](../pe-imports.md) |
@@ -190,6 +190,8 @@ O REA requer Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) ou 26+ (>=26.12.1), alé
A inspeção estática de JavaScript e .NET lê os arquivos fornecidos sem executar o aplicativo. A captura em execução inicia o alvo selecionado ou interage com ele usando as permissões do seu usuário; cada guia descreve seus efeitos.
Para inspecionar binários nativos offline, o REA também oferece suporte ao GNU objdump e ao Rizin, que você deve fornecer por conta própria. O [guia de ferramentas de engenharia reversa](../reverse-engineering-tools.md) descreve a configuração dos provedores, os comandos da CLI e as limitações de Evidence. O REA não instala nem atualiza nenhum desses provedores.
<a id="choosing-a-deep-analysis-provider"></a>
Para binários grandes, aumente o prazo de inicialização com `REA_GHIDRA_STARTUP_TIMEOUT_MS` ou `REA_HOPPER_STARTUP_TIMEOUT_MS`.
@@ -223,8 +225,51 @@ Inspecione as instruções de 16 bits do jogo original para PC-98, recupere os c
[Leia o estudo de caso](https://rea.tools/pt-BR/showcase/th04/) · [Repositório da reconstrução](https://github.com/N0zoM1z0/th04)
### Criar ambientes de RL com o REA
Grave uma sessão de aplicativo web, transforme sua API em ferramentas e exporte um ambiente que um agente de IA possa usar. Execute com o AgentEnv e adicione tarefas e verificações de recompensa para treinamento RL ou avaliação.
[Guia para criar um ambiente](https://rea.tools/guides/rl-environments/) ·
[Veja a demonstração no X](https://x.com/reatools/status/2112574822584918075?s=20)
Se você usou o REA em algo interessante, gostaríamos de conhecer. Compartilhe seu caso em uma [issue](https://github.com/morluto/rea/issues) ou um [pull request](https://github.com/morluto/rea/pulls), incluindo o alvo, sua pergunta, como o REA ajudou e o que descobriu.
<a id="build-rl-environments"></a>
## Criar ambientes de RL
Crie um ambiente local onde um agente de IA possa praticar tarefas como encontrar uma issue ou criar uma pasta, sem executar o aplicativo original. Use para aprendizado por reforço (RL) ou para testar como o agente conclui tarefas.
O REA transforma requisições e respostas de API gravadas em ferramentas que o agente pode chamar. O ambiente usa os dados gravados e só aceita alterações cujos efeitos sejam confirmados pela gravação.
Configure o REA no agente e substitua a URL e as tarefas de pastas do exemplo pelas suas:
```text
Use o REA para criar um ambiente de RL a partir do meu aplicativo web de teste em
http://127.0.0.1:3000.
Inclua listar, criar, renomear e excluir pastas. Pode criar e remover
pastas de teste, mas não altere os dados existentes.
Salve em uma pasta chamada my-env, verifique quais operações funcionam e diga como executar.
```
<details>
<summary>Usar a linha de comando</summary>
Use estes comandos se já tiver um arquivo com as requisições e respostas do aplicativo gravadas no navegador. Para executar o resultado, você também precisa do AgentEnv e do Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
O REA exporta um ambiente executável com um teste básico para verificar se ele inicia e responde. Use com seu framework de RL para definir objetivos, adicionar verificações de recompensa e executar o treinamento.
[Guia para criar um ambiente](https://rea.tools/guides/rl-environments/) ·
[Referência de ambientes](../agent-environments.md) ·
[Veja a demonstração no X](https://x.com/reatools/status/2112574822584918075?s=20)
## Perguntas frequentes
<details>
@@ -235,9 +280,9 @@ Qualquer agente que ofereça suporte a servidores MCP locais. A configuração p
</details>
<details>
<summary><strong>Preciso do Hopper, Ghidra ou IDA?</strong></summary>
<summary><strong>Preciso do Hopper, Ghidra, IDA ou Kuna?</strong></summary>
A análise nativa aprofundada usa um desses motores. A inspeção estática de JavaScript e .NET funciona sem um motor de análise nativa. A configuração pode instalar o Hopper após aprovação; Ghidra e IDA usam as instalações existentes. Consulte [configuração dos provedores](../installation.md#hopper).
A análise nativa aprofundada usa um desses motores. A inspeção estática de JavaScript e .NET funciona sem um motor de análise nativa. A configuração pode instalar o Hopper após aprovação; Ghidra, IDA e Kuna usam as instalações existentes. Consulte [configuração dos provedores](../installation.md#hopper).
</details>
@@ -305,7 +350,7 @@ Relate vulnerabilidades conforme [SECURITY.md](../../SECURITY.md).
## Histórico de estrelas
🎉 **300.000 estrelas no GitHub — muito obrigado!**
🎉 **400.000 estrelas no GitHub — muito obrigado!**
Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam builds e contribuem com correções.
+49 -6
View File
@@ -20,7 +20,7 @@
**[Site web](https://rea.tools/) · [Ghiduri](https://rea.tools/guides/) · [Studii de caz](https://rea.tools/showcase/)**
[Pornire rapidă](#pornire-rapidă) · [Cum funcționează REA](#cum-funcționează-rea) · [Ce poți analiza](#ce-poți-analiza) · [Studii de caz](#studii-de-caz) · [Întrebări frecvente](#întrebări-frecvente) · [Documentație](#documentație)
[Pornire rapidă](#pornire-rapidă) · [Cum funcționează REA](#cum-funcționează-rea) · [Ce poți analiza](#ce-poți-analiza) · [Studii de caz](#studii-de-caz) · [Construiește medii RL](#build-rl-environments) · [Întrebări frecvente](#întrebări-frecvente) · [Documentație](#documentație)
<code>npx rea-agents setup</code>
@@ -62,7 +62,7 @@ Ai văzut într-o aplicație o funcționalitate pe care ai vrea să o incluzi î
REA conectează agentul tău la unelte pentru inspectarea fișierelor binare native, a aplicațiilor JavaScript și Electron, a ansamblurilor .NET și a site-urilor web. Poți folosi aceleași unelte și din terminal. Analiza rulează local, iar rezultatele includ dovezile și limitările care stau la baza fiecărei concluzii.
Programul de configurare înregistrează REA în agentul tău și instalează instrucțiunile corespunzătoare pentru fluxul de lucru. Analiza nativă poate folosi o instalare existentă de Hopper, Ghidra sau IDA; programul de configurare poate instala opțional Hopper, cu aprobarea ta. Analiza statică JavaScript nu necesită un motor de analiză nativă.
Programul de configurare înregistrează REA în agentul tău și instalează instrucțiunile corespunzătoare pentru fluxul de lucru. Analiza nativă poate folosi o instalare existentă de Hopper, Ghidra, IDA sau Kuna; programul de configurare poate instala opțional Hopper, cu aprobarea ta. Analiza statică JavaScript nu necesită un motor de analiză nativă.
> **[Vizitează site-ul REA](https://rea.tools/)** pentru instrucțiuni de configurare, ghiduri ilustrate și studii de caz reale.
@@ -187,7 +187,7 @@ Uneltele suplimentare și platformele acceptate depind de ținta analizată:
| Țintă | Ce returnează REA | Cerințe și ghid |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Aplicații desktop instalate | Componente de execuție candidate, fișiere auxiliare, indicii despre componente și următoarele verificări | Inspectare integrată a directoarelor și antetelor, cu limite de resurse; [aplicații desktop](../desktop-applications.md) |
| Fișiere binare native | Pseudocod, cod de asamblare, șiruri de caractere, simboluri, apeluri și referințe | Hopper, Ghidra sau IDA; [analiză nativă](../native-investigation.md) |
| Fișiere binare native | Pseudocod, cod de asamblare, șiruri de caractere, simboluri, apeluri și referințe | Hopper, Ghidra, IDA sau Kuna; [analiză nativă](../native-investigation.md) |
| Structura ELF, offline | Secțiuni, segmente, simboluri și relocări originale, precum și indicii statice despre mecanismele de protecție | pwntools furnizat de utilizator, pe Linux x64; [diagnosticarea binarelor](../binary-diagnostics.md) |
| Fișiere binare Go | Versiunea compilatorului încorporată în fișier, modulele, înlocuirile și setările de compilare | Inspectare statică integrată a fișierelor ELF/PE/Mach-O cu o singură arhitectură; nu necesită instalarea Go |
| Obiecte de cod GPU | Ținte CUDA/HIP, parametri și resurse selectate ale kernelurilor GPU, textul PTX păstrat | Inspectare statică integrată a fișierelor ELF/PE/fatbin/CUBIN/PTX; [obiecte de cod GPU](../gpu-code-objects.md) |
@@ -282,11 +282,54 @@ compară codul C++ reconstruit cu rezultatul compilatorului folosit la acea vrem
[Citește studiul de caz](https://rea.tools/showcase/th04/) ·
[Repository-ul reconstrucției](https://github.com/N0zoM1z0/th04)
### Construiește medii RL cu REA
Înregistrează o sesiune de aplicație web, transformă API-ul în instrumente și exportă un mediu pe care un agent AI îl poate folosi. Rulează cu AgentEnv, apoi adaugă sarcini și verificări de recompensă pentru antrenare RL sau evaluare.
[Ghid pentru construirea unui mediu](https://rea.tools/guides/rl-environments/) ·
[Vezi demonstrația pe X](https://x.com/reatools/status/2112574822584918075?s=20)
Dacă ai folosit REA pentru ceva interesant, ne-ar plăcea să vedem rezultatul.
Prezintă cazul într-un [issue](https://github.com/morluto/rea/issues) sau într-un
[pull request](https://github.com/morluto/rea/pulls), menționând ținta analizată,
întrebarea ta, cum te-a ajutat REA și ce ai descoperit.
<a id="build-rl-environments"></a>
## Construiește medii RL
Creează un mediu local în care un agent AI să exerseze sarcini precum găsirea unui issue sau crearea unui dosar, fără a rula aplicația originală. Folosește-l pentru învățare prin recompensă (RL) sau pentru a testa cât de bine îndeplinește agentul sarcinile.
REA transformă cererile și răspunsurile API înregistrate în instrumente pe care agentul le poate apela. Mediul folosește datele înregistrate și permite modificări doar când înregistrarea le confirmă efectele.
După ce configurezi REA în agent, înlocuiește URL-ul și sarcinile pentru dosare din exemplu cu ale tale:
```text
Folosește REA pentru a crea un mediu RL din aplicația mea web de test de la
http://127.0.0.1:3000.
Include listarea, crearea, redenumirea și ștergerea dosarelor. Poți crea și elimina
dosare de test, dar nu modifica datele existente.
Salvează într-un dosar numit my-env, verifică operațiile disponibile și spune-mi cum îl rulez.
```
<details>
<summary>Folosește linia de comandă</summary>
Folosește aceste comenzi dacă ai deja un fișier cu cererile și răspunsurile aplicației înregistrate în browser. Pentru a rula rezultatul ai nevoie și de AgentEnv și Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA exportă un mediu executabil cu un test de bază care verifică pornirea și răspunsurile. Conectează-l la frameworkul RL pentru a defini obiectivele, a adăuga verificări de recompensă și a rula antrenarea.
[Ghid pentru construirea unui mediu](https://rea.tools/guides/rl-environments/) ·
[Referință pentru medii](../agent-environments.md) ·
[Vezi demonstrația pe X](https://x.com/reatools/status/2112574822584918075?s=20)
## Întrebări frecvente
<details>
@@ -299,11 +342,11 @@ poți folosi [înregistrarea manuală MCP](../installation.md#mcp-registry).
</details>
<details>
<summary><strong>Am nevoie de Hopper, Ghidra sau IDA?</strong></summary>
<summary><strong>Am nevoie de Hopper, Ghidra, IDA sau Kuna?</strong></summary>
Analiza nativă aprofundată folosește unul dintre aceste instrumente. Inspectarea
statică JavaScript și .NET funcționează fără un motor de analiză nativă.
Programul de configurare poate instala Hopper după aprobare; pentru Ghidra și IDA
Programul de configurare poate instala Hopper după aprobare; pentru Ghidra, IDA și Kuna
folosește instalările existente. Consultă [configurarea motoarelor de analiză](../installation.md#hopper).
</details>
@@ -386,7 +429,7 @@ Raportează vulnerabilitățile conform [SECURITY.md](../../SECURITY.md).
## Istoricul stelelor
🎉 **300.000 de stele pe GitHub — vă mulțumim!**
🎉 **400.000 de stele pe GitHub — vă mulțumim!**
Mulțumim tuturor celor care folosesc REA, raportează erori, propun funcționalități,
testează versiuni și contribuie cu remedieri.
+51 -6
View File
@@ -20,7 +20,7 @@
**[Сайт](https://rea.tools/ru/) · [Руководства](https://rea.tools/ru/guides/) · [Примеры](https://rea.tools/ru/showcase/)**
[Быстрый старт](#быстрый-старт) · [Как работает REA](#как-работает-rea) · [Что можно анализировать](#что-можно-анализировать) · [Примеры](#примеры) · [Частые вопросы](#частые-вопросы) · [Инструменты GNU objdump и Rizin](../reverse-engineering-tools.md) · [Документация](#документация)
[Быстрый старт](#быстрый-старт) · [Как работает REA](#как-работает-rea) · [Что можно анализировать](#что-можно-анализировать) · [Примеры](#примеры) · [Создание RL-окружений](#build-rl-environments) · [Частые вопросы](#частые-вопросы) · [Документация](#документация)
<code>npx rea-agents setup</code>
@@ -60,7 +60,7 @@
REA подключает вашего агента к инструментам для исследования нативных бинарных файлов, приложений JavaScript и Electron, сборок .NET и сайтов. Те же инструменты доступны в терминале. Анализ выполняется локально, а результаты содержат данные и ограничения, на которых основан каждый вывод.
Настройка регистрирует REA у агента и устанавливает соответствующие инструкции. Нативный анализ использует установленный Hopper, Ghidra или IDA; Hopper можно установить после одобрения. Статическому анализу JavaScript нативный движок не нужен.
Настройка регистрирует REA у агента и устанавливает соответствующие инструкции. Нативный анализ использует установленный Hopper, Ghidra, IDA или Kuna; Hopper можно установить после одобрения. Статическому анализу JavaScript нативный движок не нужен.
> **[Посетите сайт REA](https://rea.tools/ru/)**: там есть инструкции по настройке, иллюстрированные руководства и реальные исследования.
@@ -151,7 +151,7 @@ REA требует Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) или 26+ (>=26.1
| Цель | Что возвращает REA | Требования и руководство |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra или IDA; [нативный анализ](../native-investigation.md) |
| Нативные бинарные файлы | Псевдокод, ассемблер, строки, символы, вызовы и ссылки | Hopper, Ghidra, IDA или Kuna; [нативный анализ](../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) |
@@ -190,6 +190,8 @@ REA требует Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) или 26+ (>=26.1
Статическое исследование JavaScript и .NET читает предоставленные файлы, не запуская приложение. Захват во время выполнения запускает выбранную цель или взаимодействует с ней с правами вашего пользователя; соответствующие руководства описывают последствия.
Для автономного анализа нативных бинарных файлов REA также поддерживает GNU objdump и Rizin, которые пользователь предоставляет самостоятельно. В [руководстве по инструментам обратной разработки](../reverse-engineering-tools.md) описаны настройка провайдеров, команды CLI и ограничения Evidence. REA не устанавливает и не обновляет ни один из этих провайдеров.
<a id="choosing-a-deep-analysis-provider"></a>
Для больших файлов увеличьте срок запуска через `REA_GHIDRA_STARTUP_TIMEOUT_MS` или `REA_HOPPER_STARTUP_TIMEOUT_MS`.
@@ -223,8 +225,51 @@ REA требует Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) или 26+ (>=26.1
[Прочитать исследование](https://rea.tools/ru/showcase/th04/) · [Репозиторий реконструкции](https://github.com/N0zoM1z0/th04)
### Создавайте RL-окружения с REA
Запишите сеанс веб-приложения, превратите его API в инструменты и экспортируйте окружение для ИИ-агента. Запустите его с AgentEnv, затем добавьте задания и проверки наград для RL-обучения или оценки.
[Руководство по созданию окружения](https://rea.tools/guides/rl-environments/) ·
[Смотреть демо в X](https://x.com/reatools/status/2112574822584918075?s=20)
Если вы исследовали с REA что-то интересное, поделитесь результатом. Создайте [issue](https://github.com/morluto/rea/issues) или [pull request](https://github.com/morluto/rea/pulls) и укажите цель, ваш вопрос, как помог REA и что удалось узнать.
<a id="build-rl-environments"></a>
## Создание RL-окружений
Создайте локальное окружение, где ИИ-агент сможет выполнять пробные задания, например искать задачу в трекере или создавать папку, без запуска исходного приложения. Используйте его для обучения с подкреплением (RL) или проверки того, как агент справляется с заданиями.
REA превращает записанные API-запросы и ответы в инструменты, которые может вызывать агент. Окружение использует записанные данные и поддерживает изменения только тогда, когда запись подтверждает их эффект.
Настройте REA в своём агенте, затем замените пример URL и операции с папками на свои:
```text
С помощью REA создай RL-окружение из моего тестового веб-приложения:
http://127.0.0.1:3000
Включи просмотр списка папок, создание, переименование и удаление.
Можно создавать и удалять тестовые папки. Существующие данные не меняй.
Сохрани в папку my-env, проверь доступные операции и расскажи, как запустить окружение.
```
<details>
<summary>Использовать командную строку</summary>
Эти команды подходят, если у вас уже есть файл с записанными запросами и ответами приложения в браузере. Для запуска результата также нужны AgentEnv и Docker.
```sh
rea environment-build ./session.har ./my-env --name my-env --json
agent-env run ./my-env
```
</details>
REA экспортирует готовое к запуску окружение с базовым тестом запуска и ответов. Подключите его к своему RL-фреймворку, чтобы задать цели, добавить проверки наград и запустить обучение.
[Руководство по созданию окружения](https://rea.tools/guides/rl-environments/) ·
[Справочник окружений](../agent-environments.md) ·
[Смотреть демо в X](https://x.com/reatools/status/2112574822584918075?s=20)
## Частые вопросы
<details>
@@ -235,9 +280,9 @@ REA требует Node.js 22.x (>=22.23.4), 24.x (>=24.22.1) или 26+ (>=26.1
</details>
<details>
<summary><strong>Нужны ли мне Hopper, Ghidra или IDA?</strong></summary>
<summary><strong>Нужны ли мне Hopper, Ghidra, IDA или Kuna?</strong></summary>
Углублённый нативный анализ использует один из этих инструментов. Статическое исследование JavaScript и .NET работает без движка нативного анализа. Настройка может установить Hopper после подтверждения; Ghidra и IDA используют существующие установки. См. [настройку провайдеров](../installation.md#hopper).
Углублённый нативный анализ использует один из этих инструментов. Статическое исследование JavaScript и .NET работает без движка нативного анализа. Настройка может установить Hopper после подтверждения; Ghidra, IDA и Kuna используют существующие установки. См. [настройку провайдеров](../installation.md#hopper).
</details>
@@ -305,7 +350,7 @@ npx rea-agents@latest setup
## История звёзд
🎉 **300 000 звёзд на GitHub — спасибо!**
🎉 **400 000 звёзд на GitHub — спасибо!**
Спасибо всем, кто использует REA, сообщает об ошибках, предлагает новые функции, тестирует сборки и помогает с исправлениями.
Loaded 100 of 3243 files, more files were not shown because too many files have changed in this diff. Show more