Compare commits

..
Author SHA1 Message Date
github-actions[bot]andmorluto 27dc42d102 chore(release/6.7.0): release rea-agents 6.7.0 (#4983)
* chore(release/6.7.0): release rea-agents 6.7.0

* docs(release): finalize frozen 6.7.0 contribution notes

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-18 15:40:45 +08:00
Kaoru0822andClaude Opus 5.5 b83b9caf4a fix(setup): edit the duplicate JSON member that clients read (#4957)
JSON.parse, JSONC parse, and native Claude Code keep the last duplicate
object member, and parseClientConfiguration therefore validates the last
one. The shared setup/uninstall serializer instead edited text through
jsonc-parser's modify and findNodeAtLocation, which select the first
matching member, so setup and uninstall on configurations with repeated
server tables or rea members wrote into a shadowed member and failed
readback.

Locate every JSON text edit by the effective (last) member in one place,
replacing the first-member modify path. Removing an effective member
that shadows an earlier duplicate would activate that duplicate, whatever
its ownership, so the serializer now returns a tagged shadowed_member
failure and setup and uninstall refuse before writing a backup or the
configuration.

Fixes #4952

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 22:15:47 -07:00
morluto bb212ffecb fix(tests): inherit server identity deadline policy
Remove per-case ten-second overrides from MCP catalog and identity checks. Keep the suite-owned bounded ordinary and coverage deadlines, all assertions, and session cleanup.

Fixes #4967
2026-10-18 13:01:44 +08:00
morluto 6b180783ed fix(tests): budget CLI coverage from parsed options
Use the pinned Vitest parser for coverage and shard flags. Keep ordinary CLI workers at 384 MiB and covered workers at the tested 512 MiB with unchanged concurrency. Retain complete coverage and add actual-config regressions for false, provider-only and spaced-shard options.

Validation: 27 focused cases; 16 covered cases with CLI preloaded; 5 docs checks; typecheck/lint; exact discovery of 1578 files. Measured covered control: 22.18s elapsed, 46.52s CPU, about 2.33 GiB sampled summed process-family RSS on macOS arm64. Full Linux CI pending. No runtime/device verification claimed.

Fixes #4960
2026-10-18 12:43:17 +08:00
morluto 8cbaf6c702 fix(tests): isolate command finalization module mocks
Move the five registered WASM finalization cases into the existing per-file isolated project. Preserve all result, exit-code, observation and cleanup assertions. A preloaded shared CLI graph reproduces three failures before the move; the isolated covered packet passes.

Fixes #4959
2026-10-18 12:42:26 +08:00
github-actions[bot]andmorluto 2c4338db1f chore(main): release rea-agents 6.6.0 (#3476)
* chore(main): release rea-agents 6.6.0

* docs(release): finalize 6.6.0 notes and contribution record

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-18 11:39:53 +08:00
Kaoru0822andClaude Opus 5.5 18aa9af2b2 fix(setup): admit only strict JSON for Claude Code configuration (#4944)
Claude Code shared the generic `json` client format, which the shared
configuration reader admits through JSONC parsing with comments and
trailing commas enabled. Native Claude Code reads `.claude.json` with a
strict JSON parser (after a UTF-8 BOM), so setup reported `ready`, wrote
a registration into a file the client rejects as corrupt, and doctor
reported it `aligned`.

Give Claude Code its own `claude_code` configuration format and parse it
at the owning boundary with strict JSON.parse after removing a leading
BOM. Setup, doctor, and uninstall all consume that parser, so comment or
trailing-comma documents are now refused as malformed before any backup
or write, while plain and BOM-prefixed JSON still configure. Clients that
natively accept JSONC keep the `json` format and its behavior.

Fixes #4940

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:57:28 -07:00
morluto 1f23e977b5 fix(pwntools): retain exact cleanup owners through finalization
Give retained processes and runtime roots separate cleanup leases. Bind
composed failures to their exact dependencies so process retirement removes
only process labels and root deletion resolves the remaining markers.
Retain local evidence while descriptor cleanup is unresolved.

Preserve completed decoded facts and the original cancellation reason when
final cleanup itself fails, then expose that primary after successful retry.
Remove the superseded root-error composition branch after descriptor gating.

Validation: 68 focused tests across nine files, including real retained file
handles, late process handshakes, failed final cleanup, mixed child outcomes
and cleanup retry. Static, docs (five checks) and discovery (1577 files) pass.
The producer qualification scope is controlled Node/file fixtures with the
real macOS inspector and a simulated availability gate, not native pwntools
or GDB. Task tokens/CPU/process-family memory are unmeasured; no speed claim.

Fixes #4945
2026-10-18 10:51:51 +08:00
morluto 08fbeb8bda fix(pwntools): preserve producer cancellation outcomes
Keep opaque reasons at admission, queued work, command/file projection and
successful final cleanup. Normalize Node's ABORT_ERR envelope only at the
snapshot write API that produced it, using the verified original cause.
Remove downstream signal/name/identity guesses in decoder and debugger
catches, including reply-close and path-probe handling.

The initial regressions failed 15 cases with seven controls passing.
The complete final series passes 68 focused tests, static checks, docs and
discovery. Real owned Node/file fixtures use the actual macOS inspector;
only the Linux x64 availability gate is simulated. No native pwntools or
GDB qualification or performance improvement is claimed.

Refs #4945
2026-10-18 10:51:50 +08:00
47d3c6b1a1 test(perf): verify authentic retained investigation queries (#4814)
Verify retained queries against authentic SQLite ELF and npm histories, retain failed RPC/cleanup/output costs, and make mixed-history verification repeatable. Record the separate validation-reuse bottleneck in #4810.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-18 02:32:58 +00:00
morluto b33c0df02e fix(pwndbg): reject core mapping paths that escape sysroot
Interpret source-bound ELF64 NT_FILE descriptors once before debugger
launch. Bound counts and pathname coverage by the descriptor, retain exact
path bytes, and refuse relative names or dot segments rather than letting
GDB resolve them against the host. Pin GDB's pathname semantics to Unix.

Preserve the decoded partial observation on refusal, basic-only recovery,
and pre-admission cancellation. Share an exact mapping fixture and replace
the old fixture boolean modes with explicit report producers.

Validation: final series has 33 passing Vitest cases plus five Python
producer controls; 38 Linux x64 provider cases are explicitly skipped on
macOS. Typecheck/lint, docs checks and test discovery pass. Real GDB16.3
and strace reproduce the relative-path escape using only an owned fixture;
compiled admission admits a real absolute-path core and refuses that
relative-path core. Full native pwndbg / Linux x64 remain unverified here.
Task token, CPU and peak-family-memory costs are unmeasured; no speed claim.

Fixes #4942
2026-10-18 10:27:37 +08:00
morluto 5bf4fffc1b fix(pwndbg): prevent core-triggered executable discovery
Occupy GDB's executable slot with its owned /proc/self/exe while loading a
core, then discard it before mapping queries. Select the validated decoder
architecture explicitly and restrict build-ID lookup to the owned empty path.
Preserve cancellation reasons at debugger admission.

Keep the original fixture executable present during syscall verification and
add Debian 13 / GDB 16 coverage alongside Ubuntu 24.04 in the CI definition.

Validation: controlled producer regressions and request-profile controls;
real GDB 16.3 / strace on Linux arm64 shows the old bridge opening the
recorded executable and the fix returning the same mapping without that
access. A cross-architecture gdb-multiarch probe confirms profile selection.
The plugin was controlled; full native pwndbg and Linux x64 remain unverified.
No performance improvement claimed; task tokens/CPU/family memory unmeasured.

Fixes #4914
2026-10-18 10:26:42 +08:00
morlutoandLuigi Pinna 847472acf5 fix(gdb): report close disposition as a capability precondition
Adapt #4732 using canonical provider identity and explicit producer recovery. Keep the valid session retained for caller-selected disposition and preserve default capability error behavior. Refs #4653.

Co-authored-by: Luigi Pinna <luigipinna3@gmail.com>
2026-10-18 10:03:39 +08:00
Kaoru0822andClaude Opus 5.5 270bc38f72 fix(setup): read signed 64-bit TOML integers losslessly (#4937)
Codex and Grok client TOML was parsed with smol-toml's default reader,
which rejects any integer beyond JavaScript's safe Number range. Valid
TOML 1.0 Int64 values such as `max_bytes = 9223372036854775807` made
setup, doctor and uninstall treat the whole file as malformed.

The client TOML owner now parses with `integersAsBigInt: "asNeeded"`,
keeping safe integers as numbers and larger ones exact as bigint, and
rejects values outside signed Int64 before any write. All TOML parses in
the document owner (document read, inline string decoding and the
preserving-edit check) use that reader. The inline-table writer emits
bigint values, and setup and doctor accept a positive bigint
`startup_timeout_sec`/`tool_timeout_sec` instead of replacing or
rejecting it.

Fixes #4917

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:02:26 -07:00
morlutoandXander-AJ d5fc7e6ebf fix(rizin): preserve output whitespace before completion markers
Adapt #4044 at the shared normal/interrupted frame owner. Preserve the decoded prefix before byte-budget accounting and cover MCP delivery across framing and UTF-8 boundaries. Refs #4016.

Co-authored-by: Xander-AJ <133286098+Xander-AJ@users.noreply.github.com>
2026-10-18 09:53:59 +08:00
morlutoandTapraj-Pathak 279c590ef6 fix(cli): require cancellation through command finalization
Adapt the forwarding proposal in #4652 with a required signal before optional resource diagnostics. Migrate all callers and cover actual command registration during final close. Refs #4939.

Co-authored-by: Tapraj-Pathak <165466587+Tapraj-Pathak@users.noreply.github.com>
2026-10-18 09:48:11 +08:00
morluto 2ae4e1608f fix(cli): preserve omitted positions in filtered JSON arrays
Normalize only filter-owned selections before streamed JSON and JSONL output, and count the same normalized payload. Keep source values and strict domain JSON validation intact. Refs #4938.
2026-10-18 09:40:02 +08:00
morluto ba98130049 fix(mcp): distinguish schema references from literal metadata
Share schema keyword roles and preserve reference bases for explicit local pointer targets and uncertain intermediate scopes. Retain literal values and canonical validation. Refs #4936.
2026-10-18 09:32:28 +08:00
Ysopwnable 1accac27c3 fix(ci): restore plist, verifier, and TOML capacity checks (#4930)
Correct stale plist and prerequisite fixtures, and replace the TOML serializer's repeated terminal-LF regex scans with a backward scan.

Keep capacity, timeout, source-preservation, backup, and idempotence coverage intact.

Fixes #4931
2026-10-18 01:20:43 +00:00
morluto 9df559b7e7 fix(analysis): gate document selection fallback and completion 2026-10-18 09:19:37 +08:00
morluto 94bc7ed322 fix(browser): retain module resolution through finalization 2026-10-18 09:07:53 +08:00
morluto 52b73ee857 fix(analysis): retain artifact admission cancellation reasons 2026-10-18 08:52:55 +08:00
morluto a8170163b9 test(rust): verify CLI retries exact descriptor cleanup 2026-10-18 08:51:13 +08:00
morluto bbfe6edd60 fix(artifacts): bind inventory and extraction cleanup to exact owners
Preserve typed failed attempts through root admission, hashing, inventory,
nested JavaScript readers and extraction rollback. Remove the intermediate
cause/resource records that discarded canonical cleanup capabilities.

Resolve original provider errors after confirmed release while preserving
primary failures, partial observations and invalidated-handle uncertainty.

Fixes #4928
2026-10-18 08:44:49 +08:00
morluto 2582c267af fix(artifacts): carry exact cleanup authority through scope failures
Return the canonical owner and lease from failed releases. Compose initial
cleanup failures from explicit operation outcomes and failed attempts, and
carry their authority through the shared artifact failure contract.

Keep independent unknown cleanup unresolved. Distinguish operation failures
from completed work whose close rejected. Let the scope own current child
resource labels without replacing its canonical retry lease.

Cover mixed owners, partial release, cancellation provenance, typed close
rejections and independent unknown cleanup through the producing boundaries.
2026-10-18 08:44:41 +08:00
morluto 2183c9598c fix(process): retain kernel limit descriptor cleanup ownership
Use the shared artifact file owner for kernel report reads, preserving the
physical outcome and exact retry lease through failed close and recovery.
Remove the handwritten finally path that discarded this authority.

Cover successful and failed reads with and without a caller scope, denied
retry, blocked replacement admission, and recovery of original error markers.
Adapt the separate descriptor repair proposed in #4863.

Fixes #4926
Co-authored-by: abdooo2235 <abdalrhmantheiv15@gmail.com>
2026-10-18 08:29:57 +08:00
morlutoandabdooo2235 93196449ad test(javascript): verify endpoint certainty through CLI and MCP
Exercise Map omission, escaped prototypes, opaque eval and candidate Evidence
through the rebuilt CLI worker and public MCP transport. Preserve exact static
fetch evidence and SQLite certainty controls.

Co-authored-by: abdooo2235 <abdalrhmantheiv15@gmail.com>
2026-10-18 08:25:28 +08:00
morluto fbfdb6abe9 fix(javascript): distinguish Map lookups from network endpoints
Resolve unchanged Map operations through shared binding, capture, mutation,
and ambient escape facts. Reuse that proof in application and captured
bundle analysis; unresolved get/delete receivers remain inferred candidates.

Preserve repeated native operations without manufacturing receiver escapes.
Retain uncertainty for real escapes, opaque eval, and changed constructor
adder hooks. Converge stored aliases at the producing boundary.

Adapt the JavaScript changes from #4863, excluding its Linux resource fix.
Add captured-bundle parity, repeated-operation and constructor-hook coverage.

Fixes #4853
Co-authored-by: abdooo2235 <abdalrhmantheiv15@gmail.com>
2026-10-18 08:25:06 +08:00
morluto e6c487799b fix(native): preserve resolved plist selection intent
Resolve lookup identity and selected/default origin together in the plist
source owner. Physical-file and conversion failures consume that fact
rather than reconstructing intent from omission of the path argument.
Selected plist artifacts resolve independently of readiness; unresolved
scope admission does not acquire an invented file-selection context.
Remove the superseded resolver and path/requested representation.

Cover direct-target CLI/MCP refusals, physical file conditions, permission
denial, default controls, unresolved scope context and cleanup retry for
both explicit path and selected-target workflows.

Fixes #4923. Related: #4849.

Validation: public CLI/MCP baseline3 failed8 controls passed; final55
passed across7files, check:fast, docs5, discovery1566 and source review.
Actual macOS26.3 plutil CLI/MCP; no Linux/Windows native qualification.
2026-10-18 08:11:46 +08:00
morlutoandapitoagents 7ca7e38717 fix(native): retain bounded plutil refusal diagnostics
Read failed conversion diagnostics from both output streams, retaining
raw bounded excerpts, observed byte totals, exit status and truncation.
Remove only repeated path prefixes from display text and report a useful
reason when the command prints no diagnostic. Reuse native failure
capture bounds rather than expanding accepted nonzero output into errors.

Adapted from PR #4851. Fixes #4849.

Validation: six controlled boundary failures on baseline, including the
stdout-only empty-reason defect; final46 passed across6files, real macOS
CLI/MCP controls, static checks, docs5 and discovery1565. On macOS26.3
plutil uses stderr; stdout-only coverage is controlled output. Separate
selected-target classification defect is reproduced and tracked as#4923.

Co-authored-by: apitoagents <339136651+apitoagents@users.noreply.github.com>
2026-10-18 08:04:33 +08:00
morluto f2b7bbb312 fix(plist): retain known binary non-finite value identity
Make XML numeric uncertainty explicit at its producing boundary, separate
from decoded IEEE NaN and signed infinities. Shared projection preserves
known values using canonical numeric labels; unresolved XML numeric
values remain explicit unknowns. Remove the superseded known-value
wrapper and spelling alias, keeping numeric interpretation with its owner.

Cover public CLI/MCP binary archives, lookalike dictionaries, authored
32/64-bit IEEE payloads, signed zero, and XML parsing/overflow uncertainty.
Document canonical labels and unrepresented NaN payload/sign details.

Fixes #4919. Related: #4906, #4852.

Validation: baseline 2 failures/5 controls through public CLI/MCP; stable
final 439 passed across25files, check:fast, docs:check and discovery.
Native macOS plutil and existing codesign controls executed; no
Linux/Windows run or real Interface Builder engine qualification.
2026-10-18 07:55:51 +08:00
morluto 69324b0f86 fix(native): project decoded entitlement scalars through plist owners
Consume shared value and exact-number projections before JSON validation
so decoded plist scalars cannot leak as ordinary dictionaries. Carry
projection limitations into signature evidence with entitlement context.

Related: #4906. Controlled command-runner regression passed. Real
codesign refused the authored non-finite entitlement; this does not claim
real entitlement support. Existing real signature CLI controls passed.
2026-10-18 07:48:25 +08:00
morlutoandMert Kaya 6c98708793 fix(plist): preserve observed non-finite XML reals
Recognize complete CFPropertyList literals at the XML owner and retain
canonical NaN and signed infinity identity as typed scalars. Keep scalar
wrappers distinct from lookalike dictionaries, share limitation text and
document alias normalization. Incomplete markup retains its existing
compatibility fallback and limitation. Bound token matching before case
normalization using the accepted grammar.

Adapted from PR #4908. Fixes #4906.

Validation: public CLI/MCP regression baseline 2 failed, 4 passed.
Final focused validation 430 passed across 25 files, including controlled
entitlement response coverage in the following commit. Real macOS plutil
CLI, check:fast, docs:check and discovery passed. Binary value identity
remains tracked in #4919; malformed literal policy remains #4852.

Co-authored-by: Mert Kaya <47145541+mertkayacs@users.noreply.github.com>
2026-10-18 07:48:18 +08:00
morlutoandMert Kaya d205c528e3 test(pcap): verify UTC metadata against authored capture records
Use capinfos epoch output and compare public CLI/MCP results with UTC
instants derived independently from the known authored PCAP records.
Avoid comparing product output with the same host-local display text.

Related: #4907, #4909. Syntax checked; live Linux verification not run.

Co-authored-by: Mert Kaya <47145541+mertkayacs@users.noreply.github.com>
2026-10-18 07:40:35 +08:00
morlutoandMert Kaya 796faa0e4e fix(pcap): preserve exact UTC capture instants
Request epoch timestamps from capinfos and normalize them once at the
metadata boundary, preserving nanosecond precision and explicit unknowns.
Bound numeric parsing to the producer representation and cover negative
fractions, calendar limits, malformed output and MCP projection.

Adapted from PR #4909. Fixes #4907.

Validation: 47 passed, 24 platform-specific skips across five focused
files; check:fast and test discovery passed. No live Wireshark or
Linux/Windows capture execution was performed on this macOS host.

Co-authored-by: Mert Kaya <47145541+mertkayacs@users.noreply.github.com>
2026-10-18 07:40:25 +08:00
morluto f0b9ef34c4 fix(verify): request command JSON for Cutter inspection
Use --json-output for the verifier's ij observation. Exercise the actual
verifier-selected arguments through the public CLI and authenticated fixture
bridge, asserting command JSON mode and retained Evidence. The old bare --json
selection fails this control. A live Cutter GUI was not qualified here.

Fixes #4912
2026-10-18 07:34:08 +08:00
morluto f4456dc196 fix(verify): restore owned firmware fixture hashing
Replace the removed hashFirmwareFile export with shared stable verifier hashing.
Keep hashing under the file scope and close MCP/file owners independently before
removing their fixture parent. Preserve the primary failure if cleanup also fails.

The actual firmware entrypoint now reaches its prerequisite gate; descriptor
retry and mixed-cleanup controls pass. Real Linux firmware-engine qualification
was not run here. Refs #4912.
2026-10-18 07:34:07 +08:00
morluto 7d79a6a85b fix(verify): own asynchronous Ghidra prerequisite inspection
Await installation inspection through one shared helper with a real resource
scope at all 13 verifier call sites. Retain exact close owners, complete cleanup,
and preserve primary plus cleanup failures. Keep compiler-only loading lazy and
use the namespace workflow's selected environment.

Add admission contract and native-file lifecycle controls, plus a real script
prerequisite rejection check. Controlled Java/header observations do not qualify
a real Ghidra engine. Combined verification selection: 122 tests passed across
five files; static/format/discovery passed; two scoped source reviews clear.

Refs #4912
2026-10-18 07:33:58 +08:00
morluto 823521085a fix(setup): transfer unscoped registration cleanup ownership
Preserve original RegularFileCleanupFailure capabilities when registration
inspection or maintenance planning has no caller-supplied resource scope.
Keep scoped diagnostics with the scope that already retained the descriptor.

Cover configuration and policy sources, completed and malformed-UTF8 reads,
all four exported reader/planner boundaries, exact descriptor retry after
pathname replacement, no subsequent execution, and scoped cleanup retry.

Validation: 79 tests across four focused files; the historical baseline fails
all 16 new ownership-transfer controls with eight existing/scoped controls
passing. check:fast, format:check, test discovery and six isolated completed
public doctor comparisons passed. Scoped source review found no blocker.

Real temporary descriptors and injected close rejection on macOS arm64 /
Node24.18.0; no native Windows/Linux close faults or provider verification.

Fixes #4910
2026-10-18 07:22:14 +08:00
morluto abb54ce374 test(setup): cover configuration identity regressions
Add direct controls for literal AppData roots, denied MSIX target rechecks,
and unrecognized Claude package deployments. Verify setup refuses mutation
and registration diagnostics remain invalid for unknown package readers.

Six new controls fail at 6d5281407 before the existing 9abdad335 fix; one
existing-behavior guard passes. All seven pass on current main. Keep native
Windows/app behavior distinct from macOS filesystem and platform-selected
adapter checks.

Validation: 82 tests across four configuration/CLI files, 42 header/skill/
lifecycle tests, 144 Ghidra/doctor consumer tests, check:fast, format:check,
and test-discovery verification passed. No provider/target execution.

Refs #4378, #4432, #4496, #4501, #4384, #4676
2026-10-18 07:16:10 +08:00
morluto d818c3d263 fix(doctor): preserve unresolved client configuration evidence
Use entry metadata to discover registration evidence independently of target
readability. Preserve failed metadata inspection as a named invalid diagnostic
instead of treating all lookup failures as absence. Remove the duplicate
boolean existence wrapper; configuration parsing remains the read owner.

Cover native permission-denied targets and metadata, dangling configuration
entries, maintenance exclusion, and public doctor output without mutation.

Validation: 73 focused tests across four files, check:fast, format:check,
and six isolated completed public doctor cost comparisons passed on macOS
arm64 / Node24.18.0. Native Windows/Linux permissions were not verified;
POSIX permission controls skip unsupported hosts and root.

Fixes #4905
2026-10-18 07:10:44 +08:00
morluto d0253c99d6 fix(setup): preserve the selected destination during configuration publication
Replace configuration-specific write-file-atomic delegation with a verified
input snapshot, exclusive private staging, and an explicit canonical-parent
destination. Existing files publish by rename; first-run files use an exclusive
link so a newly created destination is retained. Both consumers read back the
publication owner's selected path.

Retain descriptor and staging cleanup capabilities through recovery and host
retry. Preserve mode and ownership, remove temporary permission handoffs, and
use positional restoration writes. Keep UTF-8 diagnostics with failed cleanup.

Validation: 284 focused tests passed, one skipped across 14 files; check:fast,
format:check, docs:check (including five consistency tests), two source reviews,
and 12 completed isolated public CLI setup/uninstall cost controls passed.
Native Windows/Linux, real editor concurrency, and providers were not verified.
Final-check/publication races and same-inode concurrent writers remain unexcluded.

Fixes #4904
2026-10-18 07:06:15 +08:00
morluto 2fb5e204a3 fix(uninstall): retain configuration publication ownership through recovery
Replace pathname writes with the shared configuration publication owner.
Reject replacement readback and restore through the exact staged descriptor.
Retain initial-read, readback and publication cleanup owners for retry. Share
nested cleanup handling with setup without granting authority to opaque
cancellation reasons. Separate host admission from nested file cleanup gates.

Preserve uninstall file modes, including readable read-only configurations.
Hold the exact staging permission owner through writable-descriptor handoff
and failed mode restoration. Remove the superseded writeText effect contract.

Validation: 206 focused tests across 9 files, check:fast, formatting and
docs:check passed. Three uninstall replacement controls fail on baseline
7e4eed9dd while thirteen setup controls pass. Twelve completed CLI uninstall
tasks preserve equivalent outputs, config, backups and modes0400/0640.
Two read-only source reviews completed. Native Windows/Linux and real editor
races remain unverified; in-place writer exclusion is still not provided.

Closes #4902
2026-10-18 06:50:22 +08:00
morluto 7e4eed9dd4 fix(setup): bind recovery to the published configuration file
Retain the staged file descriptor through atomic publication, readback and
recovery. Refuse detected replacements or edits and restore through that
owned descriptor instead of reopening a pathname. First-run readback failure
now retains the file for manual recovery because pathname deletion cannot
prove exact ownership. Keep both descriptor owners when nested closes fail;
opaque close rejections do not transfer ownership.

Validation: 192 focused checks in 9 files, check:fast, formatting and docs:check
passed. Three replacement regressions fail on the baseline while six existing
recovery controls pass. Six completed setup tasks preserve equivalent config
and backups. Two read-only source reviews completed on macOS arm64 / Node24.
Native Windows/Linux and real concurrent editor behavior remain unverified.
State checks do not exclude an in-place writer after the last check.

Closes #4900
2026-10-18 06:33:04 +08:00
morluto 19329e43bb fix(setup): preserve launcher identity and uncertainty
Use one registration classifier for doctor, maintenance and uninstall.
Preserve unknown identity when launcher resolution fails, and compare native
paths without collapsing symlink traversal. Keep Node argv script selection
separate; ambiguous direct-launch interpretations cannot authorize removal.
Remove the superseded boolean ownership parser.

Validation: 183 focused tests passed, 2 Windows cases skipped; check:fast
and docs:check passed. Five public regressions fail on the baseline, including
foreign registration removal in an isolated fixture. Source review and authored
Node shebang controls completed on macOS with Node 24.18.0. Native Windows,
Linux and real mise upgrades remain unverified.

Closes #4895
Closes #4896
2026-10-18 06:18:34 +08:00
morluto 01cdbbdc55 fix(update): bound package-manager output retention
Reuse supervised raw-byte capture with a 4 MiB aggregate budget. Drain package-manager output through physical close, reject oversized complete replies, and let verbose installs finish with explicitly bounded failure diagnostics. Preserve existing command resolution, selected environment/cwd, runtime prerequisites and signal policy.

Own human progress backpressure and final write acknowledgements without ending borrowed stderr. Continue draining after destination failures and observe outstanding write rejections through their error event.

Validation: 152 checks across 12 focused files, followed by a 44-check rerun including two additional no-deadline waiter controls; typecheck/lint, docs and discovery pass. The public oversized-metadata regression fails on 4f7b5fb60. Fixtures execute owned Node/fake npm/Bun commands; no actual package install or registry request. Native Windows/Linux and exhausting-output/OOM scenarios were not run.

Small completed CLI checks return identical replies and token estimates. Six sequential baseline/candidate tasks separate first-process and two warm repeats; no speedup, true-cold or large-install memory claim. Existing descendant cleanup and signal behavior is outside this output-bound fix.

Closes #4888.
2026-10-18 05:57:57 +08:00
morluto 182e9a268c refactor(process): allow awaiting physical output closure
Allow the existing supervised output wait to omit its deadline while preserving bounded waits and abort-listener cleanup for current consumers. Updater package-manager commands can await physical stream completion without an invented install timeout.

Refs #4888.
2026-10-18 05:57:36 +08:00
morluto 4f7b5fb602 fix(cli): route update flag through verified updater
Normalize the unambiguous root --update alias before output handling and
through direct createCli().serve calls. Reuse the existing output-value scan
and canonical update command, including selected environment, installation
ownership, Windows-aware launch, verification, maintenance and failure facts.
Retain option data and help/check precedence. Reject remaining Incur install
requests: update:false does not disable its explicit installer in0.6.1.
Remove the superseded output-only normalizer name and update its consumers.

Validation:123focused checks/7files pass, including compiled CLI with an owned
rejecting fake npm and direct serve across5formats. Original argument owner
fails6new controls/7pass; isolated baseline fails8workflow checks/2controls
pass. Static/docs/discovery1561 pass. Both scoped source reviews are clear.
Six completed equivalent current-version workflows compare baseline canonical
update with the alias; complete replies identical. Native Windows upgrade,
real package-manager installation and full install costs remain unverified.

The first baseline escaped a Vitest-only builtin mock and installed REA in the
pinned Node global prefix. Removed the newly added package and verified original
Node/npm/Corepack tools. Re-ran using the real builtin spy with synchronized
ESM exports, an independently rejecting PATH shim and owned npm prefix/cache.
Keep heavy tests/profiling stopped. Independent updater output bounds remain
tracked in #4888 rather than changing collection policy in this routing fix.

Fixes #4883
2026-10-18 05:33:21 +08:00
morluto c555caad65 fix(setup): resolve Hermes named-user homes before planning
Resolve the current named POSIX account through OS identity rather than the
caller-selected HOME/USERPROFILE. Preserve the home prefix for repeated
separators using the same joining semantics as the existing ~/ branch.
Require an absolute HERMES_HOME for unresolved names and Windows named forms
before exposing config or skill write destinations. Reuse the shared Hermes
path owner and existing diagnostics across setup, doctor, skills and uninstall.

Validation: 113 checks across seven files pass, including the compiled CLI
setup/doctor/skill/repeat/uninstall workflow over an owned profile beneath the
actual account home and a separate caller home. The isolated unchanged baseline
fails the five new checks and passes44existing checks; final repeated-separator
controls also fail that baseline. Static/docs/discovery1559 pass. Both source
reviewers clear after correcting repeated-separator composition.

Twelve completed setup dry runs compare normal and named overrides, with exact
normal-home replies unchanged. Measurements have source hashes and separate
first/warm runs; no speedup, full Hermes agent/model or native Windows/Linux
qualification claim. No provider software was installed; heavy tests/profiling
remain stopped.

Fixes #4841
2026-10-18 05:17:31 +08:00
morluto 9ac76d3d94 fix(javascript): invalidate stale facts across direct eval
Index unshadowed direct-eval sites once at the semantic owner. Distinguish
lexical rebinding, non-strict eval-introduced names, and possible mutation
of reachable objects. Reuse existing effect timing and capture proofs;
retain original definitions and module origins without inventing assignments
or parsing or executing eval payloads. Query object uncertainty conservatively
across the owning activation so aliases remain covered when names are shadowed
or leave block scope. Retain no binding-by-eval table.

Use the shared facts for values, read provenance, reference effects and child
argument shapes. Preserve indirect/optional/shadowed eval controls, unrelated
activations, immutable shapes, strict-mode bindings and prior primitive
captures. Remove obsolete reference plumbing and the source-wide eval blocker.

Validation: 306 focused checks across 16 files pass, including compiled CLI
and stdio MCP return projections, constructor uncertainty and child-process
consumers. Against the preceding SQLite commit, 9 of 23 selected checks fail
and 14 controls pass. Static/docs/test discovery (1559 files) pass. Two source
reviews found no remaining scoped blocker after alias and sloppy-name fixes.
No analyzed JavaScript, SQLite engine, heavy test or profiler was executed.
Conservative object reachability can intentionally lose exactness; large-case
opaque-query CPU and memory remain unmeasured.

Fixes #4875
2026-10-18 05:08:37 +08:00
morluto fc847ffe35 fix(javascript): preserve SQLite constructor provenance
Use Database spelling only to select a candidate. Reuse shared expression
provenance and indexed mutation facts to omit proven local constructors and
retain known SQLite API origins separately from uncertain names. Match ESM
default/namespace and CommonJS export forms without collapsing their identity.
Keep type-only import origins as ambiguous runtime values, including aliases.

Carry candidate interpretation through the worker schema and graph nodes and
edges with low confidence, explicit limitations and distinct identities.
Remove the name-only SQLite storage classifier. Other storage APIs retain
existing handling; PR4863's separate Map endpoint work is not integrated.

Validation: initial9negative controls fail unchangedf5fcf5216 while4positive
controls pass; final67focused checks/8files plus60provenance-consumer checks/
4files pass. Static/docs/discovery1557 pass. Two source reviewers clear after
correcting namespace constructor identity. Public CLI checks worker/schema
projection and separate exact/candidate identities with the same filename.

Twelve small completed CLI workflows preserve exact known-API replies and
remove false local-class storage facts. No speedup/large-case memory or real
SQLite execution claim. Direct eval's existing generic invalidation defect
remains tracked separately in #4875. Heavy tests/profiling remain stopped.

Additional consumer validation caught and corrected runtime import-equals
classification: require-mode import origins remain runtime values. Three new
SQLite controls cover runtime and erased import-equals forms; compiled
child-process CLI/MCP stdio workflows pass after the correction.

Fixes #4854
2026-10-18 05:06:46 +08:00
morluto f5fcf5216f fix(apktool): retain decode facts across interrupted read stages
Keep one typed accumulation of observed decode facts instead of constructing
partial Evidence only after string projection. Record decoded client/target
before the post-command cancellation checkpoint, parsed metadata before
manifest reads, raw manifest before interpretation, and inventory prefix
before rethrowing its exact original cause. Omit unexamined fields.

Return inventory success or exact failure plus completed prefix through
Result. Keep resource-cap stops distinct from physical failures. Attach
truncation and inventory limitations at their producing stages. Validate
complete results with the named domain schema; centralize partial Evidence
assembly in the existing failure/cleanup boundary.

Validation: six authored stage controls fail unchanged34a88d6c1; 131 focused
checks across7files, check:fast, docs:check and discovery1556 pass. Covers
manifest bytes/XML, interrupted inventory, late cleanup cancellation,
denied removal/retry and existing table interruption. Two source reviewers
clear after moving the command handoff checkpoint. No separate runtime
qualification of that precise handoff race.

Public CLI manifest failure retains metadata/raw manifest with unknown
fields omitted and original failure framing unchanged. Twelve small normal
CLI tasks retain exact replies. No speedup or memory-saving claim; failure
reply estimate189 to610cl100k tokens preserves completed Evidence. No real
Apktool, large-case memory or whole-agent qualification. Heavy tests remain
stopped.

Fixes #4882
2026-10-18 04:36:30 +08:00
morluto 34a88d6c16 fix(apktool): retain completed facts after locale read failures
Return completed string projections with the exact failure cause in Result.
Force partial coverage and disclose the interrupted selection and remaining
unattempted selections without inventing table status or counts.

Assemble execution once from success or partial projection. Preserve the
original failure through existing ownership/cleanup classification, then
retain completed Evidence before snapshot fallback. Existing producer
observations retain precedence. Remove the throw-only projection contract.

Validation: four authored filesystem controls fail unchanged f1edf0da0;
99 focused checks across six files, check:fast and docs:check pass. Covers
late cancellation, denied workspace cleanup and retry, opaque cancellation
between tables, exact physical cause, and CLI/MCP contracts. Public CLI
failure retains completed facts; original failure framing is unchanged.
Two source reviews found no blocker.

Twelve small normal-path CLI tasks preserve exact replies. Measurements
show no speedup; failure reply grows to retain Evidence (cl100k estimate
189 to 696). No real decoder, whole-agent, or large-case memory claim.
Heavy tests and profiling remain stopped.

Fixes #4880
2026-10-18 04:29:41 +08:00
morluto f1edf0da0c fix(cli): preserve APK locale-list schema bounds
Reuse the named domain locales field instead of reconstructing an optional
array from its element type. Preserve min/max selection bounds through the
CLI parser and public JSON Schema while retaining the repeat-flag guidance.
The application service already validates the input; provider authority is
unchanged.

Add a public schema regression and compare advertised Ajv2020 acceptance
and CLI parser acceptance with the owner for omission, empty, valid,
maximum, oversized and invalid-element selections.

Validation: regression fails unchanged d37c34647; 21 focused checks across
4 files, check:fast and docs:check pass. Source review found no blocker.
No real-provider or performance qualification claim. Heavy tests remain
stopped.

Fixes #4876
2026-10-18 04:21:19 +08:00
morluto d37c346477 fix(apktool): retain observed table counts through output limits
Separate physical string-table facts from per-selection output allocation.
Use one owner for legacy and batched projections, preserving caller labels
and normalized-directory reuse. Retain complete counts and at most one
bounded table prefix for later aliases. A skipped cached alias keeps its
known counts; unexamined tables keep explicit unknown counts.

Remove the provider's duplicated parsing and status branches. Charge the
primary legacy copy before selecting output entries and derive limitation
text from the actual emitted count. Reuse the named request input type and
clarify nullable count descriptions without changing their schema types.

Have the workspace report retained raw-prefix bytes, including a stripped
UTF-8 BOM, instead of reconstructing source cost from decoded text.

Validation: 145 focused checks across 8 files; baseline count control fails
unchanged fd6da7092; check:fast, docs:check and discovery 1556 pass. Twelve
small public CLI decode workflows preserve exact normal-path replies and
request/reply token estimates. Timing variation is noise-level; no speedup,
large-case memory or real Apktool qualification claim. Heavy tests/profiling
remain stopped.

Fixes #4874
2026-10-18 04:19:10 +08:00
ShuaixinHuangandmorluto 9e372c6bc9 fix(cli): preserve spaced output flag values (#4823)
* fix(cli): preserve spaced output flag values

* docs(readme): fix French heading spacing

* fix(ci): retain portable build cache until snapshot upload

* test(browser): assert composed Electron cleanup failures

---------

Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-18 04:02:45 +08:00
morluto fd6da70920 fix(cli): report string capacity failures during result formatting
Recover completed ordinary command results when pinned Incur formatting
exceeds the runtime string limit before stdout begins. Emit a small typed
memory constraint with an explicit unknown formatted size, the runtime limit
and JSON/filter remediation. Preserve full-output framing and leave normal
CTA, human and token-window formatting with Incur. Never rerun analysis.

Capture canonical failure identity at its logging owner, including thrown
AnalysisError projections. Recovery reads compact captured facts without
revalidating or retaining large diagnostics. Keep destination failure ownership,
prevent a second stdout document and retain quiet SIGPIPE status during recovery.

Validation: 111 distinct focused tests across 10 files; check:fast,
docs:check and discovery of all 1555 test files. Sixteen authored formatter
controls fail unchanged e103ae0ce and pass with this fix. A separate closed
reader control caught and now covers recovery EPIPE handling. The heavy JSON
string-limit regression remains excluded; no large Electron reproduction ran.

Twelve small public CLI artifact inspections preserve identical raw replies
and token estimates in TOON and JSON. Timings are noise-level, with no speedup,
cold-cache, large-result memory or real-provider qualification claim. Sentinel
and generator protocols keep their existing ownership.

Fixes #4806
2026-10-18 04:00:15 +08:00
Abhay Tiwari 6668424343 feat(apktool): share one APK resource decode across selected locale tables (#4777) (#4804)
Project default and multiple selected localized string tables from one
immutable decode pass. Remove the need for repeated APK snapshotting,
digesting, version probing, apktool d invocations, and workspace enumeration.

- Contract: add optional locales array to decode_android_resources input
  schema (bounded to 20 locales) and structured string_tables to output schema
  with per-table status, strings, total_count, unparsed_count, and coverage.
  Preserve legacy strings and locale fields for complete backward compatibility.
- Bounds: enforce 32 MiB aggregate XML read cap and 10,000 aggregate string
  entries cap across batched projections. Handle missing, oversized, and
  malformed tables per-table without failing or losing completed tables.
- Lifecycle: maintain strict descriptor cleanup and provider-owned workspace
  removal in finally, preserving typed cancellation and failure details.
- Adapters: add --locales repeatable option to CLI and update MCP contract.

Validation: 10 service tests, 3 CLI boundary tests, and MCP boundary schema
tests pass. Fast typecheck/lint and turbo docs:check:built pass.
Fixes #4777
2026-10-18 03:57:17 +08:00
pablodiazjorge 3b5605ecd2 fix(plist): keep negative-zero reals distinct from positive zero (#4839)
Plist inspection reported a serialized -0.0 real as the JSON number 0.
- The shared plist projection reports it as a typed real scalar whose value is the string -0, counted in a limitation for keyed archives and inspect_plist.
- The plutil JSON path applies the same value when it decodes -0.
- The XML decoder no longer returns -0 for a mixed-content integer.

Fixes #4834
2026-10-18 03:56:43 +08:00
Prasad Navale 09de00b410 fix(javascript): admit CommonJS bare scoped package directory resolution (#4838) 2026-10-18 03:54:51 +08:00
morluto e103ae0ce5 fix(clients): advance TOML statement lines without document rescans
Reuse the writer's monotonic statement index to find the last physical line
of an assignment. Remove the full line-start scan performed for every key.
Preserve source edits, multiline values, BOM, CRLF and final-line handling.

Add LF/CRLF controls with adjacent assignments, multiline values, an empty
value and EOF without a newline. Validated 85 focused tests across six files,
check:fast, docs:check and discovery of all 1553 test files.

Twelve bounded public CLI uninstall tasks preserve equivalent replies,
configuration and original backups. Warm 10000-assignment elapsed medians
were 0.538/0.520 s and CPU 0.817/0.744 s before/after; small-input timings
were noisy and slower in the candidate. No general speedup, cold-cache,
real-client or analysis-provider claim. Heavy profiling remains stopped.

Fixes #4873
2026-10-18 03:41:32 +08:00
hhang c43bc0bf66 fix(clients): preserve large TOML documents without argument spreads
Fixes #4856
2026-10-18 03:38:12 +08:00
morluto 3460ceac3f fix(browser): retain exact scenario cleanup ownership
Transfer canonical leases through opening, session and storage boundaries. Keep response deadlines separate from actual completion, drain independent owners, and join late opening failure cleanup before confirming recovery. Remove error copies in favor of canonical primary/cleanup composition.

Preserve exact caller reasons, completed observations and independent physical failures through final-close cancellation and retry. Closes #4869.

Validation:155 tests pass across15 focused source, service, CLI subprocess and MCP files; static/docs/discovery1551 pass. Two original-revision controls fail as expected. Bounded authored-session public CLI comparison preserves equivalent Evidence and1282 reply token estimates; no real Chromium qualification or forced-termination recovery claim (#4659).
2026-10-18 03:22:29 +08:00
morluto 16924e275e fix(artifacts): serialize concurrent cleanup lease releases
Share the in-flight release for one exact owner, preserve failed attempts for retry, and notify dependent errors only after confirmed completion.

Validation: concurrency control fails on3fcba0796 with two cleanup attempts; isolated foundation passes38 selected lease/scope/resource tests. Authored lifecycle controls, no native provider qualification.
2026-10-18 03:21:02 +08:00
morluto 3fcba07962 fix(process): preserve file outcomes through exact cleanup recovery
Classify canonical physical file outcomes through the provider mapper before composing cleanup. Retain unknown capabilities as unresolved and replace runtime failure maps with exact leases, including mixed cleanup and partial retry.

Keep completed-read cancellation output and cleanup history. Closes #4865.

Validation: 179 unique focused tests passed across 13 selected files, 7 Linux-only skips; static checks, docs checks and 1551-file discovery passed. Authored Node producers and controlled real-descriptor faults do not qualify native providers.
2026-10-18 02:55:41 +08:00
morluto daa641aa3c fix(artifacts): retain canonical cleanup leases for scope owners
Pair each retry owner with its exact lease and reuse that lease for release and recovery. Remove variant-based lease inference.

Validation: isolated scope foundation passed 23 selected tests; final candidate passed the broader focused suite and static checks. Real-provider behavior was not qualified.
2026-10-18 02:55:19 +08:00
morluto 8a247fc70f fix(providers): preserve artifact producer cancellation facts
Wire sigrok and tshark finalization to the effective signal. Services and file-failure adapters retain exact opaque reasons and completed Evidence instead of guessing from error names. Preserve typed primary outcomes through failed cleanup and recovery.

Validation: latest per-file coverage is 114 passing tests across nine selected files with 14 explicit Linux-only skips; core foundation passes independently. check:fast, docs and discovery pass. Four finalization controls failed before the signal ownership fix. Bounded completed authored-producer service workflows have identical Evidence with no performance improvement claim. Real sigrok/tshark and native Linux/Windows were not verified.

Closes #4858
2026-10-18 02:38:30 +08:00
morluto 147ae9718a fix(process): preserve artifact cancellation through finalization
Consume owner-recorded cancellation reasons, recheck admission after pending cleanup, and keep typed cancellation with completed observations through final workspace cleanup and retry. Existing physical failures remain primary.

Validation: 18 core tests pass; 20 combined boundary controls fail on baseline before consumer migration, and four final-close service controls failed before finalization signal ownership. Focused integration, static/docs and bounded service comparisons pass. No native Linux/Windows or real sigrok/tshark qualification.
2026-10-18 02:37:53 +08:00
morluto 300905c11b fix(android): retain archive admission ownership through cleanup retries
Borrow the archive descriptor from the canonical artifact file workflow. Preserve primary configuration failures, completed archive facts and exact cancellation through final close, retain failed descriptor leases, and join provider and doctor shutdown without nested resource admission.

Validation: three baseline failed-close regressions; 65 passing tests across seven files, nine real CLI and nine real MCP tiny APK inspections, check:fast, docs and discovery. Two read-only reviews clear. Bounded equivalent workflow costs recorded without a speedup claim; no actual OS close fault or native Windows/Linux qualification.

Closes #4846
2026-10-18 02:19:12 +08:00
morluto f1d18859eb fix(artifacts): preserve opaque ZIP cancellation reasons
Use the canonical artifact cancellation checkpoint for enumeration, open and extraction instead of dropping the caller reason in a ZIP-specific helper.

Validation: both new ZIP reason controls fail on the unchanged baseline and pass on the candidate; the focused seven-file run passes 65 tests. Native Windows/Linux were not run.
2026-10-18 02:18:55 +08:00
morluto 662fad9072 fix(cli): finalize doctor cancellation after failure logging
Make the signal boundary own logging and projection as it does for other cancellable commands. Preserve SIGINT/SIGTERM exit disposition after joined doctor cleanup without changing generic failure classification.

Validation: both public signal controls fail on the baseline with exit1 and pass with130/143 after the fix; selected Java groups are empty. Twenty focused tests across five files, check:fast, docs and discovery pass. Authored launcher fixtures do not establish real JVM or native Windows/Linux behavior.

Closes #4848
2026-10-18 02:07:41 +08:00
morluto ceeff5a417 fix(android): own Java prerequisite probing and readiness shutdown
Run the selected module-listing command through owned supervision, preserve completed module facts through finalization, and retain failed cleanup in provider/doctor scopes. Join complete availability calls on shutdown, preserve opaque interruption reasons, and validate numeric Java facts before reporting them.

Validation: 223 passing focused tests across 21 affected files, one platform skip; controlled baseline returns before child exit; real doctor cancellation leaves the selected Java group empty; nine real CLI and nine MCP tiny-APK inspections pass; six bounded MCP cost comparisons preserve normalized results. Native Windows/Linux and actual JVM failure modes remain unverified. Separate CLI exit disposition and archive failed-close findings remain open.

Closes #4845
2026-10-18 02:00:29 +08:00
morluto 964decd989 fix(providers): preserve live cleanup ownership through retries
Share exact command/helper cleanup adoption across Java probes. Preserve complete live resource labels and explicit unknowns through inspection leases, and retain unresolved ownership when a cleanup capability is unavailable.

Validation: focused cleanup, provider/doctor and Kuna consumer checks; shared Ghidra lifecycle and public doctor regressions. Native Windows/Linux provider behavior remains unverified.
2026-10-18 01:59:10 +08:00
morluto 3ad1032b11 fix(android): finalize startup diagnostics before reporting failure
Record the first transport failure before SDK teardown, then capture terminal stderr after owned retirement. Preserve exact opaque cancellation reasons and keep foreign cleanup ownership separate through retries.

Validation: 119 focused tests across eight files; five selected baseline regressions; check:fast, docs:check, test discovery; nine real CLI and nine real MCP tiny-APK inspections. Native Windows/Linux startup failures and actual JVM OOM remain unverified.

Closes #4844
2026-10-18 01:28:36 +08:00
YsopwnableandShuaixinHuang 3ddb2e4cf7 fix(ci): handle cache eviction and composed cleanup assertions (#4824)
* fix(ci): handle eviction when staging portable build cache

* docs(readme): fix French heading spacing

(cherry picked from commit 0ccd0e6999)

* test(ci): verify observed cache coverage during eviction

* test(electron): assert composed launch cleanup diagnostics

(cherry picked from commit e1466dc480e715b427cddfc3569b2baf03574405)

---------

Co-authored-by: ShuaixinHuang <1836656514@qq.com>
2026-10-18 01:08:14 +08:00
morluto 7016951394 fix(process): retain diagnostics through bounded output finalization
Separate verified process cleanup from output closure. Bound additional retention from owned stop entry through cleanup retry, drain before detaching capture, and mark unreadable or abandoned output incomplete. Release owned event-loop references on drain timeout without changing the proven cleanup disposition; preserve borrowed handle reference state.

Cover held and failed cleanup, late tail, bounded drain, stream errors, borrowed authority, and a real POSIX inherited-stderr release barrier. The real pipe control drops its final ten bytes on the baseline and retains them with this change. Focused consumer checks passed, including simulated Windows ownership; native Windows and real provider failure scope remain unverified.

Android still constructs its startup error snapshot before retirement; that consumer correction remains separate work.

Fixes #4840
2026-10-18 01:03:19 +08:00
morluto 3fa972af7c fix(android): preserve typed JVM memory failures during loading
Translate actual OutOfMemoryError at the bridge boundary before upstream stringifies it. Preserve observed heap bytes, missing reasons, coroutine context and cancellation; retain SessionHolder ownership and load options. Restrict heap-specific remediation to known heap reasons and parse named bridge failure contracts once.

Coordinate bridge protocol v4, clarify doctor configuration versus target capacity, and preserve the memory primary across cleanup failure/retry. Verify controlled immediate/late/inline continuation outcomes with the pinned JAR and real JDK, focused tests, and tiny real CLI/MCP method workflows.

Actual heap exhaustion, the reported APK, pre-handshake failures, Linux and Windows remain unverified; no stress or profiling run.

Fixes #3517
2026-10-18 00:48:12 +08:00
morluto 9fa6d2b254 fix(android): preserve primary failures through cleanup retries
Compose cleanup failures with the canonical primary error and bind current resource attribution to the retained acquisition record. Remove the stale diagnostic alias and duplicate failed-handle representation.

Validate the strengthened controlled cleanup regression in an isolated checkout; it fails on the baseline's stale resources and passes with this commit. Real JVM cleanup failure is unverified.

Fixes #4835
2026-10-18 00:47:46 +08:00
morlutoandTaksh 63c65a2243 fix(android): recover original bodies when Java source is omitted
Resolve smali using frozen raw method names and full DEX descriptors. Select
one complete block before truncation for missing Java, static initializers
and decompiler marker fallbacks. Reject ambiguous or incomplete blocks and
preserve upstream disassembly failure notes.

Bind method replies to the selected descriptor with bridge protocol 3.
Remove consumer placeholder/error-prefix interpretations and the superseded
blanket overload fallback rejection. Producer failures now use the shared
failed-tool path before truncation. Migrate protocol fixtures and consumers.

Adapt the direct selector guard from PR #3450; recover original bytecode
instead of inferring a holder from generated comments.

Validation: 122 focused tests in 9 files; real pinned-JAR baseline regression
fails and candidate passes, including overloads, aliases after generation,
branches/handlers, 16-byte output and negative selection controls. Nine real
CLI and nine MCP fixture calls pass with parity/identity/digest/no-mutation
checks. Static/docs checks and two source reviews pass. Six completed real
MCP cost workflows recorded; same calls with improved source, no speedup
claim. Tiny authored APKs, macOS/JDK 21 only; reported editor APK and native
Linux/Windows unverified. Heavy profiling and stress remain stopped.

Fixes #3443

Co-authored-by: Taksh <takshkothari09@gmail.com>
2026-10-18 00:25:36 +08:00
morlutoandbalkan16 742b6f587f fix(android): preserve native and abstract body absence
Freeze body-absence access flags with stable parsed method identity, before
code generation can rewrite method metadata. Skip source slicing for these
methods and return unavailable empty source with explicit native/abstract
markers, rather than attributing neighbouring members to the selected method.

Adapt the access-flag guard and tiny Smali fixtures from PR #3527. Extend real
metadata and public CLI/MCP regressions for native, static native, abstract,
concrete overloads and re-reading frozen facts after neighbouring generation.
Rename the expanded method-body verifier and remove its old entry point.

Validation: 72 focused tests in 3 files; real pinned-JAR baseline control
fails and candidate passes without triggering code generation; 6 real CLI
and 6 MCP fixture calls with parity, identity and unchanged APK; docs/static
checks and two source reviews. Six measured real MCP workflows, no speedup
claim. Tiny authored APK only; reported BinaryEye, Linux/Windows and browser
workflows unverified. Heavy profiling/stress remain stopped.

Fixes #3488

Co-authored-by: balkan16 <57933796+balkan16@users.noreply.github.com>
2026-10-17 23:53:23 +08:00
Prasad Navale 3c1cce78ee fix(domain): admit Qualcomm Hexagon (EM_HEXAGON, 164) ELF binaries (#4819)
* fix(domain): admit Qualcomm Hexagon (EM_HEXAGON, 164) ELF binaries

Resolve missing ELF admission case for Qualcomm Hexagon DSP targets (e_machine = 164, EM_HEXAGON).

- Add 'hexagon' to BINARY_ARCHITECTURES and HeaderArchitecture
- Map EM_HEXAGON (164) in elfArchitecture() to 'hexagon'
- Include 'hexagon' in GhidraProvider's SUPPORTED_ARCHITECTURES
- Gracefully decline 'hexagon' with Ghidra-directed diagnostic in Hopper and IDA
- Add unit tests for Hexagon ELF parsing and adapter admission checks

Fixes #4781

* fix(hopper,ghidra): add Ghidra guidance to Hopper Hexagon refusal and add Ghidra admission regression test
2026-10-17 23:52:03 +08:00
morluto b27e1a74c9 docs(i18n): complete Malayalam locale registration and links
Resolve eight nested README links from their owning directory. Preserve the
shared README/website inventory contract by registering Malayalam with an
explicitly untranslated catalog and the existing visible, noindex English
fallback. Regenerate the shared website navigation and catalog references.
Existing parsed translations remain unchanged.

Validation: docs check, full website check (401 HTML pages, 27790 local
references, 19 tests), all 19 generated Malayalam fallback pages, and two
source reviews. No Malayalam website translation or browser layout claim.

Fixes #4821
2026-10-17 23:39:40 +08:00
morlutoandAbhay Tiwari dc2e8117b6 fix(apktool): distinguish document failures from entry omissions
Return tagged string-document parsing failures instead of fabricating one unparsed entry. Preserve XML failure reasons and publish unknown counts with partial coverage; count only examined unsupported entries in validated documents. Migrate every consumer, remove the superseded throwing XML wrapper, and retain completed failure Evidence through cancellation and failed cleanup.

Adapt the document-versus-entry distinction from PR #4804 using the shared Result and XML owner. Multi-table projection and its aggregate bounds remain under review in #4777.

Validation before incoming main rebase: 229 focused tests in 15 files, four baseline controls fail, static/docs checks and two source reviews. Twelve tiny actual MCP workflows and four CLI controls; authored launchers only, no real Apktool/JVM/Windows qualification.

Fixes #4820

Co-authored-by: Abhay Tiwari <abhaytiwari0821@gmail.com>
2026-10-17 23:27:29 +08:00
rodricksz4h5 bec88b9d77 fix(javascript): retain CommonJS exports defined with Object.defineProperty (#4725)
* fix(javascript): retain CommonJS exports defined with Object.defineProperty

tsc, Babel and Rollup emit Object.defineProperty(exports, name, descriptor) for CommonJS re-exports. The semantic projection only recognised assignments, so these exports were missing from export_names and exposes edges. Recognise the call on exports or module.exports with the existing unmodified-global and receiver checks, track its receiver lifetime like an assignment, and link a data descriptor's value like the assigned value; an accessor's result stays unknown.

* fix(javascript): unwrap assignment chains in defined CommonJS export values

A descriptor value such as holder.parse = require("./parser").parse lost its require origin because only the assignment path took the rightmost assigned value. Do it once in the shared export builder.
2026-10-17 23:23:47 +08:00
ShuaixinHuang 6b0113a534 fix(browser): preserve URL paths when removing credentials (#4731)
* fix(browser): preserve URL paths when removing credentials

* test(browser): verify URL userinfo through real V8 captures
2026-10-17 23:23:37 +08:00
ShuaixinHuang 68c3c5b538 fix(native): preserve leading U+FEFF in Apple metadata names (#4730)
* fix(native): preserve leading U+FEFF in Apple metadata names

* test(native): run property metadata regressions on macOS
2026-10-17 23:23:27 +08:00
kraken-503 af67ad5047 docs: add ml translation (#4792)
* docs: add malayalam translation

* docs: add ml hyperlinks to other docs

* docs: fix ml hyperlinks

* docs: fix ml hyperlinks

* docs: add english hyperlink in README_ml.md

* docs: fix README_ml.md

* docs: fix README_ml.md

* Update links and headings in README_ml.md
2026-10-17 23:22:58 +08:00
Shivam Dwivedi c1fe0d653d fix(setup): recognize shared CLI launcher aliases (#4803) 2026-10-17 23:22:43 +08:00
morluto d38f099692 fix(apktool): disclose platform and release advisory windows
Carry the selected host into the version owner, disclose the Windows follow-up before 2.9.3, and bound the 3.0.x resource type-name validation warning before 3.0.2. Share warning formatting and preserve reported spelling, prerelease semantics and exact dirty-release handling.

Verify the upstream producing-boundary patch instead of assuming a file-writer sanitizer. Explicitly label inclusion of the tagged 3.0.0 release line as source-derived; version and host guidance do not establish engine contents or backports. Retain warnings with completed Evidence during cancellation and failed cleanup.

Validation: 222 focused tests in 15 files, 16 baseline controls fail, static/docs checks and two source reviews. Twelve tiny actual MCP workflows and six CLI controls with authored launchers; no real Apktool/JVM, native Windows, exploit or true cold verification.

Fixes #4818
2026-10-17 23:16:13 +08:00
morlutoandGovindu Sasanka 63696d2773 fix(apktool): retain advisory facts from the version observation
Parse the launcher version once to own both compatibility and CVE-2024-21633 advisory facts. Inspection and decoding consume those facts, including completed Evidence retained during cancellation. Preserve source spelling, exact dirty-release handling, prerelease semantics, and existing version-only failure diagnostics.

Adapt the Apktool warning policy from PR #3440. State that a reported version does not establish engine contents or downstream backports; avoid recommending 2.9.2+ as generally safe. Other advisory applicability and release-range questions are tracked in #4818.

Validation: 194 focused tests in 15 files; final 87 source checks; five baseline controls fail; static/docs checks; two source reviews. Twelve tiny actual MCP workflow comparisons and four CLI controls; authored launcher only, no real Apktool/JVM/Windows or exploit verification.

Fixes #3438

Co-authored-by: Govindu Sasanka <31107592+GovinduSasanka@users.noreply.github.com>
2026-10-17 23:08:00 +08:00
morluto 6385ef4355 fix(apktool): derive locale size from resource configuration fields
Allow the 23-character script-region-variant representation emitted by Apktool, retaining the shared admission grammar and request aliases. Exact discovery and CLI/MCP selection consume the same bound.

Validation: 67 focused tests across four files; five controls fail on the baseline; static/docs checks and two source reviews. Twelve ordinary tiny CLI/MCP task comparisons preserve Evidence; two actual authored-launcher long-locale CLI/MCP calls select the table. No real Apktool/JVM or native Windows verification.

Fixes #4817
2026-10-17 23:00:26 +08:00
morlutoandOke Iyanuoluwa E. 98886adddf fix(apktool): disclose tables outside exact locale selection
Inventory observed entries through the owned artifact traversal, preserve other configuration names, and disclose non-regular tables with partial coverage. Share request alias normalization with exact table classification and preserve filesystem failures.

Adapt the disclosure policy from #4738. Correct the fixture command separator so all advertised tables are actually created.

Validation: 164 focused tests; check:fast; test discovery; docs:check. Two regression controls fail on the baseline. Twenty-four tiny authored CLI/MCP comparisons; no real Apktool or Windows verification.

Fixes #4612

Co-authored-by: Oke Iyanuoluwa E. <oke.iyanuoluwa12@gmail.com>
2026-10-17 22:55:08 +08:00
morlutoandPeter cc038da218 fix(apktool): attribute decode refusals to the selected APK
Carry caller-selected target identity separately from launcher selection. Only fully collected ordinary nonzero decode exits represent target refusals; startup, preparation, capture and signal failures retain provider attribution. Reuse one command/preparation output projection for probe and decode errors.

Adapt the target-path correction from PR #3462 (08d3d0d3a0) and extend its producer-boundary classification and regression coverage.

Validation: 131 focused tests in 12 files, final 50 source checks, build, typecheck/lint and docs. Ten regression controls fail on baseline 4844ae812. Twenty-four tiny actual CLI/stdio MCP refusal tasks preserve every projected field except the corrected message/path. Authored launchers only; no real Apktool/JVM or native Windows claim. Heavy stress/profiling remained stopped.

Closes #3340

Co-authored-by: Peter <304086198+peter-research@users.noreply.github.com>
2026-10-17 22:44:00 +08:00
morluto 4844ae812b fix(apktool): own file and workspace finalization
Replace raw descriptor and workspace bookkeeping with artifact file ownership, canonical chunk reads, private roots and cleanup leases. Retain failed owners, fence replacement acquisition, release successful peers once, and preserve completed Evidence and physical failures through final cleanup and cancellation.

Use the shared directory reader and enforce the examined-entry budget before special-file omission. Keep command and artifact retry ownership separate by exact lease identity; remove superseded reads, implicit traversal and suppressing closes.

Validation: 163 focused tests in 20 files, build, typecheck/lint, docs and discovery passed. Six public controls fail on clean baseline 11bcf4425. Tiny FIFO, descriptor denial/retry, late allocation and mixed outcomes are controlled fixtures. Twenty-four completed CLI/stdio MCP comparisons return byte-identical replies; no speedup claim. Actual Apktool/JVM, natural OS denial and native Windows remain unverified; heavy stress/profiling stayed stopped.

Closes #4812
2026-10-17 22:36:51 +08:00
morluto 11bcf44252 fix(apktool): retain command cleanup ownership through recovery
Admit provider operations through one command resource scope, retain exact process and preparation-helper cleanup capabilities, and bind original failures to their live cleanup leases. Keep unknown recovery capabilities unresolved and fence their workspaces.

Interpret version output at command completion, preserve opaque cancellation and compiler output, and attribute prerequisite failures to the consuming operation. Prepare Darwin ownership outside the short version deadline.

Validation: 106 focused tests across 11 files; final 44 source regressions; build, typecheck/lint, docs and test discovery. Eight new controls fail on the clean baseline. Tiny authored launchers exercise process cleanup and public CLI/stdio MCP; actual Apktool/JVM and native Windows remain unverified. Heavy stress/profiling remained stopped.

Closes #4808
2026-10-17 22:22:47 +08:00
morlutoandJ0UH 376eeca770 fix(ghidra): prepare ownership before Java probe deadline
Allow independently bounded Darwin helper compilation to finish before the five-second Java deadline starts. Keep Linux process-table preparation under command supervision.

Share preparation failure translation between both stages so physical compiler outcomes, exact cancellation reasons and cleanup capabilities retain one owner. Adapt contributor PR #4795 and extend preparation handoff and retry controls.

Fixes #4793

Co-authored-by: J0UH <217747670+J0UH@users.noreply.github.com>
2026-10-17 22:06:16 +08:00
morluto f4322b15ed fix(javascript): bound semantic unknown retention at projection
Admit unknowns before canonical construction and provenance interning. Offer independent per-file and application capacities through CLI, Evidence and the owned analysis worker, and reject over-allocation during streamed decoding.

Report examined omitted emission occurrences by family and reason without retaining discarded identities. Preserve omission-free graph identities and distinguish node truncation from overall partial coverage.

Fixes #4797
2026-10-17 21:57:31 +08:00
morlutoandAniketXD 926e18b3fc fix(native): report PE resource subject architecture
Reuse the canonical COFF decoder and one optional-header magic rule. Preserve unknown architecture for conflicting headers and unproven managed OS overrides; assert subject parity through CLI and MCP.

Adapted from AniketR10/rea-aniket PR #4801 (250c9d726f), with expanded ARM and late-cancellation coverage.

Fixes #4800

Co-authored-by: AniketXD <aniketrawat826@gmail.com>
2026-10-17 21:44:54 +08:00
morluto e7df00e807 fix(electron): retain process and transport cleanup owners
Retain independent teardown leases, block capture admission until recovery, and preserve cancellation through failed finalization. Reuse pending close operations and require fresh Windows lineage plus passive family absence proof without cached descendant kills.

Fixes #4805
2026-10-17 21:40:46 +08:00
morlutoandhhang f9de41371f fix(electron): own fuse cleanup through adapters and shutdown
Adapt the prepared descriptor lifecycle repair from xu91102/rea dbb7db16. Bind exact file cleanup leases, retain typed physical failures and cancellation reasons, and join CLI/MCP finalization and active preflight. Share canonical Evidence construction and retain completed reports across reader handoff cancellation.

Scope active capture admission through shutdown and gate launch after close. Preserve successful descriptor peers and retry only unresolved owners. Separate process/transport retry ownership remains tracked in #4805.

Validation: 168 focused checks passed, one Windows-only skip; built CLI and actual stdio MCP controlled descriptor recovery; build, static and docs checks. No natural OS fault or real Electron launch/teardown claim. Ordinary full replies and Evidence IDs remain byte identical across 30 small CLI tasks.

Fixes #4658

Co-authored-by: hhang <169027046+xu91102@users.noreply.github.com>
2026-10-17 21:24:00 +08:00
2d84c800bc perf(android): filter class pages before bridge serialization (#4791)
Filter class names at the native owner before serialization, and resume matching pages through contiguous inventory positions without a second index or query-result cache. Preserve selected source Evidence, query identity, complete top-level coverage and shared CLI/MCP behavior.

Fixes #4776.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-17 13:21:37 +00:00
Ysopwnable 060eb43b54 docs: celebrate 300,000 GitHub stars 🎉 (#4778) 2026-10-17 21:12:16 +08:00
morlutoandKaoru0822 bf54c46264 fix(electron): share executable architecture facts for fuse inspection
Own ELF machine and canonical family in the fixed-header parser. Fuse inspection consumes validated ELF facts and complete COFF machine values while retaining null for unknown or incomplete headers. Binary target, MIPS and Go consumers reuse the parsed facts.

Adapt public CLI controls and fixture builders from #4788; extend x86, ELF byte order, malformed and unknown headers, MCP projection and byte preservation coverage. 430 focused tests passed, one Windows-only skip. Five authored inert fixtures have full actual CLI/stdio MCP Evidence parity; real Linux/Windows Electron apps remain unverified.

Fixes #4786

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-17 21:10:07 +08:00
Ysopwnable bd3210eb24 fix(ci): format keyed archive CLI regression test (#4796)
Apply the locked formatter to the keyed-archive CLI/MCP regression test. Preserve all assertions and runtime behavior.
2026-10-17 13:05:59 +00:00
morluto 22a0746f90 fix(wasm): retain cleanup ownership through WABT recovery
Bind runtime and descriptor cleanup to exact retry leases and retain command supervisors until stop is confirmed. Preserve primary errors, partial Evidence and finalization cancellation reasons.

Validate with 88 focused tests, official WABT 1.0.42 CLI/MCP verifier (51 cases), build, static and documentation checks. Command stop failures use controlled source seams; real permission failures and target execution are unverified.

Fixes #4787

Fixes #4798
2026-10-17 21:02:50 +08:00
morluto 7aa4b98c98 fix(plist): own XML values and numeric facts in one decoder
Interpret the validated, depth-bounded DOM directly. Collect source number
facts during the same traversal and share them with keyed archives, Interface
Builder and native plist projections. Remove the second XML parse, key aliases,
source-location rewriting and both duplicate XML numeric scanners. Preserve
character references, container/null behavior, safe own-property construction
and prototype omission accounting.

Decode signed hexadecimal integers and combine real text/CDATA. Retain exact
integer identity when a finite integer exceeds even Number's finite range,
using the shared scalar projector. Keep unsupported mixed integer syntax
conservative and report incomplete metadata.

Adapt @apitoagents's hexadecimal regression and literal-parsing proposal from
PR #3475. Native plutil controls establish the supported hex/real cases and
confirm that the synthetic 401-digit overflow case exceeds native bounds;
retaining accepted input does not claim native-format support.

Validation: 274 focused checks in 30 files pass, one skipped; build,
check:fast and docs:check pass. Built CLI/actual stdio MCP, native plist and
Interface Builder controls cover kinds, references, exact digits and digests.
Eight baseline checks fail; native binary conversion independently verifies
updated CDATA real expectations. 48 tiny completed CLI cost comparisons
preserve ordinary XML/binary and all three native replies byte for byte.
Two read-only reviews clear. No statistical speed claim, heavy profiler,
investigated-target execution or real deep-provider verification.

Fixes #3373
Fixes #4042
Fixes #4789
2026-10-17 20:40:55 +08:00
morluto 78cf6100f3 fix(plist): preserve complete XML dictionary key identities
Use the validated DOM's character-data key names for both identity and
prototype omission. Replace first-child reinterpretation with canonical,
collision-free aliases inside the pinned decoder boundary; restore names
through the existing dictionary projection. Alias every spelling of the
same name to preserve duplicate assignment order. Handle empty key spellings
and keep scalar key elements outside aliasing. Preserve value text and bytes.

Adapt @thangldw's tests and proposal from PR #3426. Avoid the proposal's
closing-content scanner and re-escaping source names. Add duplicate, empty,
alias-collision, scalar-key, native fallback and Interface Builder controls.

Validation: 180 focused checks across 20 files pass, including built CLI and
actual stdio MCP, build, check:fast and docs:check. Baseline public inspection
truncates main to ma. 24 tiny completed CLI cost controls preserve ordinary
XML/binary full replies and Evidence IDs byte for byte. No statistical speed
claim, heavy profiling, investigated-target or real deep-provider execution.

Fixes #3371
2026-10-17 20:28:01 +08:00
morluto 2cf9c28f27 fix(apple): preserve decoded keyed archive scalar identity
Move plist projection into the graph owner and identify generated scalar
wrappers by producer identity through every dictionary/UID consumer. Remove
the intermediate JSON clone that erased those facts. Literal wrapper-shaped
dictionaries remain dictionaries; scalar $top values fail as malformed.
Keep numeric projection after graph interpretation, preserve unknown counts,
and retain binary prototype-key partial facts with an explicit limitation.

Adapt @Jax367's relevant scalar proposal and public regression from PR #4317.
Add scalar-root, literal-root and binary prototype controls. Correct only
the captured Foundation data node expectation and its manifest digest;
original producer bytes and source are unchanged. Unrelated PR changes excluded.

Validation: 175 focused checks across 23 files pass, one skipped; build,
check:fast and docs:check pass. Public CLI and stdio MCP cover both encodings.
Baseline scalar controls fail; 24 tiny completed CLI cost comparisons retain
ordinary full replies and Evidence IDs byte for byte. No statistical speed
claim, heavy profiling, target execution or real deep-provider verification.

Fixes #4295
Fixes #4785
2026-10-17 20:20:53 +08:00
morluto 5d6029ea62 fix(apple): derive launchd domains from owning directories
Use the matched Contents/Library/LaunchAgents or LaunchDaemons suffix to
select a plist's domain. Remove the independent scan of every ancestor.
Keep regular-file, application-root, sidecar and suffix admission rules.

Adapt @bnkaiteam's proposal and ZIP boundary regression from PR #3504,
adding public CLI/stdio MCP controls for nested bundles, case variants,
misleading ancestors and excluded paths.

Validation: 53 focused checks, build, check:fast and docs:check pass.
Two new controls fail before the fix. 12 completed actual built CLI cost
controls preserve the ordinary reply and projection ID byte for byte.
No heavy profiling, target or real deep-provider execution; npm release
and whole-agent costs remain unverified.

Fixes #3353
2026-10-17 20:10:12 +08:00
morluto fc935d0df3 fix(mobile): derive runtime hints from classified components
Use the owning DEX/JVM and Ark/JavaScript component lists for runtime
summaries. Remove the independent filename checks and Harmony path copy.
Preserve native format checks and framework path conventions.

Adapt @eco-null's proposal and regressions from PR #3627. Cover all eight
supported source extensions and unrelated content, plus the Android
inverse mismatch discovered during consumer review: .dex/.class files
had no bytecode components but produced runtime hints.

Validation: 44 focused checks, build, check:fast and docs:check pass.
Six Harmony assertions and one Android built CLI assertion fail before
this fix. 36 actual built CLI cost controls preserve four ordinary
complete replies and projection IDs byte for byte. No heavy profiling,
target or real deep-provider execution; npm release unverified.

Fixes #3350
Fixes #4782
2026-10-17 20:02:26 +08:00
morluto a425b3e528 fix(mobile): classify authenticated file occurrences as components
Select file and slice identity once before Android, Apple and Harmony
classification. Keep directory/link facts in source inventory and Apple
anatomy rather than deriving code roles, runtime hints or bridges from them.
Preserve occurrence order, multiplicity and existing unavailable facts.

Adapt @flyl1u's proposal and public CLI/stdio MCP controls from PR #3830,
extending the controls and structural fix to Apple and slice/link semantics.

Validation: 80 focused checks, build, check:fast and docs:check pass.
Four package controls fail before the fix. 72 tiny completed source cost
tasks preserve all regular-file control replies and projection IDs byte
for byte. No heavy profiling, target or real deep-provider execution;
full agent/public-task costs and published npm package unverified.

Fixes #3349
2026-10-17 19:58:18 +08:00
morluto 149a0fc06c fix(apple): derive bundle anatomy from directory facts
Build separate directory and authenticated-file indexes before applying
anatomy name preferences. Share those facts across application roots,
nested bundles, layout, metadata, executable candidates and signing paths.
Remove mixed child-name interpretation and downstream membership repairs.

A leaf Contents/Versions resource no longer changes a shallow layout, and
leaf files/symlinks cannot manufacture application roots. Real explicit
and implied directories retain their existing semantics and spelling.

Adapt the directory-identity proposal and source regressions from PR #3505
by @bnkaiteam, extending it to metadata file selection and root admission.

Validation: 57 focused checks, build, check:fast and docs:check pass.
30 tiny completed source projection cost controls preserve ordinary deep
and versioned replies byte for byte. No real-provider/target execution,
heavy profiling or published npm verification.

Fixes #3359
Fixes #4779
2026-10-17 19:53:45 +08:00
morluto c192c58815 fix(apple): retain unavailable application components
Preserve unread file and slice facts before Apple attribution. Report partial
component coverage while keeping manifest count completeness independent.
Directories and symlinks retain their existing representation.

Consolidate occurrence identity interpretation and component schemas across
Apple, Android and Harmony; remove superseded producers. Android/Harmony
completed source replies and projection IDs remain byte-identical in controls.
Apple's additive unavailable_components field changes its projection IDs.

Adapt the unavailable-component proposal and real ZIP regressions from
PR #4692 by @rodricksz4h5, adding directory, CLI, MCP and non-encrypted controls.

Validation: 77 focused checks; check:fast; docs:check (5 README checks).
18 tiny completed source cost controls; no real-provider/target execution
or heavy profiling. Published npm package and large-input costs unverified.

Fixes #4688
2026-10-17 19:46:20 +08:00
e5ee3ac658 fix(apktool): preserve decoded APK Evidence subject (#4771)
Bind shared CLI/MCP Evidence to the digest already computed from the owned
APK snapshot. Exercise source mutation during decoding through the shared
application workflow and verify subject identity in the real Apktool lane.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-17 11:36:21 +00:00
morluto 969aafcf28 fix(ghidra): compare final DOS relocation windows
Adapt the correction and authored overlap control proposed by @berelels in #4156 to the bounded prepared-image owner. Retain each fixup's application facts, then read every memory window after all writes. Carry the producer's load segment into comparison and advance only the MZ evidence revision.

Validation: 129 focused parser/comparison/MCP checks, 38 shared MCP harness checks and 41 selected provider checks passed, with 15 checks overlapping those runs. Fourteen lifecycle checks also passed, plus static/build/docs checks. Two baseline controls failed before the correction. Twelve completed normal source comparisons retained byte-identical replies; no real Ghidra or maximal-relocation performance qualification is claimed.

Fixes #3981
2026-10-17 19:30:11 +08:00
Kaoru0822andClaude Opus 5.5 34239d445b fix(flutter): keep completed inspection facts when cancelled during snapshot cleanup (#4766)
FlutterBuildProvider.execute checks the caller signal after its awaited
snapshot-root removal. When the signal was aborted during a successful
first removal, that check replaced the completed AnalysisExecution with a
bare AnalysisCancelledError, so identify-flutter-build and
inspect-dart-aot reported a typed cancellation without
details.partial_observation and the shared CLI/MCP Evidence assembly
never saw the facts.

The post-cleanup check now keeps the caller's abort reason and retains a
completed result as the cancellation's partial observation. The Evidence
composition from executeProviderOperation moves into
createAnalysisExecutionEvidence beside the provider contract, so the
success path and the retained cancellation use one composer and carry
identical Evidence. Failed results keep their existing classification.

Fixes #4717

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:27:55 -07:00
Kaoru0822andClaude Opus 5.5 83d2780008 fix(ida): refuse universal Mach-O targets in attached profiles (#4765)
Attached IDA binds the open database to the target only through the
recorded whole-input SHA-256, path and image base. Every slice of a
universal Mach-O shares that digest, so an attached database of another
slice passed the identity check and its results were attributed to the
host-selected architecture. Attached admission now reports the target
format as unsupported, with lipo -thin and headless recovery, before any
upstream contact. Headless mode keeps thinning the selected slice.

Fixes #3871

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:27:46 -07:00
Kaoru0822andClaude Opus 5.5 8589b7e778 fix(evidence): verify staged output identity after its final write (#4764)
* fix(evidence): verify staged output identity after its final write

On macOS FAT32 and exFAT volumes an empty file reports a placeholder file
ID, and the first write assigns its cluster-derived ID. The staged JSON
writer sampled the descriptor identity right after exclusive creation, so
publication and cleanup both rejected REA's own staged file as replaced:
every export failed with cleanup_incomplete and retained a .rea-write-*
directory.

The staged output owner now observes the descriptor identity immediately
before closing it, after the last write, and uses that identity for the
publication and cleanup pathname checks. A failed observation leaves the
identity unknown, so cleanup still refuses pathname removal.

Fixes #4613

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

* test(evidence): cover failed final staged identity reads

Reject the staged descriptor's final stat and verify that the writer
still closes the descriptor, refuses publication, and retains the
unverified staged content with incomplete cleanup.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:27:38 -07:00
Kaoru0822andClaude Opus 5.5 63c530998e fix(flutter): report cancellation during snapshot cleanup with completed observations (#4762)
The one-shot Flutter CLI commands passed their command signal to the
inspection but not to finishAnalysisCommand, whose post-close cancellation
guard only runs when a signal is supplied. When the provider's first
snapshot-root removal failed, close() retried it after the inspection had
returned; SIGINT during that retry set exit status 130 while the command
still printed ordinary successful Evidence.

Pass the command signal to the finisher so an abort observed after the
awaited cleanup retry yields typed cancellation that retains the completed
Evidence as partial_observation. A failed retry still reports
cleanup_incomplete ahead of the later signal.

Fixes #4640

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:27:23 -07:00
Kaoru0822andClaude Opus 5.5 f03a55909d fix(mcp): accept authentic native Evidence for managed boundary verification (#4761)
The MCP verify_managed_native_boundaries handler resolved native
observations through an inspect_macho/analyze_function allowlist before
calling the shared verification service, and reported any other authentic
operation as evidence_integrity_mismatch. The domain already owns which
native operations it can read symbols from and counts the rest as
unsupported, which is what the CLI returns. The MCP resolver now only
authenticates native observations and leaves operation support to the
shared workflow, so both adapters return the same partial verification.

Fixes #4639

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:27:06 -07:00
Kaoru0822andClaude Opus 5.5 f1ab5959bd fix(javascript): bind response endpoints only from writes that reach the read (#4759)
collectResponseConsumers copied the linked request's endpoint onto a
response consumer whenever the receiver binding had exactly one
initializer (added in 0323ce0a2, #3822). A single initializer is a source
fact, not proof that the write reaches the read: an incoming parameter
that is overwritten only conditionally, or only after the read, still
lets the consumer read a caller-supplied response, yet it received the
request's exact endpoint.

The sole write now also has to cover the read, using the same rule the
call resolver applies to incoming values: either it is the binding's
stable unconditional declaration initializer, or the shared read-position
owner (semanticBindingAtRead) reports a definite preceding initializer.
Otherwise the endpoint stays null.

Fixes #4606

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:26:55 -07:00
Kaoru0822andClaude Opus 5.5 31c87b40ee fix(javascript): report oversized recovery inputs as file-size limits (#4757)
scanRecoveryFile raised a plain AnalysisOutputError when a selected file
exceeded the remaining operation-wide input allowance, and
snapshotRecoveryInput folded that, read failures and UTF-8 decode
failures into one invalid_value request issue. A 64 MiB + 1 input was
therefore reported as a retryable invalid argument whose only record of
the 67108864-byte budget was message text that also called it an
invalid analysis output, and malformed UTF-8 received the same reason.

The scanner now marks its byte-bound refusals with the bound it
enforced. snapshotRecoveryInput, which owns the meaning of that bound
as the remaining total input allowance, reports it as a non-retryable
file-size AnalysisResourceConstraintError with maximum_input_bytes and
remaining_input_bytes, and decodes UTF-8 separately as an invalid_format
issue. Other scanner consumers still receive an AnalysisOutputError, and
the limit stays enforced.

Fixes #4629

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:26:39 -07:00
Kaoru0822andClaude Opus 5.5 6a407619fe fix(javascript): report malformed runtime context events as excluded (#4755)
V8 Inspector capture counted an execution-context created or destroyed
event whose context ID was missing or not a safe integer as retained,
but recorded nothing about it. The capture counters claimed the event
was kept while the context list silently omitted it, and no unknown
identified the loss.

The producer that parses the event and owns the capture counters now
records an invalid-context count, mirroring the existing invalid-script
accounting. The projection reports a non-zero count as an explicit
unknown, so the retained count and the reported omission agree. No
context is invented from a malformed ID, and all-valid captures are
unchanged.

Fixes #4685

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:26:25 -07:00
Kaoru0822andClaude Opus 5.5 95b561f2e9 fix(native): retain Apple dispatch metadata descriptor cleanup ownership (#4745)
* fix(native): retain Apple dispatch metadata descriptor cleanup ownership

inspect_native_dispatch_metadata opened the target with raw
openRegularFile and closed it in a finally block, so a rejected close
replaced integrity, capacity or cancellation failures and left no owner
to retry. The read now uses the shared owned regular-file operation in a
client resource scope; the physical failure stays the cleanup primary,
client close retries the exact descriptor, and a confirmed release
clears the original error's cleanup uncertainty. Decoding runs after the
descriptor is released.

Fixes #4743

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

* fix(verify): give the Apple dispatch verifier an owned file scope

Pass an ArtifactResourceScope to inspectAppleDispatchMetadata and close
it after inspection so a failed descriptor close is retained and retried
rather than reaching an undefined scope.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 04:20:40 -07:00
morluto 2f9b9c48b8 fix(ghidra): stream DOS MZ overlay attestation
Keep initialized image facts and full source identity separate at the snapshot owner. Stream overlay bytes into original and modified digests, retain format-bounded image bytes, and consume prepared relocation/mapping facts. Preserve completed comparisons, exact cancellation and cleanup retry through descriptor finalization. Keep explicit source refusals as typed primary failures.

Validation: 119 focused parser/comparison/MCP checks, 40 selected provider checks and 14 lifecycle checks passed; static checks, runtime build, discovery and docs checks passed. Twelve small completed source comparisons retained byte-identical full replies. Real Ghidra, large input and full public CLI/MCP performance remain unverified. The separate overlap timing issue #3981 remains open.

Fixes #4770
2026-10-17 19:18:34 +08:00
morluto 3fc007534b fix(native): validate NativeAOT PE virtual ownership
Reject contradictory headers, overlapping virtual sections, DOS header reuse and image intervals outside the 64-bit address domain before metadata interpretation. Preserve empty and adjacent ranges, source section order, and raw padding semantics. Advance the metadata profile revision and retain provider snapshot refusal facts.

Validation: 37 parser checks and 35 selected provider checks passed; check:fast and build:cached passed. Six tiny authored-fixture summary/detail tasks returned byte-identical 791-token replies. No real-engine or Windows loader qualification.

Fixes #4763
2026-10-17 19:02:29 +08:00
morluto 9c56d09c05 fix(ghidra): preserve load-image completion through cancellation
Consume the named inventory observation once and compare typed facts through one final cancellation check. Retain measured or completed load-image facts and exact reasons, preserve source partials and cleanup, and remove duplicate interpretation and format-specific abort guards.

Validation: 131 contract/projection checks, 40 selected provider checks, and 24 selected private-file/socket lifecycle checks pass; typecheck, lint and builds pass. Includes the original confirmed descriptor-close boundary and late result consumption. Tiny authored fixtures and simulated installation/engine facts; no real Ghidra, investigated target or heavy profiling.

Equivalent completed DOS/raw/NativeAOT tasks retain byte-identical full replies and one source read. First processes and two alternating warm repeats; no statistically established performance improvement.

Fixes #3977
2026-10-17 18:52:42 +08:00
morluto a43ce8a98f fix(ghidra): retain measured facts through NativeAOT failures
Attach each caller’s measured observations before source failure and cleanup projection. Preserve those facts through admission, peer and draining cancellation, cached results, cleanup fences and later lease resolution.

Validation: selected NativeAOT provider controls and typecheck/lint passed in the load-image audit tree. Related consumer validation follows in the next commit.

Refs #3977, #4753
2026-10-17 18:52:42 +08:00
ae029fe2f8 perf(ghidra): aggregate binary overview at the provider boundary (#4754)
Compute overview counts at the Ghidra inventory owner, preserve complete inventory access and coverage, and share CLI/MCP projection. Keep native aggregate Evidence separate from workflow snapshot identities.

Fixes #4746

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-17 10:44:24 +00:00
morluto 5120eb4412 fix(ghidra): join shared NativeAOT derivation and retain outcomes
Replace the private promise race with a named snapshot owner using SharedStartupAttempt. Keep peers independent, stop and join final departure, preserve source failures and completed facts through draining waits, and fence replacement behind retained cleanup. Close joins derivation before releasing the underlying client.

Validation: 31 selected simulated-provider lifecycle and NativeAOT checks, 80 shared-contract/schema/projection checks, typecheck, lint and builds. Completed tiny summary/detail/close comparison preserves full replies and one snapshot read. No real Ghidra, investigated target or heavy profiler execution.

Refs #4753
2026-10-17 18:37:57 +08:00
Ysopwnableandabdooo2235 f0d175dace fix(verifiers): read packed bridge without extraction
Parse only the exact regular packed Python bridge member without extracting into the caller-owned private runtime root. Preserve required Ghidra admission, typed callers, native lease ownership and cleanup on success or failure.

Validation: 263 focused real tar/Python/ownership and CI selection checks, 42 official WABT packaged CLI/MCP cases, full check:ci/check:fast/actionlint, real-package alternating measurements and exact-head hosted CI passed. The required Windows lane exercises the retained native lease without skipping missing authority.

Fixes #4134.

Co-authored-by: abdooo2235 <abdalrhmantheiv15@gmail.com>
2026-10-17 10:35:31 +00:00
morluto 73965f9431 fix(ghidra): retain snapshot outcomes and join reader cleanup
Use the shared artifact resource scope for snapshot reads. Preserve completed facts, exact cancellation reasons and descriptor cleanup leases through session and public error projection; keep parent cleanup pending until all retained resources release.

Validation: 22 selected snapshot lifecycle checks and 85 contract, projection and bounded-reader checks; typecheck, lint and runtime builds. Uses small authored Node/socket fixtures, not real Ghidra or investigated target execution.

Refs #4752, #3977
2026-10-17 18:25:59 +08:00
morluto 5e13e0a876 refactor(files): allow reader-owned cancellation failures 2026-10-17 18:25:52 +08:00
morluto 4a076f368c fix(native): bound NativeAOT reads to declared PE headers
Validate the consumed optional-header extent before interpreting mapping fields. Require complete header-backed read intervals and prevent failed header reads from falling through to section mappings. Advance NativeAOT profile interpretation identity to v4.

Refs #4750
2026-10-17 18:07:29 +08:00
morluto d9099190ab fix(native)!: retain UI outcomes through finalization
Carry caller and runtime deadline cancellation through helper cleanup, preserve command-owner reasons and physical failures, and retain collected scenario reports with typed terminal errors.

BREAKING CHANGE: failed or cancelled native UI scenarios now return typed errors with the collected report in partial_observation instead of successful reports containing failed or cancelled steps.

Refs #4227
2026-10-17 17:57:50 +08:00
morluto 04221e5f01 fix(native): bind UI runtime cleanup to exact owners
Join admitted helper work before runtime removal, retain one preparation outcome and root, and bind originating and retry errors to exact runtime release leases with live resources.

Refs #4227
2026-10-17 17:57:50 +08:00
Ysopwnable 2092f90b7e perf(ci): upload only current portable build cache entries
Stage only the current portable Turbo task archives, metadata and available manifests for same-run artifact consumers. Share task identity/hash validation with cross-run keys and fail publication on incomplete preparation, while retaining existing cache authority and consumer build/prepack verification.

Validation: 252 focused tests, full check:ci, docs:check, check:fast, actionlint, real Turbo output equivalence and invalidation, restored CLI/MCP scenarios and full Linux package verification passed. Fault injection detected historical-entry inclusion. Exact-head hosted CI and available review passed; measurement limits are recorded in the PR.

Refs #4744.
2026-10-17 09:44:11 +00:00
morluto 0f7fd005db fix(native): retain LLDB readback ownership through cleanup
Own journal, capture, result and PID descriptors through confirmed release. Preserve parsed facts and exact cancellation reasons while retaining unresolved children and gating runtime removal on their completion.

Refs #4742
2026-10-17 17:40:49 +08:00
gongfppandgongfpp 5a7e8a166a fix(mcp): normalize browser scenario input errors (#4661)
Co-authored-by: gongfpp <22683417+gongfpp@users.noreply.github.com>
2026-10-17 17:36:32 +08:00
gongfppandgongfpp 9534e42ec8 fix(adb): mark unknown permission coverage partial (#4663)
fix(adb): mark unknown package coverage partial

Co-authored-by: gongfpp <22683417+gongfpp@users.noreply.github.com>
2026-10-17 17:36:19 +08:00
6b27d8f4e3 fix(electron): retain fuse descriptor ownership through failed final close (#4668)
* fix(electron): retain fuse descriptor ownership through failed final close

Static Electron fuse inspection admitted a file descriptor and closed it
in a bare finally: a rejecting final close() replaced the in-flight read
error, was classified by errno (e.g. EACCES) as a read permission failure,
and silently dropped ownership of the still-live descriptor.

Route the read through withOwnedRegularFile so a failed close keeps its
exact owner, preserves the primary error in the outcome, and surfaces as
RegularFileCleanupFailure. The provider now maps that to a primary error
with its own classification plus a ProviderCleanupError reporting
incomplete cleanup, instead of an access-denied read failure.

Regression tests fault close() (EACCES) with and without a primary read
error (EIO): both fail on the pre-fix revision and pass with the fix.

Fixes #4658

* fix(electron): keep cleanup report and partial evidence through cancel and successful reads

Address automated review on #4668:

- Handle RegularFileCleanupFailure before the cancellation check in
  failureFor: a cancelled operation whose final close rejects now reports a
  typed cancellation composed with the incomplete-cleanup error, instead of a
  bare AnalysisCancelledError that silently dropped the descriptor owner.
- Attach the completed fuse image as an explicitly partial Evidence
  observation when only the final close fails, instead of discarding the
  successful read. The abort-after-completion path keeps the same evidence on
  the composed cancellation error.
- Add provider-level regression tests: combined read+close faults, abort
  synchronized with the faulted close boundary, and partial-observation
  retention. Abort-during-close and partial-evidence tests fail pre-fix.

29/29 electron tests green; npm run check:fast clean.

---------

Co-authored-by: nosmile99 <nosmile99@users.noreply.github.com>
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
2026-10-17 17:36:06 +08:00
Oke Iyanuoluwa EnochandClaude Opus 5.5 f85a932d71 test(paths): pin Windows separator normalization before native admission (#4733)
rea-agents 6.5.0 passed an absolute caller path to Windows native
snapshot admission verbatim, so a spelling with forward slashes or
repeated separators reached the native component walker, which rejects
empty components as "Ambiguous Windows path component is unsupported"
(Win32 50). Current main already resolves every Windows caller path with
win32.resolve (fc791bb60), which collapses those spellings.

Pin that boundary: absoluteCallerPath normalizes four separator spellings
of one absolute Windows path, and on Windows parseBinaryTarget returns the
same canonical sourcePath for each of them. The Windows test fails when
the 6.5.0 verbatim-absolute-path rule is restored.

Fixes #4707

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 17:14:16 +08:00
morluto 69e670d268 fix(native): own call preflight hashing through client close
Reuse stable-file hashing and exact cleanup leases for target verification, join admitted call workflows before tracer close, and block replacement work while descriptor cleanup remains unresolved. Preserve physical failures, exact cancellation reasons and completed call facts; remove the duplicate reader and AbortError-name heuristic.

Validate real inert-file cleanup controls and controlled tracers through provider and MCP boundaries. No LLDB execution, real OS close-failure or Windows qualification.

Refs #4740
2026-10-17 17:12:39 +08:00
Ysopwnable 9d5b931875 perf(tests): reuse MCP connections within source matrices
Reuse test-owned stdio MCP connections within two stateless source-analysis matrices while retaining every original CLI/MCP scenario, schema/Evidence checks and test-finished cleanup. Add cross-input identity controls.

Validation: 23 focused public-workflow tests and complete check:ci passed; stale-response fault detected. Exact-head hosted CI and available review passed. Pinned workload measurements and their limits are recorded in the PR.

Refs #4737.
2026-10-17 09:11:22 +00:00
morluto 715c9c8a84 fix(native): retain signature facts through finalization cancellation
Bind signature inspection to its named domain result and retain completed facts in typed cancellation. Check cancellation after descriptor and root finalization, preserve exact caller reasons, and keep physical failures primary. Use explicit cancellation checkpoints instead of signal-state guesses.

Validate root and descriptor cleanup, retries, late root handoff, opaque reasons, provider projections, and existing real codesign/CLI controls. No real OS close-failure or Windows qualification.

Refs #4735
2026-10-17 17:01:21 +08:00
morluto 4f3b573b09 fix(native): bind signature snapshot cleanup to exact leases
Retain roots and descriptors through shared cleanup leases and bind composed errors to their actual pending owners. Successful retries shrink live attribution and reveal the original typed failure.

Validate mixed root and descriptor failures, partial/final release, existing target binding, and real codesign and CLI controls. No real OS close-failure or Windows qualification.

Refs #4734
2026-10-17 16:52:28 +08:00
morluto e09a503f44 fix(native): retain plist descriptor cleanup ownership
Use shared owned file operations for plist admission and source probes. Join admitted work during close, retain exact descriptor leases through retries, and preserve physical failures, cancellation reasons and completed converter output.

Validate with controlled cleanup faults and native plist CLI workflows on inert data. Real OS close-failure incidence and Windows behavior remain unverified.

Refs #4723
2026-10-17 16:43:14 +08:00
morluto 26bb85c007 fix(core): keep released cleanup dependencies empty
Distinguish unbound resource attribution from a completed dependency set so final release cannot restore historical resource names.

Refs #4578
2026-10-17 16:43:14 +08:00
9744d07211 docs(skills): capture measured analysis optimization workflow
Add a reusable contributor workflow for locating analysis bottlenecks, preserving Evidence and cache ownership, and comparing equivalent real tasks. Keep pinned Kuna results and experimental limits in an optional case study.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
2026-10-17 08:33:18 +00:00
ShuaixinHuang a040533470 fix(ghidra): reject byte matches outside searched coverage (#4531)
* fix(ghidra): reject byte matches outside searched coverage

* test(ghidra): cover inclusive and overlay byte match bounds

* test(firmware): assert composed cleanup error evidence

* test(ghidra): assert cancellation during profile shutdown

* test(jeb): retain Linux ownership prerequisite in isolation
2026-10-17 16:18:18 +08:00
ShuaixinHuang abe49808b2 fix(plist): ignore inherited XML entity lookup properties (#4530)
* fix(plist): ignore inherited XML entity lookup properties

* test(firmware): assert composed cleanup error evidence

* test(ghidra): assert cancellation during profile shutdown

* test(jeb): retain Linux ownership prerequisite in isolation
2026-10-17 16:17:53 +08:00
morluto 70de702109 fix(browser): share DOM snapshot admission
Own decoded node columns, attributes and parent validity once for web, Electron and SVG interpretation. Reject dangling, self and cyclic parent facts; preserve source positions and independently unknown fields. Remove fallback conversions and duplicated string/attribute interpretation.

Validation: baseline public CLI controls failed for four malformed cases with valid control passing; final 103 focused checks, 5 final built CLI controls, 1 late-detach cancellation control (20 skipped), check:fast and docs:check passed. Fake CDP producers and generated local files; no real browser/Electron or Windows qualification.

Refs #4709
2026-10-17 15:59:57 +08:00
4e14452ddb fix(native): report unidentified text plists as unknown (#4320)
* fix(native): report unidentified text plists as unknown

Require explicit XML identification in file output instead of treating all
text as XML. Preserve decoded plist values and source-format provenance
when plutil falls back to XML conversion.

Add provider-boundary regressions and real macOS CLI controls for OpenStep,
data-bearing OpenStep, XML, UTF-16 XML and binary property lists.

Fixes #4294

* fix(native): keep XML plists without a declaration labeled xml

`file -b` names XML only when a document declaration is present, so the
narrowed `\bXML\b` check reported a declaration-less XML plist as unknown and
broke the real-plutil `decodes xml plists that plutil cannot express as JSON`
CLI test. When `file` reports only text, read the source head once and label it
XML only when its first non-whitespace character (after a UTF-8 BOM) is `<`;
OpenStep and other text stay unknown.

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

* fix(native): distinguish OpenStep data from XML source markup

Recognize XML markup instead of treating every leading angle bracket as XML.
Keep data-only OpenStep sources unknown, honor explicit JSON identification,
and decode BOM-marked UTF-16 prefixes before detecting declarationless XML.
Add source-format regressions and macOS CLI cases for data-only sources.

---------

Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:52:25 +08:00
星闌 de9371b85d fix(javascript): preserve effective child-process stdio options (#4336)
* fix(javascript): preserve effective child-process stdio options

* fix(javascript): retain proven callbacks and primitive stdio keys

* fix(javascript): preserve argv shapes and nullish spreads

* fix(javascript): bound callable proofs and retain exposed binding uncertainty

* test(javascript): keep callback acceptance within transport budget

* test(javascript): inspect application coverage for callback proof limits

* fix(javascript): keep spread command argument slots uncertain

* fix(javascript): bound mapped argument content proofs

* fix(javascript): distinguish erased declarations from runtime shadows

* fix(javascript): prove runtime module context before binding isolation

* fix(javascript): share erased declaration and opaque scope proofs

* fix(javascript): keep lowered enum scopes opaque

* fix(javascript): narrow stdio proofs and consolidate regressions

* perf(javascript): reuse lexical references for child shapes

* fix(javascript): retain CommonJS child argument context

* fix(javascript): keep Annex B affected child arguments unknown

* fix(javascript): recognize value import-equals runtime modules

* fix(javascript): retain exact stdio through module and primitive syntax

* fix(javascript): bound inline spread property resolution

* fix(javascript): distinguish copied methods from getters
2026-10-17 15:51:55 +08:00
郭立 Guo Li 0cd4eafd61 perf: reduce MCP launcher and browser capture overhead (#4350)
* perf(browser): 为单次捕获复用脚本资源索引

* docs(setup): 说明多会话直接启动以减少 npm 驻留
2026-10-17 15:51:23 +08:00
Tapraj-PathakandCopilot 509d4c8f56 Fix permissions count issue for pkg=null in ADB analysis and add test cases (#4665)
* Fix permissions count issue for `pkg=null` in ADB analysis and add test cases

* fix(adb): handle null package permission counts

Recognize pkg=null as unknown permission data and keep the provider projection aligned with the parser. Add regression coverage for the parser and provider.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-17 15:45:15 +08:00
morluto 79d2b71896 fix(electron): preserve unknown resource sizes
Use one typed CDP resource-size owner in web and Electron capture. Supplied invalid sizes retain null plus completeness diagnostics; omitted sizes remain unknown without inventing malformed metadata. Preserve other resource facts and valid zero/positive values.

Validation: public CLI regression failed against baseline clamping; 36 focused controls passed after the fix, check:fast and docs:check passed. Fake CDP producer with real CLI/transport and tiny local files; no real Electron/browser or heavy profiling qualification.

Refs #4708
2026-10-17 15:41:07 +08:00
Kaoru0822andClaude Opus 5.5 9be493880c fix(kuna): name the setting that owns a timed-out Kuna run (#4343)
* fix(kuna): name the setting that owns a timed-out Kuna run

A Kuna run past its deadline surfaced the generic "Analysis took too
long. Try a smaller request" message. The request is already one
function or one whole-program scan, and the same run takes as long
again, so the advice was wrong and REA_KUNA_TIMEOUT_MS or
REA_KUNA_PROJECT_TIMEOUT_MS was never mentioned.

Each Kuna command now carries a KunaDeadline: the configured
milliseconds and the setting that owns them, from KunaConfiguration.
A timeout reports, for example, "kuna decompile did not finish within
REA_KUNA_TIMEOUT_MS (120000 ms)." Its remediation says to raise that
setting and restart REA, and for a single-function decompile that the
session's project export can still answer. AnalysisTimeoutError now
accepts a producer message and remediation, which projection uses and
per-waiter scan errors keep.

Refs #1957

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

* docs(kuna): scope the provider_timeout statement to direct Kuna runs

A timed-out project export is reported through the export failure as
capability_unavailable, not provider_timeout.

Refs #1957

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

* fix(kuna): verify native xrefs under the project deadline

The provider's xrefs scan runs under REA_KUNA_PROJECT_TIMEOUT_MS, but the
native oracle in verify:kuna aborted at REA_KUNA_TIMEOUT_MS. A scan that
fit the project deadline but not the function deadline failed
verification although the provider answered it. Use the same deadline.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 00:38:16 -07:00
morluto 748ac7f0df fix(sqlite): preserve column identity before row selection
Read raw column metadata through the built-in PRAGMA in the private empty temp schema. Validate bytes before names become SQL identifiers, and select inventory subsets by exact encoded identity so unrelated malformed names cannot alias valid columns.

Validation: 5 focused identity controls; 15 selected producer/provider controls (33 skipped); public CLI baseline collision, fixed format refusal and valid-subset success; check:fast and docs:check. Generated inert SQLite fixtures on macOS arm64 with Node 24.18.0; no Windows qualification or large-file/stress workload.

Refs #4710
2026-10-17 15:33:59 +08:00
Saim ShafiqueandSaim Shafique 77c8a1ba32 fix(javascript): mark resource-skipped files parse_status skipped (#3852)
* fix(javascript): mark resource-skipped files parse_status skipped

Files above ~5 MB exhaust the worker heap during static analysis (or exceed
the 8 MB static-checkpoint budget with a larger heap). They were inventoried
with text included but never parsed, leaving parse_status null and no
counter, so the summary read as 'nothing there' instead of 'not analyzed'.

Report them as skipped: parse_status 'skipped' on the file observation and a
skipped_javascript_files statistics counter. The analysis-failure reason keeps
surfacing as a limitation entry.

Fixes #3670

* fix(javascript): default skipped_javascript_files when reading old saved evidence

Saved analysis evidence written before skipped_javascript_files existed failed validation against the strict reconstruction statistics schema, so users could not reuse old results for comparisons or runtime reconciliation. Accept the field's absence on read (defaulting to 0) while continuing to write it for new results.

* fix(javascript): preserve unknown skipped count for legacy evidence

The .default(0) gate fix fabricated a measured zero for saved
pre-change evidence, so comparisons would receive a definitive
"no files skipped" fact the producer never established. Use the
codebase's exactOptional idiom instead: legacy reads accept absence
and keep omission (unknown), while the producer still always writes
the field (required by JavaScriptArtifactReconstructionResult).

Tests: legacy payload now asserts the key stays absent/undefined;
current-output test keeps asserting the producer-written counter.

* fix(javascript): add required failure scope and status to graph fixture

---------

Co-authored-by: Saim Shafique <sx4im@users.noreply.github.com>
2026-10-17 16:33:41 +09:00
Mohamed Ayoub Eleuch 8a2a1a2b8b fix(cutter): preserve mixed Unicode output within the frame limit
Count real UTF-8 bytes in bounded chunks and retain authenticated omission for malformed Unicode. Preserve existing wire/resource limits and completion semantics.

Validation: producer/client regressions, fresh real Linux Cutter CLI/MCP output and Evidence recovery, and complete exact-head CI passed. Hosted unrelated CLI timeout and unchanged rerun results remain recorded in the PR.

Fixes #3330.
2026-10-17 07:30:30 +00:00
morluto c7e9e096d3 fix(plist): reject malformed XML before value decoding
Reuse the shared validated XML document for depth and prototype-key preflight, preventing recovery-only values from being projected as observations. Preserve OpenStep and valid XML source semantics.

Validation: 46 focused checks; 5 final syntax controls; 10 encoding and public CLI/MCP overlap checks; check:fast. Public malformed-entity CLI changed from success to typed format failure. Generated inert artifacts only; no real Apple application or native engine execution.

Refs #4714
2026-10-17 15:24:57 +08:00
Aditya kharmale 8c62a4aa36 fix(javascript): preserve case-sensitive Unicode seed identity
Use NFC for case-sensitive feature seeds while preserving the existing explicit insensitive compatibility fold.

Validation: exact/substring/absent controls, fresh public CLI/MCP workflows and complete exact-head CI passed. Hosted CLI-worker failure and unchanged rerun results remain recorded in the PR.

Fixes #3314.
2026-10-17 07:20:34 +00:00
morluto 3cfa00a29c fix(ghidra): preserve valid Unicode language metadata
Validate XML bytes before shared syntax parsing so literal U+FFFD remains valid while malformed bytes and declaration mismatches fail at their producing boundary.

Validation: 92 focused checks, 3 selected fake Apktool boundary checks, 6 final encoding controls, check:fast and docs:check. Ghidra coverage uses tiny real files and descriptors, without a real engine or Windows qualification.

Refs #4712
2026-10-17 15:17:03 +08:00
morluto 623339a7ab refactor(xml): centralize strict document parsing
Own syntax validation and source-located DOM projection together. Preserve explicit consumer policies and remove duplicated warning-message filters from Apktool and SAZ.

Validation: 92 focused checks, 3 selected fake Apktool boundary checks, check:fast and docs:check. No real Apktool or Ghidra execution.

Refs #4694
2026-10-17 15:16:24 +08:00
Kshitiz Jain c0b3cd14b1 fix(javascript): exclude class member keys from lexical reads
Classify noncomputed class member keys and private names at the shared reference owner, avoiding false reads and closure captures. Preserve computed keys and initializer/body reads.

Validation: regression controls, fresh public CLI/MCP workflows and complete exact-head CI passed.

Fixes #3310.
2026-10-17 07:11:19 +00:00
siegfly 195cf18818 docs(native): distinguish analysis memory from source bytes
Document initialized Ghidra analysis-memory bytes, source mappings and incomplete coverage. Retain the portable test-owned alternate ELF for liveness cancellation.

Validation: fresh docs:check and complete exact-head CI passed. Historical real Ghidra checks remain explicitly attributed to their recorded revision/platform in the PR.

Refs #3075.
2026-10-17 07:11:10 +00:00
keeponlight e26bb49a4b fix(managed): avoid duplicate decode budget charging on cached metadata strings
Charge each immutable metadata heap string decode once; keep unique-string and per-occurrence projection accounting bounded.

Validation: focused capacity regressions, fresh real .NET DLL CLI/MCP workflows and complete exact-head CI passed. Before/after measurements and their limits are recorded in the PR.

Fixes #3449.
2026-10-17 07:10:58 +00:00
Sua Choi 326c073880 fix(apktool): preserve valid replacement characters in decoded XML (#4697) 2026-10-17 15:09:14 +08:00
Ysopwnable c6b62754b0 perf(kuna): reuse sorted string inventory for exact lookups
Reuse the validated string inventory's numeric address order for O(log n + matches) exact reads, preserving every encoding at the selected address without a second lookup index. Keep streaming validation, session cache lifetime, full listings, provenance and caller choices.

Validation: complete latest-head CI passed. Original real Kuna 1.833 Linux correctness and warm-lookup measurements remain pinned to their recorded feature revisions in the PR. The latest local 300 ms export-deadline observation and unchanged 31-test provider recheck are explicitly documented there; no assertion or timeout was weakened.

Refs #4695.
2026-10-17 07:04:16 +00:00
morluto 264799b0ff fix(kuna): retain workspace rollback failures
Compose failed rollback with the original target or read failure, bind it to the exact workspace lease, and retain the failed attempt while cleanup remains unresolved. Remove the silent release wrapper and duplicate exception wrapping; keep clean failures retryable and unknown causes opaque.

Refs: #4704
2026-10-17 14:56:01 +08:00
Ysopwnable 5b24399387 test(kuna): preserve caller and producer graph failure context
Align malformed call-graph retry assertions with caller-attributed errors while retaining the parser operation in diagnostics and the cause. Keep all malformed shapes, corrected-response retry, exact native-command count and owned-client cleanup coverage.

Validation: clean main reproduces 3 failed / 14 passed; corrected complete Kuna boundary selection passes 266 tests across 26 files; full check:ci and complete current-head CI passed. Greptile 5/5; human owner reviewed the diff/evidence and explicitly declared readiness. Codex review remains unavailable due repository usage limits. Test-only; no production/schema/authority change or real-engine qualification.

Fixes #4701.
2026-10-17 06:47:06 +00:00
morluto 5927937179 fix(kuna): preserve cancellation and cleanup ownership
Reuse shared startup ownership for query waits and preserve opaque cancellation reasons, captured command facts and typed primary failures. Bind retained command errors to exact process and workspace leases; share close attempts and update earlier caller and aggregate errors after cleanup retry.

Refs: #4700, #4702
2026-10-17 14:38:50 +08:00
morluto 988494abdb fix(kuna): own cancellable installation startup
Reuse the shared startup owner for independent caller waits, final departure cleanup, and session closure. Carry the producer signal through version probing and fingerprint finalization. Retry cleanly cancelled acquisition after settlement while retaining authored failures and exact descriptor cleanup dependencies.

Refs: #4698
2026-10-17 14:23:17 +08:00
Ysopwnable 3c9b5d6d02 test(ci): align fixtures with runtime and evidence contracts
Restore test fixture runtime prerequisites and align assertions with current Evidence and uncertainty contracts. Separate actual CLI publisher refusal from explicitly admitted Hopper socket/CLI fixtures, retaining exact wire identity and cleanup coverage. Validate retained EVM Evidence against exact unchanged source-carrier bytes.

Validation: 88 targeted local test passes across three completed selections, two platform skips, full check:ci; hosted Windows probes and complete current-head CI. No production authority, authentication or schema change. Controlled fixtures do not qualify actual disassemblers or workers.

Fixes #4690.
2026-10-17 06:20:23 +00:00
morluto 54c71313ae fix(kuna): attribute inventory failures to callers
Normalize shared installation and inventory failures at the session boundary, retaining producer operation metadata. Preserve exact cancellation reasons before admission and while waiting without adopting foreign cleanup authority.

Refs: #4689
2026-10-17 14:13:25 +08:00
morluto 6eb55be4e8 fix(kuna): preserve live cleanup in caller failures
Reuse canonical typed failure attribution instead of copying cleanup markers. Preserve captured facts, typed primary outcomes and opaque cancellation reasons; bind caller projections to the exact producer cleanup owner.

Refs: #4693
2026-10-17 14:13:16 +08:00
morluto 5717ad24aa fix(kuna): attribute installation failures to caller operations
Project the immutable shared installation failure through the existing authored-failure normalizer for each requesting operation. Preserve direct health identity, diagnostics, retryability and live cleanup dependencies.

Validation: ten baseline/candidate public CLI cases each; nineteen focused boundary checks plus four overlapping final cleanup controls, check:fast and docs:check passed. Concurrent callers share one acquisition failure without mutating its producer. No real Kuna, Windows, MCP-specific failure replay or performance measurement. Refs #4631.
2026-10-17 13:49:27 +08:00
morluto d09be9cfa2 docs(browser): clarify scenario cleanup after termination
Document retained profile data, missing-executable Playwright artifacts, platform cancellation differences and the absence of later reclamation. Keep recovery work tracked in #4659.

Confirmed installed Playwright 1.58.2 preparation order and one public CLI missing-executable reproduction in a private fixture; an empty artifacts directory remained and was removed only with the owned experiment root. Forced termination was not rerun. docs:check passed.
2026-10-17 13:49:20 +08:00
morluto 7086768a27 fix(adb): preserve display-scoped window focus declarations
Retain every focus declaration with its display header and identity, including explicit absence, unknown identities and duplicates. Derive singular summaries only for one unambiguous context; preserve scope and ambiguity through named CLI/MCP contracts.

Validation: original public CLI replay before/after, four failing baseline parser controls, 23 focused checks plus 11 overlapping provider/parser controls, converted MCP schemas, check:fast and docs:check. Bounded completed synthetic CLI warm reply tokens 282/513, elapsed 0.391/0.403s and CPU 0.622/0.622s; no efficiency claim. No live Android, vendor or large-output qualification. Refs #4660.
2026-10-17 13:40:09 +08:00
morluto be0b2d138c fix(adb): scope package uninstall requests to user zero
Send shell pm uninstall --user 0 through the shared quoted command boundary. Align tool guidance and Evidence limitations with the selected request scope while preserving device refusal diagnostics.

Validation: two provider controls failed before the fix and pass afterward; three public CLI/MCP scenarios capture exact arguments and equivalent success facts; nineteen command/SDK contract checks, check:fast and docs:check pass. No real device, multi-user data preservation, vendor/APEX behavior or performance measurement. Refs #4673.
2026-10-17 13:30:29 +08:00
morluto c360cfcd6d fix(browser): parse complete COOP and COEP structured items
Validate token items and their parameters before projecting exact declared policy tokens. Keep malformed and non-token values unknown; retain separate grammar for other policy headers.

Validation: real pinned Chrome public CLI baseline/candidate, 101 focused checks and 90 overlapping final checks, 834 upstream item-vector adaptations with two permitted refusals, check:fast and docs:check. Other browser/platform and policy-specific MCP delivery unverified; no performance measurement. Refs #4677.
2026-10-17 13:26:13 +08:00
morluto df2fc251e3 fix(browser): preserve repeated document Link fields
Parse CDP repeated field lines independently before applying URI and quoted-parameter delimiters. Preserve declaration order and derive agent hints from retained links.

Validation: real pinned Chrome public CLI baseline and candidate each captured three responses per fixture; repeated Document links/hints restored and comma/single/Fetch controls unchanged. Three source controls failed before the fix. Sixty-one focused checks plus fifteen overlapping final network checks, check:fast and docs:check passed. No performance measurement or other browser/platform claim. Refs #4679.
2026-10-17 13:21:50 +08:00
morluto 0ec4826633 fix(evm): preserve command owner cancellation reasons
Copy the exact opaque reason already recorded by OwnedCommand rather than discarding it at EVM failure conversion. Keep physical, timeout and incomplete cleanup outcomes distinct.

Validation: direct compiled probe and eight source controls; four reason controls failed before the fix. Twenty-one overlapping service/adapter checks, check:fast and docs:check passed. No real Linux x64 worker cancellation or public delivery exercised. Refs #4686.
2026-10-17 13:18:05 +08:00
morluto d694aef227 fix(evm): retain completed evidence through cleanup cancellation
Share validated interface Evidence assembly across success, cleanup failure and late cancellation. Preserve exact admission and completion abort reasons.

Validation: 26 service, MCP and host-refusal checks passed; check:fast passed. Thirty Linux x64 provider checks skipped on Darwin arm64, including expanded root-removal controls. Linux real-worker and public SIGINT reproduction remain unverified; no performance measurement. Refs #4683.
2026-10-17 13:16:40 +08:00
morluto 5853089885 fix(hopper): retain search failure context and cleanup ownership
Attribute regex inventory failures to the accepted search operation while retaining wire identity, typed outcomes, captured facts and live cleanup dependencies. Preserve exact cancellation reasons at inventory and progress completion.

Validated with focused source, socket-boundary and public CLI fixtures, existing MCP contract checks, check:fast and docs:check. Simulated Hopper only; real-engine behavior and performance costs remain unmeasured. Refs #4680.
2026-10-17 13:12:43 +08:00
morluto 4d980d0176 fix(javascript): preserve unresolved version relationships
Keep positive topology differences separate from unpaired neighbor identity. Preserve exact content pairing and source observations, report unresolved relationships without inventing incomplete inventory, and omit comparison edges when no substantive difference was observed.

Validated with 45 focused domain/CLI/MCP tests, nine expanded domain controls, check:fast, and docs:check. Clean baseline fails seven controls and passes two positive controls. Controlled static fixtures only; no target execution or large-bundle profiling.

Refs #4681
2026-10-17 12:51:04 +08:00
morluto 556504edcb fix(javascript): distinguish relocation from application changes
Keep location-only matched pairs unchanged under complete coverage while retaining both coordinates and location dimensions. Preserve incomplete coverage as unknown and retain definite content, property, and relationship changes.

Validated with focused domain, compiled CLI and MCP workflows, static checks and docs checks. A tiny public CLI bundle fixture reproduces the issue; the reported Bitwarden releases were not rerun.

Refs #4520
2026-10-17 12:36:21 +08:00
morluto 1e36e707b1 fix(ghidra): preserve launch outcomes through cancellation and rollback
Carry producer cancellation separately from physical launch errors and diagnostic causes. Retain exact opaque reasons, LaunchSupport warnings, and rollback owners; consume the authored outcome without reclassifying failed launches from a later deadline.

Validation: focused client/provider/rollback and helper/MCP tests, check:fast, docs:check. Controlled native process ownership and Node bridge only; real Ghidra/JVM and Windows/Linux fault behavior unverified.

Refs #4517
2026-10-17 12:27:08 +08:00
morluto e31aa72c9d fix(ghidra): retain executable header read and cleanup ownership
Read bounded stable prefixes through the installation file owner, preserve unknown header diagnostics, and propagate cancellation or incomplete cleanup. Share extent and identity validation with full artifact reads.

Validated with 269 focused tests, check:fast, and docs:check. Controlled Darwin file faults reproduce the original lost owner; real Ghidra and native Windows/Linux verification remain unperformed.

Refs #4676
2026-10-17 12:17:44 +08:00
1053 changed files with 125393 additions and 87575 deletions

No files matched your search

@@ -0,0 +1,113 @@
---
name: rea-analysis-optimization
description: Optimize REA providers and shared analysis workflows for agent context, latency, CPU, and memory while preserving correctness and Evidence. Use for analysis bottlenecks and cache or query design; CI/test-suite optimization belongs to rea-ci-tests-audit.
---
# REA analysis optimization
Find a concrete source of unnecessary work, change it at its owner, and verify
equivalent completed investigations. A useful outcome can also be a measured
decision to leave an implementation alone.
Follow the checkout's [performance priorities](../../../AGENTS.md#performance),
[tool design](../../../docs/tool-design.md), and
[testing guide](../../../docs/testing.md). This skill supplies an optimization
workflow, not additional permission to execute targets, publish, or merge.
Use the current contracts, provider prerequisites, and user authorization.
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.
## Pin the question and the correctness oracle
Describe the analyst's completed task, including the facts and relationships
needed to answer it, requested detail, source access, and meaningful unknowns.
Choose a representative real artifact and a small or empty case. Record the
baseline revision, target digest, engine identity, options, host, and entrypoint.
Use a separate checkout for changes without disturbing other work.
Establish an oracle independent of the changed implementation: source-built
fixture expectations, independently mapped file bytes, or a native producer
paired with checks of its interpretation. Comparing two wrappers around the
same faulty decoder does not establish correctness. Preserve address widths,
same-address alternatives, unresolved endpoints, coverage, and source linkage.
An empty result proves absence only within the actually examined scope.
## Locate the earliest unnecessary work
Trace one public CLI or MCP task through shared application code to its producer.
Measure relevant phases: admission and identity checks, native analysis,
decoding, lookup, projection, serialization, Evidence retention, and cleanup.
Include catalog discovery and extra calls when they affect the completed task.
Use the evidence to choose the smallest structural correction:
| Observed cost | Candidate correction | Condition to establish |
| --------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Repeated scans of validated facts | Reuse existing order or lookup structure | The owner establishes ordering and identity; every matching alternative survives |
| Repeated equivalent engine work | Share a validated result or in-flight producer | Inputs, freshness, lifetime, and per-caller outcomes remain explicit |
| Full reports for selected facts | Push selection or projection to the earliest capable owner | Required facts and evidence remain reachable; examined coverage is reported |
| Large temporary transport buffers | Decode incrementally or use bounded source reads | Validate the whole admitted document; retained facts and copies still consume memory |
| Many repeated homogeneous reads | Share admission, decoding, or batch work | Preserve item identity, order where required, and individual failures |
Do not introduce an index, generic cache, batch endpoint, or orchestration layer
without identifying the work it removes and its maintenance/resource cost.
Projection after materializing a full report may reduce output while leaving
analysis time and peak memory unchanged. Fix missing or incorrect facts before
benchmarking an alternative composition against a better-covered workflow.
## Keep one interpretation and a defined reuse lifetime
Let the producer boundary validate and normalize facts once. Consumers query
that representation through the shared CLI/MCP implementation; adapters should
not rebuild relationships or independently reinterpret raw reports. Keep lookup
identity separate from display formatting. Reuse contracts when their intent
matches, honoring requested detail and complete Evidence access.
For every cache or shared producer, state its key, owner, invalidation, retained
size, and lifetime. Account for result-affecting target bytes, engine contents,
analysis options, architecture/load mapping, and parser/schema versions where
they affect reuse. Validate live state before calling a cached observation
current. Cache a refusal only when it is deterministic for that validated key;
malformed, partial, transient, or cancelled attempts need explicit retry policy.
One cancelled waiter must not invalidate a successful peer. Preserve producer
failure context and each caller's cancellation reason. Retain ownership and
capacity charges until shared work and cleanup settle; preserve completed
observations when cleanup fails. Exercise invalidation, concurrent consumers,
last-waiter cancellation, close, and cleanup retry when those paths change.
Bound the process family and retained state, not just a parent heap or worker
count. Account for decoding and serialization expansion before allocation.
Choose CPU, memory, concurrency, and disk limits from the host and workload;
stop before OOM and verify owned cleanup. A guard-stopped task is incomplete.
Do not replace a transport buffer cap with an unbounded retained inventory or
hide partial results behind a success status.
## Compare completed tasks and limit the claim
Run the affected real public workflow before and after with equivalent inputs,
results, coverage, and Evidence semantics. Include small inputs so setup costs
and regressions are visible. Distinguish fresh sessions, warm runtime caches,
and OS file caches. Alternate or repeat runs when variance affects the decision.
Choose meaningful boundary regressions for cases the actual engine cannot
reliably reproduce; a fake engine does not qualify a real provider.
Report task outcome, relevant phase timings, total elapsed and CPU time, peak
process-family memory and its accounting method, resource stops, and cleanup.
Check the payload exit status as well as the profiler's. Keep failed attempts
and identify unmeasured costs; a passing retry does not explain a failure.
For token claims, count schemas/discovery, arguments, replies, retries, and
continuations needed to finish the task. Label tokenizer estimates separately
from actual model usage and record the client/catalog behavior. Smaller JSON
alone establishes neither fewer model tokens nor better investigation quality.
Do not claim a complex-software advantage without completed representative
investigations and comparable correctness/coverage.
Finish with the bottleneck, owning change, preserved semantics, executed
checks, before/after measurements, and remaining limits. Keep any integration
record current with its tested revision and distinguish merged production work
from experiment-only code. Stop when the demonstrated bottleneck is resolved
or further benefit remains speculative.
@@ -0,0 +1,4 @@
interface:
display_name: "REA analysis optimization"
short_description: "Optimize analysis with preserved Evidence and measured costs"
default_prompt: "Use $rea-analysis-optimization to find and verify a concrete analysis bottleneck while preserving correctness and Evidence."
@@ -0,0 +1,112 @@
# Kuna: reuse before adding machinery
Read this reference for concrete examples of the skill's decisions. The records
below concern static Linux analysis with caller-supplied Kuna. They do not
establish parity with another provider or a general advantage for Code Mode,
atomic tools, or any particular orchestration design.
## Exact-address lookup: a measured, narrow improvement
[PR #4695](https://github.com/morluto/rea/pull/4695) reused the validated string
inventory's numeric address order. Previously, each `list_strings(address)`
filtered all cached facts. The owner now performs a binary lower-bound lookup
and returns every encoding at that address: O(log n + matches), without a
second retained lookup index.
The owning implementation is
[`KunaStringInventory.ts`](../../../../src/kuna/KunaStringInventory.ts), consumed
by [`KunaStringQueries.ts`](../../../../src/kuna/KunaStringQueries.ts). Inspect
their current versions before adapting the example. Numeric u64 addresses,
same-address encodings, duplicate rejection, source digests, caller selection,
and the existing session lifetime were part of the contract. Full listings and
literal/regex searches kept their semantics. An attempted removal of the
duplicate-detection set was dropped: no stable memory benefit was established,
and it delayed malformed-input rejection.
### Recorded workload and results
The benchmark used unmodified Kuna 1.833 and LLVM 16 on Linux x86-64, with
602,544 string facts. Baseline was `be0b2d138`; the final feature was
`5f564962da0e1b17f00a68a74a312539f0209a01`, subsequently integrated in
`c6b62754b095a134d6d67877508fa34311a2eda2`. These are historical observations,
not a benchmark of every subsequent main revision.
The same production stdio MCP task discovered the catalog, opened the binary,
made one cold selected read and 28 warm exact reads, checked retained Evidence,
and closed the session. Five selected addresses and two absent selectors were
read four times. A native filtered scan selected the strings; an independent
ELF load-header mapping checked the source bytes and terminators. Returned
facts, source linkage, target digests, and cleanup were checked.
Three alternating fresh sessions per implementation used one CPU, a 4 GiB
process-family hard limit, a 3 GiB early stop, and no swap. OS file caches were
warm. Whole-harness costs include the independent native oracle, hashing,
catalog/client work, and correctness checks.
| Median | Before | After |
| ---------------------------------------- | ---------: | ---------: |
| 28 warm exact MCP reads | 495.2 ms | 90.8 ms |
| Cold selected MCP read | 11.30 s | 11.01 s |
| Whole harness elapsed | 28.24 s | 27.43 s |
| Whole process-family CPU | 27.71 s | 26.89 s |
| Kernel family peak, including file cache | 2237.6 MiB | 2240.6 MiB |
Warm totals ranged from 491.7–544.3 ms before to 84.8–99.5 ms after: about
5.5 times faster at this phase. Cold/whole-task timing and memory overlapped;
no stable improvement in those costs was established. One small SQLite pair
(7,985 facts) measured 20 warm reads at 88.6 → 80.5 ms and the whole harness at
13.68 → 13.94 s. The large-inventory lookup benefit does not generalize to a
whole-task speedup on small inputs.
Catalog hashes, call counts, and normalized facts were unchanged. A
`cl100k_base` estimate over one pass of raw catalog JSON, arguments, and replies
was about 846,000 tokens in both lanes, with about 802,562 from the catalog.
This was transport serialization, not rendered model context or actual usage;
client discovery, prompts, replay, and protocol framing were unmeasured.
**No token reduction or improved agent investigation outcome was established.**
Pinned target SHA-256:
`f62d254b7f2bf42df8c8b07d46ee3bb4c2cafeca436b2e6bc6ccbe4581f58f40`.
Pinned engine SHA-256:
`d858918b0766435cd96b999a77f2d5a31a0cc4f07256421c883b5b9dc4dd58e4`.
All six normalized-result sequence digests were
`4d2f90269da8568984090b20274163c4a7c2a0538aab63530bd2fe44840a0bba`.
Selected byte agreement does not prove native discovery completeness; missing
strings and relationships can remain unknown.
## Other transferable changes and their limits
- [Cached string inventory and search, #4095](https://github.com/morluto/rea/pull/4095):
share validated facts across queries in a defined session. Audit key inputs
and lifetime before extending reuse across targets or engine revisions.
- [Shared single-function work, #4045](https://github.com/morluto/rea/pull/4045)
and [repeat-request reuse, #4169](https://github.com/morluto/rea/pull/4169):
avoid duplicate native work while retaining per-caller cancellation and
cleanup ownership. A query count alone cannot reveal duplicate subprocesses.
- [Streamed strings, #4318](https://github.com/morluto/rea/pull/4318)
and [streamed call graph, #4329](https://github.com/morluto/rea/pull/4329):
remove fixed aggregate transport-buffer failures through incremental parsing.
Streaming transport does not bound every retained object or final reply.
These links establish changes; no numerical speedup is asserted here.
Typed reference facts, native string-query projection, and shared native byte
reads remained experimental at the 2026-10-17 checkpoint
`65f2f9a22bc892f61d2b00f9a4611124f57d4bff` on
`experiment/atomic-codemode-20261016`. Some experiments used a patched native
engine. Check current integration and bring-your-own engine capabilities before
proposing them; a working experiment is not a stock-provider guarantee.
## Applying the reasoning elsewhere
For another provider or format, inspect its actual representation and native
capabilities before borrowing the implementation. Existing numeric ordering
may support range reads; an on-disk native query may avoid materializing an
inventory; an immutable parse may support several views. Measure the relevant
alternative rather than requiring every provider to use Kuna's cached array.
For live observations, immutable artifact caching rules are insufficient:
validate the process/session identity and freshness required by the caller.
For compact replies, preserve access to source Evidence and report examined
coverage; projection must not silently turn an unresolved edge into no edge.
For batching, test mixed successes and failures and measure the entire task,
including discovery, extra calls, native work, and serialization.
@@ -124,6 +124,26 @@ operation's full ordered list. Candidate capabilities describe possible
providers. Top-level session capabilities describe the current route, and
`analysis_provider_binding` identifies the selected provider.
## Static memory and original file bytes
For Ghidra, `read_bytes` reads initialized analysis memory, including loader
fixups; it does not read a running process. Check `returned_bytes` and `complete`
before decoding a table. An incomplete read is missing coverage, not a zero-filled
tail. Use `list_segments` to inspect the selected block's initialization and address-space
facts, and retain unavailable facts as unknown.
Use `address_to_file_offset` to anchor one observed address to original file
bytes. A mapping for the first address does not establish a contiguous mapping
for an entire table, and loader fixups can make analysis bytes differ from source
bytes. Keep source ranges and analysis-memory observations separate.
A pointer table can refer to writable slots populated by a constructor rather
than directly to immutable resources. An uninitialized block or an observed zero
does not establish the slot's later runtime value. Follow `xrefs` and the relevant
writer's assembly or pseudocode; distinguish recorded assignments from inferred
execution order. Do not replace unreadable bytes with zeros or conclude that a
resource is absent without the necessary initialization evidence.
## DOS MZ with Ghidra
For an admitted DOS MZ target, use `inspect_native_load_image` to check measured
@@ -133,10 +153,8 @@ reported static image, not runtime DOS or PC-98 hardware behavior.
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.
Use `read_bytes` for initialized analysis memory and `address_to_file_offset` to
anchor one observed address to original file bytes. Loader fixups can change a
word; a source offset does not imply byte equality. Complete function body ranges
use inclusive ends and can contain gaps. Do not treat the enclosing span as code.
Complete function body ranges use inclusive ends and can contain gaps. Do not
treat the enclosing span as code.
For packed targets, retain the original and separately derived artifact identities;
decompiling an unpacking stub does not recover the unpacked program.
@@ -24,19 +24,7 @@ runs:
BUILD_CACHE_PREFIX: rea-portable-build-v2-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('.npmrc', '.nvmrc', 'package-lock.json') }}
run: |
npm run --silent test:prepare -- --dry=json |
node --input-type=module -e '
import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";
const { tasks } = JSON.parse(readFileSync(0, "utf8"));
const hashes = tasks.map(({ taskId, hash }) => {
if (typeof hash !== "string")
throw new Error(`Build task ${taskId} must have an eager Turbo hash`);
return `${taskId}:${hash}`;
}).sort();
const hash = createHash("sha256").update(hashes.join("\n")).digest("hex");
console.log(`key=${process.env.BUILD_CACHE_PREFIX}-${hash}`);
console.log(`prefix=${process.env.BUILD_CACHE_PREFIX}-`);
' >> "$GITHUB_OUTPUT"
node scripts/ci/portable-build-cache.mjs key >> "$GITHUB_OUTPUT"
- name: Restore portable build outputs
if: inputs.build_cache_artifact == '' && inputs.save != 'true'
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+8 -1
View File
@@ -357,10 +357,15 @@ jobs:
# test:prepare caches only portable JS, skill, and catalog outputs.
# Native package jobs still run their build and prepack checks; Turbo
# restores matching outputs or rebuilds when their inputs differ.
- name: Stage current portable build task cache
shell: bash
run: |
# A new Turbo dry run can evict the entries this build just used.
node scripts/ci/portable-build-cache.mjs snapshot < .cache/ci-build-plan.json
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: rea-build-cache
path: .turbo/cache/
path: .cache/ci-build-cache/
include-hidden-files: true
if-no-files-found: error
retention-days: 7
@@ -648,6 +653,7 @@ jobs:
tests/boundary/cli/nativePlistPrototypeKeyCli.test.ts
tests/boundary/cli/nativePlistSelectionFailureCli.test.ts
tests/boundary/cli/nativeDemangleCli.test.ts
tests/boundary/cli/nativeDispatchPropertyAttributes.test.ts
tests/boundary/mcp/nativeDemangleMcp.test.ts
tests/boundary/providers/native/nativeSignatureTargetBinding.test.ts
tests/boundary/cli/nativeSignatureCli.test.ts
@@ -748,6 +754,7 @@ jobs:
tests/boundary/filesystem/webScriptManifestPaths.test.ts
tests/boundary/process/ProcessEvidence.host.test.ts
tests/boundary/process/packageNpmInvocation.test.ts
tests/boundary/process/packedBridgeVerification.test.ts
tests/boundary/process/windowsOutputCapture.test.ts
tests/acceptance/webModuleCli.test.ts
tests/acceptance/webSourceLocationCli.test.ts
+12 -5
View File
@@ -24,7 +24,19 @@ jobs:
real-recorded-crash:
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
image: ["ubuntu:24.04", "debian:trixie-slim"]
container: ${{ matrix.image }}
steps:
- name: Install fixture and debugger prerequisites in the disposable container
shell: bash
run: |
apt-get update -qq
apt-get install --yes --no-install-recommends \
ca-certificates git python3-venv gcc libc6-dev strace gdb
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
@@ -36,11 +48,6 @@ jobs:
- uses: ./.github/actions/portable-build-cache
with:
build_cache_artifact: ${{ inputs.build_cache_artifact }}
- name: Install GDB on the disposable CI runner
shell: bash
run: |
sudo apt-get update -qq
sudo apt-get install --yes --no-install-recommends gdb
- name: Acquire exact unchanged upstreams in isolated runner storage
shell: bash
run: |
+1 -1
View File
@@ -1,3 +1,3 @@
{
".": "6.5.0"
".": "6.7.0"
}
+88
View File
@@ -1,5 +1,93 @@
# Changelog
## [6.7.0](https://github.com/morluto/rea/compare/rea-agents-6.6.0...rea-agents-6.7.0) (2026-10-18)
### Highlights
- Client configuration edits follow the duplicate-member semantics used by MCP clients.
### Changes
- Includes the [6.6.0 changes and migration notes](https://github.com/morluto/rea/releases/tag/rea-agents-6.6.0). That version was tagged but was not published to npm.
### Fixes
- **Client configuration:** Setup edits the last repeated JSON/JSONC member, matching the value clients actually read. Setup and uninstall refuse a removal that would reactivate a shadowed duplicate, preserving the original configuration. ([#4957](https://github.com/morluto/rea/pull/4957), [morluto/rea#4952](https://github.com/morluto/rea/issues/4952)). Thanks @kaoru0822-kitauji, @xu91102.
Full contribution record: [4 commits and 1 merged PR](https://github.com/morluto/rea/blob/rea-agents-6.7.0/docs/releases/6.7.0.contributions.json).
## [6.6.0](https://github.com/morluto/rea/compare/rea-agents-6.5.0...rea-agents-6.6.0) (2026-10-18)
### Highlights
- Add Kuna as a caller-supplied static-analysis provider.
- Query selected JavaScript facts and multiple APK locale tables without repeating the underlying analysis.
- Extend Ghidra analysis to Windows ARM PE targets and explicit raw m68k images.
- Preserve completed Evidence, cancellation reasons and retryable cleanup across provider and CLI finalization.
### Changes
- **Kuna analysis:** Use a caller-installed Kuna for procedure listings, pseudocode, assembly, call relationships, exact-address xrefs and cached string searches. Project exports retain source spans and digests; repeated requests reuse completed work. Recorded real-provider coverage uses Kuna 1.833 on Linux; Windows, PE and universal Mach-O are unsupported. See [the provider guide](docs/kuna-provider.md). ([#3832](https://github.com/morluto/rea/pull/3832), [#3854](https://github.com/morluto/rea/pull/3854), [#4071](https://github.com/morluto/rea/pull/4071), [#4095](https://github.com/morluto/rea/pull/4095)). Thanks @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0.
- **Retained JavaScript facts:** Query exact application paths, selected properties and filtered module references through `inspect_analysis_view`, with paging and complete row Evidence. These views reuse completed analysis and preserve source selection and unknown coverage. ([#4265](https://github.com/morluto/rea/pull/4265), [morluto/rea#4190](https://github.com/morluto/rea/issues/4190), [#4097](https://github.com/morluto/rea/pull/4097), [morluto/rea#4092](https://github.com/morluto/rea/issues/4092)). Thanks @kaoru0822-kitauji, @N0zoM1z0.
- **APK locale tables:** Request several resource locales in one decode with repeatable CLI `--locales` or MCP `locales`. Each table reports its status and coverage; existing single-locale fields remain available. ([#4804](https://github.com/morluto/rea/pull/4804), [morluto/rea#4777](https://github.com/morluto/rea/issues/4777)). Thanks @abhay-2108, @N0zoM1z0.
- **Windows ARM binaries:** Ghidra admits ARMNT/Thumb-2 and ARM64 PE applications and DLLs on the Windows x64 host lane. Recorded Ghidra 12.1.4 verification uses `WindowsResourceReference` disabled and raised startup budgets; default-analyzer completion, ARM64EC/ARM64X and Windows-on-Arm hosts remain unverified or unsupported. See [the exact scope](docs/windows-ghidra-p0.md#native-authority-and-target-identity). ([#3965](https://github.com/morluto/rea/pull/3965), [morluto/rea#2186](https://github.com/morluto/rea/issues/2186)). Thanks @N0zoM1z0, @WestLabsAI.
- **Raw m68k images:** Analyze explicitly selected big-endian m68k raw binaries using Ghidra’s fixed 68000 profile and a caller-supplied aligned entry. Real CLI/MCP verification used Ghidra 12.1.4 on macOS arm64; Linux is unverified and Windows P0 does not admit m68k. See [mapping requirements](docs/raw-binary.md). ([#4018](https://github.com/morluto/rea/pull/4018)). Thanks @icedac.
- **JADX deadlines:** Set `REA_JADX_OPERATION_TIMEOUT_MS` to extend APK loading and upstream operation deadlines together. Doctor reports the effective value and setup forwards an explicit selection. ([#4466](https://github.com/morluto/rea/pull/4466), [morluto/rea#3918](https://github.com/morluto/rea/issues/3918)). Thanks @jaychou813, @SandstromPL.
- **Electron window options:** Resolve stable local constant `BrowserWindow` options while retaining source provenance. Relevant writes and escapes keep the result unknown. ([#4400](https://github.com/morluto/rea/pull/4400), [morluto/rea#4366](https://github.com/morluto/rea/issues/4366)). Thanks @kaoru0822-kitauji, @N0zoM1z0.
- **Language editions:** Add the Greek website edition and Malayalam documentation, with Korean typography and translation corrections across the site. ([#3520](https://github.com/morluto/rea/pull/3520), [#4792](https://github.com/morluto/rea/pull/4792), [#3821](https://github.com/morluto/rea/pull/3821), [morluto/rea#3820](https://github.com/morluto/rea/issues/3820), [#3799](https://github.com/morluto/rea/pull/3799), [morluto/rea#3798](https://github.com/morluto/rea/issues/3798), [#4344](https://github.com/morluto/rea/pull/4344), [#3856](https://github.com/morluto/rea/pull/3856), [#4166](https://github.com/morluto/rea/pull/4166)). Thanks @gensokyo-dev, @hi2242, @kalayciburak, @kaoru0822-kitauji, @kraken-503, @kukinghan, @N0zoM1z0, @yeseong0412.
### Fixes
- **Cancellation and cleanup:** Keep completed observations, exact cancellation reasons and the original physical failure through finalization. Failed cleanup retains its process or file owner for retry; recovered resources disappear from pending-cleanup reports without replacing the original error. ([#4238](https://github.com/morluto/rea/pull/4238), [morluto/rea#4232](https://github.com/morluto/rea/issues/4232), [#4274](https://github.com/morluto/rea/pull/4274), [morluto/rea#3923](https://github.com/morluto/rea/issues/3923), [3e82366](https://github.com/morluto/rea/commit/3e8236639abffa39deb5d5e939ec8baf6aaf3ca3), [16924e2](https://github.com/morluto/rea/commit/16924e275e939d0543ba01493324959a9e1d731c), [bbfe6ed](https://github.com/morluto/rea/commit/bbfe6edd60290f9bfbec68c8a0bcf605d8bbf5b3), [1f23e97](https://github.com/morluto/rea/commit/1f23e977b50301e91f02a4a17c9f8d48bb7b60f3), [08fbeb8](https://github.com/morluto/rea/commit/08fbeb8bdab27118b6c57039aef7c0fa8b6463bc)). Thanks @coygeek.
- **Provider startup:** Join prerequisite probes and in-flight readiness work before shutdown, preserve typed timeout and JVM-memory failures, and retain startup diagnostics through cleanup. Ghidra recognizes keg-only Homebrew JDKs and names the setting responsible for a startup timeout. ([376eeca](https://github.com/morluto/rea/commit/376eeca770820b31f7f8d4c5fcc397315621643e), [ceeff5a](https://github.com/morluto/rea/commit/ceeff5a41788e47e5aee96a4baf191a6ce7fde4b), [3ad1032](https://github.com/morluto/rea/commit/3ad1032b11edea2dcb054e78f951cc43159ae83d), [964decd](https://github.com/morluto/rea/commit/964decd989acfa84c4bfc3295362c4c46877fc20), [3fa972a](https://github.com/morluto/rea/commit/3fa972af7c7cb6cf014ffc426bdf7130dc6f2fd2), [#4557](https://github.com/morluto/rea/pull/4557), [morluto/rea#4556](https://github.com/morluto/rea/issues/4556), [#4590](https://github.com/morluto/rea/pull/4590), [morluto/rea#4241](https://github.com/morluto/rea/issues/4241)). Thanks @DanielCvz1, @J0UH, @Rinkia, @RishTheFish21, @vadlachary2002.
- **Client configuration:** Preserve the selected launcher, destination file, caller timeout choices and unresolved configuration evidence. Setup/uninstall recovery stays bound to the exact published file, keeps current verified backups, and transfers failed cleanup ownership for retry. ([d0253c9](https://github.com/morluto/rea/commit/d0253c99d65afbbd12732a2fdaf711640574e17f), [7e4eed9](https://github.com/morluto/rea/commit/7e4eed9dd48485b6a7100300aa98401811c2deb9), [2fb5e20](https://github.com/morluto/rea/commit/2fb5e204a35723f6f843d56ca47b0db94d8fcc44), [8235210](https://github.com/morluto/rea/commit/823521085a28f825e7fee1929d852d420042d1f7), [d818c3d](https://github.com/morluto/rea/commit/d818c3d2639d3115edb8a5269a754101aea6c3bd), [19329e4](https://github.com/morluto/rea/commit/19329e43bb38ca9d64512d801b25abcb188d2512), [dadf909](https://github.com/morluto/rea/commit/dadf909dce2e8b3d055541de69b4118d21276316), [333e0ab](https://github.com/morluto/rea/commit/333e0ab0dfc126a9915907d5079ed6195190e38e), [c15c206](https://github.com/morluto/rea/commit/c15c2062ad815cc9a3222ccfaeb7ef53cacd8b72)). Thanks @Adolanium.
- **Configuration formats:** Read signed 64-bit TOML integers without rounding, handle large TOML documents without argument-spread failures, preserve JSONC trivia and Hermes YAML scalar text, and reject NUL bytes in registration environment values. ([#4937](https://github.com/morluto/rea/pull/4937), [morluto/rea#4917](https://github.com/morluto/rea/issues/4917), [c43bc0b](https://github.com/morluto/rea/commit/c43bc0bf66a4e245a0cafa40def0d0207bcbd73c), [4fd28fc](https://github.com/morluto/rea/commit/4fd28fc9e0c4f8358147af38c72ab9e814f52d61), [#3568](https://github.com/morluto/rea/pull/3568), [#4335](https://github.com/morluto/rea/pull/4335)). Thanks @alfredo1491, @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0, @ShuaixinHuang, @xu91102.
- **Claude Code configuration:** Setup, doctor and uninstall now accept only the strict JSON format Claude Code reads, including a leading UTF-8 BOM. Comments and trailing commas are refused before backup or writing; clients that support JSONC retain their existing behavior. ([#4944](https://github.com/morluto/rea/pull/4944), [morluto/rea#4940](https://github.com/morluto/rea/issues/4940)). Thanks @kaoru0822-kitauji, @xu91102.
- **CLI output and dispatch:** Accept `--flag=value` and spaced global output values, keep array positions in filtered JSON, validate integer tokens before coercion, and exit quietly when the output reader closes. Cancellation remains effective through command finalization; app bundles and static native inspections select the intended workflow. ([#3811](https://github.com/morluto/rea/pull/3811), [#4823](https://github.com/morluto/rea/pull/4823), [2ae4e16](https://github.com/morluto/rea/commit/2ae4e1608f290c95ff7cff28c4d16a79b301d03d), [8d82579](https://github.com/morluto/rea/commit/8d8257928bbe8d43fedffc4db5fca26c8108820f), [#3781](https://github.com/morluto/rea/pull/3781), [279c590](https://github.com/morluto/rea/commit/279c590ef6bb737d4a48ea696a0ae5eb30010b3d), [#3511](https://github.com/morluto/rea/pull/3511), [morluto/rea#3321](https://github.com/morluto/rea/issues/3321), [f31b231](https://github.com/morluto/rea/commit/f31b231a92a61be6bd1800b16be0b3210ae82944)). Thanks @arjunprabhulal, @coygeek, @kaoru0822-kitauji, @ShuaixinHuang, @Sriram-PR, @Tapraj-Pathak.
- **Updates:** Route `--update` through the verified updater and bound retained package-manager diagnostics. ([4f7b5fb](https://github.com/morluto/rea/commit/4f7b5fb6023ce2ec449561782d09e3c7e5ac7c7b), [01cdbbd](https://github.com/morluto/rea/commit/01cdbbdc556262c47d04a5b3391dd9c17946d3fc)).
- **MCP contracts:** Advertise self-contained tool inputs while preserving tuple, array, Boolean and nested-JSON constraints across schema profiles. Schema-reference handling no longer rewrites literal metadata; catalog identity includes the output-schema profile. ([5e30969](https://github.com/morluto/rea/commit/5e30969cc5f1255d44ec7a1f1ca8dbac0af5e7c4), [10aa74d](https://github.com/morluto/rea/commit/10aa74dfedc3ae776f50d1fa1eb83b64ae82d3d6), [204b9f3](https://github.com/morluto/rea/commit/204b9f3ac140a993c3e458bb0e117de31818ab29), [b3389a5](https://github.com/morluto/rea/commit/b3389a5b0834265fe7a40391be315d810a53a97e), [a2e3016](https://github.com/morluto/rea/commit/a2e30168a046f3b79319eb7fbaf807b802104199), [ba98130](https://github.com/morluto/rea/commit/ba98130049fa40ade66b03611ff70c7ddc011a1d), [c5fb86d](https://github.com/morluto/rea/commit/c5fb86d1948af0a287a581b29b2b1d554743c607)). Thanks @akushonkamen, @HarsH-1877, @kaoru0822-kitauji, @xingzihai.
- **Session ordering:** Keep snapshot admission ahead of later calls on the same connection, retain shutdown signals until cleanup succeeds, and preserve inspection authority through investigation publication. ([#3661](https://github.com/morluto/rea/pull/3661), [morluto/rea#3334](https://github.com/morluto/rea/issues/3334), [8873b39](https://github.com/morluto/rea/commit/8873b39770e89eae22b7693bc492d7e423b22bea), [663d07f](https://github.com/morluto/rea/commit/663d07f02cd62c99d81c59391d2c6d745c875335)). Thanks @coygeek, @rudycelekli, @Swatantra-66.
- **JavaScript exports and resolution:** Retain CommonJS exports created with `Object.defineProperty` and track export receiver lifetimes. Resolve scoped packages, package `main`, JSON requires and `.mts`/`.cts` imports using the owning loader; overwritten `require` bindings and erased type-only imports no longer create false runtime links. ([#4725](https://github.com/morluto/rea/pull/4725), [morluto/rea#4724](https://github.com/morluto/rea/issues/4724), [#3567](https://github.com/morluto/rea/pull/3567), [morluto/rea#3541](https://github.com/morluto/rea/issues/3541), [#4838](https://github.com/morluto/rea/pull/4838), [morluto/rea#4632](https://github.com/morluto/rea/issues/4632), [#3844](https://github.com/morluto/rea/pull/3844), [morluto/rea#3383](https://github.com/morluto/rea/issues/3383), [#4164](https://github.com/morluto/rea/pull/4164), [morluto/rea#3915](https://github.com/morluto/rea/issues/3915), [#4223](https://github.com/morluto/rea/pull/4223), [#3801](https://github.com/morluto/rea/pull/3801), [morluto/rea#3393](https://github.com/morluto/rea/issues/3393), [#4165](https://github.com/morluto/rea/pull/4165), [morluto/rea#3932](https://github.com/morluto/rea/issues/3932)). Thanks @Abishek0070, @coygeek, @JNTMTMTM, @kaoru0822-kitauji, @prasad2512, @rodricksz4h5, @xu91102.
- **JavaScript value flow:** Preserve values captured before later assignments, guarded factory fallthrough and nested destructuring. Track exact property keys and setter writes; direct `eval`, compound assignments and incoming callbacks preserve unresolved effects instead of inventing certainty. ([#4196](https://github.com/morluto/rea/pull/4196), [morluto/rea#3881](https://github.com/morluto/rea/issues/3881), [#4341](https://github.com/morluto/rea/pull/4341), [morluto/rea#3963](https://github.com/morluto/rea/issues/3963), [bfb7ed0](https://github.com/morluto/rea/commit/bfb7ed0bd43edc605e00fc52c6e21e735b285904), [#3480](https://github.com/morluto/rea/pull/3480), [#3831](https://github.com/morluto/rea/pull/3831), [morluto/rea#3312](https://github.com/morluto/rea/issues/3312), [9ac76d3](https://github.com/morluto/rea/commit/9ac76d3d9486856d25395b413d7ac5ffa744cad0), [#4342](https://github.com/morluto/rea/pull/4342), [morluto/rea#4206](https://github.com/morluto/rea/issues/4206), [#4243](https://github.com/morluto/rea/pull/4243), [morluto/rea#3880](https://github.com/morluto/rea/issues/3880)). Thanks @coygeek, @kaoru0822-kitauji, @maxazure, @N0zoM1z0, @ShuaixinHuang.
- **JavaScript relationships:** Distinguish `Map` reads from network endpoints, associate response endpoints only with writes that reach the read, and preserve child-process receiver ownership and effective stdio choices. Version comparisons keep relocation and unknown relationships distinct from application changes. ([fbfdb6a](https://github.com/morluto/rea/commit/fbfdb6abe9d663be0be146a15a489e33ccba0f68), [#4759](https://github.com/morluto/rea/pull/4759), [morluto/rea#4606](https://github.com/morluto/rea/issues/4606), [#3819](https://github.com/morluto/rea/pull/3819), [morluto/rea#3362](https://github.com/morluto/rea/issues/3362), [#4336](https://github.com/morluto/rea/pull/4336), [morluto/rea#3355](https://github.com/morluto/rea/issues/3355), [556504e](https://github.com/morluto/rea/commit/556504edcbb0f8cd9eaf81a91b18ff891b8f5457), [4d980d0](https://github.com/morluto/rea/commit/4d980d017622d3175d86aaf3b0dcfbdf4ca3d091)). Thanks @Abdooo2235, @coygeek, @kaoru0822-kitauji, @Xinglan233.
- **JavaScript source admission:** Parse JavaScript with its own grammar, refuse FIFO recovery inputs without blocking, and report oversized or resource-skipped files with their actual capacity and coverage state. Malformed runtime events stay excluded rather than becoming policy-filtered facts. ([#3782](https://github.com/morluto/rea/pull/3782), [morluto/rea#3780](https://github.com/morluto/rea/issues/3780), [#3788](https://github.com/morluto/rea/pull/3788), [morluto/rea#3332](https://github.com/morluto/rea/issues/3332), [#4757](https://github.com/morluto/rea/pull/4757), [morluto/rea#4629](https://github.com/morluto/rea/issues/4629), [#3852](https://github.com/morluto/rea/pull/3852), [morluto/rea#3670](https://github.com/morluto/rea/issues/3670), [#4755](https://github.com/morluto/rea/pull/4755), [morluto/rea#4685](https://github.com/morluto/rea/issues/4685)). Thanks @andresaragon, @coygeek, @kaoru0822-kitauji, @sx4im.
- **Browser capture:** Bound CDP handshakes and command responses, preserve malformed inventory uncertainty and partial cleanup diagnostics, and report cancellation after content reads and final cleanup. Accessibility comparisons require observed coverage; attached emulation teardown limits remain explicit. ([#3555](https://github.com/morluto/rea/pull/3555), [morluto/rea#3553](https://github.com/morluto/rea/issues/3553), [#3901](https://github.com/morluto/rea/pull/3901), [morluto/rea#3379](https://github.com/morluto/rea/issues/3379), [4cc044b](https://github.com/morluto/rea/commit/4cc044be68f813e96907e6cedcf422d0a3170de3), [#4406](https://github.com/morluto/rea/pull/4406), [morluto/rea#4403](https://github.com/morluto/rea/issues/4403), [#2893](https://github.com/morluto/rea/pull/2893), [0123d59](https://github.com/morluto/rea/commit/0123d5976828bfe621bd51daa4cf39fee48a1349), [2ff0867](https://github.com/morluto/rea/commit/2ff086796ad7b8f60397956750584e170dbe2910)). Thanks @coygeek, @dakjdakd, @kaoru0822-kitauji, @maxazure, @N0zoM1z0, @YunzhouLi-hub.
- **Browser page facts:** Preserve URL path bytes when removing credentials, repeated document `Link` headers and complete COOP/COEP structured items. WebMCP discovery reads the actual schema properties and exact receiver path. ([#4731](https://github.com/morluto/rea/pull/4731), [df2fc25](https://github.com/morluto/rea/commit/df2fc251e318a1255309dba232f9f73c700777b6), [c360cfc](https://github.com/morluto/rea/commit/c360cfcd6d7901514b16dd6113eba2e0b0fdf422), [ebd5a82](https://github.com/morluto/rea/commit/ebd5a82c439f6deb3a06062225ce009eb03257cf), [38f92d1](https://github.com/morluto/rea/commit/38f92d108e3148cdf47e4ffbfe3de8a76e795d51)). Thanks @Abdooo2235, @geekwolf, @ShuaixinHuang.
- **Electron runtime capture:** Keep native IPC listener and one-shot dispatch behavior, block synchronous shell effects during capture, refuse active scenarios when the inspect fuse is disabled, and preserve fuse/transport cleanup ownership. ([#4389](https://github.com/morluto/rea/pull/4389), [morluto/rea#4390](https://github.com/morluto/rea/issues/4390), [#4605](https://github.com/morluto/rea/pull/4605), [morluto/rea#4593](https://github.com/morluto/rea/issues/4593), [#4562](https://github.com/morluto/rea/pull/4562), [morluto/rea#4393](https://github.com/morluto/rea/issues/4393), [#3605](https://github.com/morluto/rea/pull/3605), [morluto/rea#3453](https://github.com/morluto/rea/issues/3453), [f9de413](https://github.com/morluto/rea/commit/f9de41371f7536e2e22ce6e43c9314fa2f238a30), [e7df00e](https://github.com/morluto/rea/commit/e7df00e80777757b329bbe8aba6d421d8892b9d5)). Thanks @Adolanium, @gensokyo-dev, @gkobayashi0, @HarsH-1877, @kaoru0822-kitauji, @keeponlight, @N0zoM1z0, @Nitin13-git, @xu91102.
- **APK resource accuracy:** Retain completed tables and decode facts after interrupted or failed reads. Derive locale limits from resource configuration fields, disclose unselectable qualified tables, distinguish document failures from omitted entries, and bind Evidence to the decoded snapshot. ([34a88d6](https://github.com/morluto/rea/commit/34a88d6c1674710953e2c94bd0a17332cd69ca6f), [f5fcf52](https://github.com/morluto/rea/commit/f5fcf5216ffb3a266b8c00f6d9a0943051084ab5), [6385ef4](https://github.com/morluto/rea/commit/6385ef4355d7a794b3154ee38529cbddee583336), [98886ad](https://github.com/morluto/rea/commit/98886adddfcbd7b4f4236b3a9825f91878c3cb11), [dc2e811](https://github.com/morluto/rea/commit/dc2e8117b60c4481372ed89b077e6c1cf81ee653), [#4771](https://github.com/morluto/rea/pull/4771), [morluto/rea#4768](https://github.com/morluto/rea/issues/4768)). Thanks @abhay-2108, @gensokyo-dev, @Iyanuoluwa007, @kaoru0822-kitauji, @N0zoM1z0.
- **Apktool guidance:** Retain the observed version and disclose the matching platform/release advisory windows without treating a version string as proof of decoder safety. Missing prerequisites and decode refusals identify the selected APK or launcher. ([d38f099](https://github.com/morluto/rea/commit/d38f099692394ec90c582f9f0a14b036b421b160), [63696d2](https://github.com/morluto/rea/commit/63696d277328f556c971d1fc9f81ae83128d468b), [cc038da](https://github.com/morluto/rea/commit/cc038da218cada68c87700477aba3db4739791ff)). Thanks @GovinduSasanka, @peter-research.
- **Android method bodies:** Recover original bytecode bodies when Java source is omitted while preserving genuine native/abstract body absence and primary failures during retryable cleanup. ([63c65a2](https://github.com/morluto/rea/commit/63c65a22430a4bbc0c1807a0298edb867775001f), [742b6f5](https://github.com/morluto/rea/commit/742b6f587f3c4ef1b8212e7376d6f3a305b194dc), [9fa6d2b](https://github.com/morluto/rea/commit/9fa6d2b254cc390665974efb52463386a029e9fc)). Thanks @balkan16, @Chessing234.
- **ADB observations and transfers:** Preserve display-scoped focus, distinguish missing declarations from absent focus, retain numeric physical density and mark unknown permission coverage partial. Transfers use consumed snapshot identity and refuse unknown destination existence; uninstall requests explicitly select user zero. ([7086768](https://github.com/morluto/rea/commit/7086768a27242a15daa93486aefbaacc3c891e78), [3d028db](https://github.com/morluto/rea/commit/3d028dbc74a465f6f8df1813a931fbb5362e7dc3), [#4074](https://github.com/morluto/rea/pull/4074), [morluto/rea#3942](https://github.com/morluto/rea/issues/3942), [#4663](https://github.com/morluto/rea/pull/4663), [#4665](https://github.com/morluto/rea/pull/4665), [1342127](https://github.com/morluto/rea/commit/1342127e91d4db8b4113a7a4e85be909bc96e1db), [61e6880](https://github.com/morluto/rea/commit/61e688070f48016b6d178cd04c02fcc2f33e19ad), [be0b2d1](https://github.com/morluto/rea/commit/be0b2d138c46bb951fc3c8ee57ef7b0d57fed312)). Thanks @Copilot, @coygeek, @gongfpp, @Tapraj-Pathak, @yankikucuk.
- **Apple metadata:** Preserve exact plist/keyed-archive integers, negative zero, non-finite real identity and dictionary keys. Reject malformed XML before value decoding, retain undecodable dates as unknown and report unsupported OpenStep entries explicitly. ([#4324](https://github.com/morluto/rea/pull/4324), [morluto/rea#4292](https://github.com/morluto/rea/issues/4292), [2cf9c28](https://github.com/morluto/rea/commit/2cf9c28f27261b7e64af2ba7ecb4e23ea7714aee), [#4839](https://github.com/morluto/rea/pull/4839), [morluto/rea#4834](https://github.com/morluto/rea/issues/4834), [f2b7bbb](https://github.com/morluto/rea/commit/f2b7bbb31279a820f4cf32d439570f8e5381d010), [6c98708](https://github.com/morluto/rea/commit/6c98708793c23615de8053b2cd14d9f164b960c5), [78cf610](https://github.com/morluto/rea/commit/78cf6100f33ad2412c0a3d60b83f8a44a43fbbb5), [c7e9e09](https://github.com/morluto/rea/commit/c7e9e096d3e2444e4c251123b8e914e9c0941f4e), [#3793](https://github.com/morluto/rea/pull/3793), [#4105](https://github.com/morluto/rea/pull/4105), [morluto/rea#3892](https://github.com/morluto/rea/issues/3892)). Thanks @coygeek, @kaoru0822-kitauji, @mertkayacs, @pablodiazjorge, @pollychen-lab, @xu91102.
- **Apple application structure:** Derive bundle components and launchd domains from their owning directories, retain unavailable components, and select only exact `Assets.car` names as asset catalogs. Interface Builder keeps unresolved classes and counts hierarchy records beyond the returned object page. ([149a0fc](https://github.com/morluto/rea/commit/149a0fc06c3c67ee45624e6da14dfb0754473758), [5d6029e](https://github.com/morluto/rea/commit/5d6029ea62a65ec34fd739ee40223c77c6fdb63b), [c192c58](https://github.com/morluto/rea/commit/c192c58815ddeaf5cf30159e7082c742c0bc36b7), [#4094](https://github.com/morluto/rea/pull/4094), [morluto/rea#3914](https://github.com/morluto/rea/issues/3914), [#4118](https://github.com/morluto/rea/pull/4118), [morluto/rea#3958](https://github.com/morluto/rea/issues/3958), [#4162](https://github.com/morluto/rea/pull/4162), [morluto/rea#3950](https://github.com/morluto/rea/issues/3950)). Thanks @coygeek, @kaoru0822-kitauji.
- **Native names and layout:** Keep valid Objective-C records beside malformed neighbors, preserve leading U+FEFF and repeated load-command fields, and select exact arm64e.x1 slices. PE resource ownership and NativeAOT reads stay within declared image/header ranges. ([#3833](https://github.com/morluto/rea/pull/3833), [morluto/rea#3336](https://github.com/morluto/rea/issues/3336), [#4549](https://github.com/morluto/rea/pull/4549), [morluto/rea#4540](https://github.com/morluto/rea/issues/4540), [morluto/rea#4541](https://github.com/morluto/rea/issues/4541), [#4730](https://github.com/morluto/rea/pull/4730), [#4048](https://github.com/morluto/rea/pull/4048), [morluto/rea#4008](https://github.com/morluto/rea/issues/4008), [#3500](https://github.com/morluto/rea/pull/3500), [morluto/rea#3389](https://github.com/morluto/rea/issues/3389), [#4463](https://github.com/morluto/rea/pull/4463), [morluto/rea#4373](https://github.com/morluto/rea/issues/4373), [morluto/rea#4455](https://github.com/morluto/rea/issues/4455), [3fc0075](https://github.com/morluto/rea/commit/3fc007534bb2104d662b43cc712281f9d1d6a7d3), [4a076f3](https://github.com/morluto/rea/commit/4a076f368c62bdfb19415accad342e03a38d1005)). Thanks @coygeek, @Iyanuoluwa007, @jayinvers, @kaoru0822-kitauji, @kevinjosh10, @maxazure, @ShuaixinHuang.
- **Native analysis providers:** Keep Ghidra byte matches within examined coverage, retain PE PDB/function-boundary limitations and preserve configured MIPS choices. Attached IDA refuses universal Mach-O rather than silently choosing a slice; request timeout identity and captured output survive adapter handling. ([#4531](https://github.com/morluto/rea/pull/4531), [#2933](https://github.com/morluto/rea/pull/2933), [morluto/rea#2259](https://github.com/morluto/rea/issues/2259), [01a1b3f](https://github.com/morluto/rea/commit/01a1b3fda6a7dacd24a0b10619d41d12153080d4), [50dd9fc](https://github.com/morluto/rea/commit/50dd9fcad1efb47cb404192c30bdf190dcdaca58), [#4765](https://github.com/morluto/rea/pull/4765), [morluto/rea#3871](https://github.com/morluto/rea/issues/3871), [c0cfccb](https://github.com/morluto/rea/commit/c0cfccb45fe43e7eeff18e56c64caa5b121988f9)). Thanks @BeLit-Development-2, @coygeek, @kaoru0822-kitauji, @N0zoM1z0, @ShuaixinHuang.
- **Recorded crashes:** Prevent GDB from discovering an executable named by an untrusted core, reject core mapping paths that escape the isolated sysroot, and preserve pwntools worker ownership across launcher exec. Completed decode facts and cancellation reasons remain available through failed final cleanup. ([5bf4fff](https://github.com/morluto/rea/commit/5bf4fffc1b835130ddb16f96db9ce13b639591db), [b33c0df](https://github.com/morluto/rea/commit/b33c0df02e93fabca00a44f2de625b1a63637ee9), [#4435](https://github.com/morluto/rea/pull/4435), [morluto/rea#4011](https://github.com/morluto/rea/issues/4011)). Thanks @coygeek, @N0zoM1z0.
- **Cutter and Rizin:** Read Cutter’s active document from core configuration and attribute its host version correctly. Keep interrupted Rizin frames and output whitespace before completion markers, with exact command and cleanup failure attribution. ([#4507](https://github.com/morluto/rea/pull/4507), [morluto/rea#4497](https://github.com/morluto/rea/issues/4497), [#4514](https://github.com/morluto/rea/pull/4514), [morluto/rea#4498](https://github.com/morluto/rea/issues/4498), [#4459](https://github.com/morluto/rea/pull/4459), [morluto/rea#4015](https://github.com/morluto/rea/issues/4015), [d5fc7e6](https://github.com/morluto/rea/commit/d5fc7e6ebf9af050081fc4c6e18b9079cfaa5cdc), [199396f](https://github.com/morluto/rea/commit/199396f61c8f61da326d059606a992304a760147)). Thanks @coygeek, @N0zoM1z0, @Xander-AJ.
- **Windows cleanup:** Retain unpublished runtimes after failed removal, handle read-only attributes and sharing conflicts, preserve primary snapshot failures and honor caller environment overrides. ([f78d137](https://github.com/morluto/rea/commit/f78d137b42741a0ed5fb8ac161286f9a50220c4d), [d69acc3](https://github.com/morluto/rea/commit/d69acc3455c33f90a2fc4381db43d38b6af50622), [0679a79](https://github.com/morluto/rea/commit/0679a7972b4f2b02eee6a86a44f50f4c2967d3cb), [5f9ac2c](https://github.com/morluto/rea/commit/5f9ac2c98a6fe11988c41afb737df9b6d5c3a1b3), [1bbf4bd](https://github.com/morluto/rea/commit/1bbf4bd16ca134cdb2187eaf29291cae90d14a57)). Thanks @DeryFerd.
- **Managed metadata:** Compare nominal signatures and declaring identities across builds, preserve empty names without display substitutions, verify ABI-prefixed Mach-O exports exactly, and charge cached metadata once. Metadata errors report artifact file offsets; mixed-mode assemblies retain their actual boundary classification. ([#3059](https://github.com/morluto/rea/pull/3059), [#3079](https://github.com/morluto/rea/pull/3079), [#3853](https://github.com/morluto/rea/pull/3853), [morluto/rea#3352](https://github.com/morluto/rea/issues/3352), [#3974](https://github.com/morluto/rea/pull/3974), [morluto/rea#3961](https://github.com/morluto/rea/issues/3961), [#3491](https://github.com/morluto/rea/pull/3491), [morluto/rea#3449](https://github.com/morluto/rea/issues/3449), [#4418](https://github.com/morluto/rea/pull/4418), [morluto/rea#4372](https://github.com/morluto/rea/issues/4372), [#3516](https://github.com/morluto/rea/pull/3516), [morluto/rea#3366](https://github.com/morluto/rea/issues/3366)). Thanks @8rulerstar, @coygeek, @duckhunt113, @Hahaa909, @JayOfTheKeyboard, @kaoru0822-kitauji, @keeponlight, @N0zoM1z0, @tomyrms.
- **Archive and filesystem identity:** Reject colliding extraction paths before writing, classify ZIP offsets beyond EOF as malformed, normalize ZIP current-directory prefixes once, and preserve symlink and unreadable-path provenance. A directory named `*.map` is no longer mistaken for a source-map file. ([862a0b2](https://github.com/morluto/rea/commit/862a0b2631785492f8dc20c8acd396646c545fd1), [c209dcb](https://github.com/morluto/rea/commit/c209dcb209118069f123e789949eeba1ef78853e), [6b1c36e](https://github.com/morluto/rea/commit/6b1c36e336eeacbb7159b211e687b4b84f99b9f5), [25c2222](https://github.com/morluto/rea/commit/25c22222abe7a681491bdb4d7316250fdcf32973), [d6e4fe4](https://github.com/morluto/rea/commit/d6e4fe4a4dd8914ec3db50d2a7fc3d0802649262), [#4131](https://github.com/morluto/rea/pull/4131), [morluto/rea#3909](https://github.com/morluto/rea/issues/3909)). Thanks @Adkid-Zephyr, @coygeek, @jackie-cqz, @kaoru0822-kitauji, @maxazure, @XY-code1.
- **Evidence and reconstruction:** Authenticate all retained inventory substeps, preserve source-attributed caveats in composed workflows, and require comparable cited Evidence before declaring reconstruction coverage or readiness. Missing Evidence and residual replay uncertainty stay explicit. ([9ac91e0](https://github.com/morluto/rea/commit/9ac91e0c1e13e91cd21341635ad5be89b0e8642d), [c4608a2](https://github.com/morluto/rea/commit/c4608a29620ea3e7bb8259b47357b942fe4e4709), [#4075](https://github.com/morluto/rea/pull/4075), [morluto/rea#3357](https://github.com/morluto/rea/issues/3357), [#3526](https://github.com/morluto/rea/pull/3526), [morluto/rea#3363](https://github.com/morluto/rea/issues/3363), [153017d](https://github.com/morluto/rea/commit/153017d750322188c1a112b2284c1b8065c67320)). Thanks @coygeek, @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0, @rudycelekli.
- **Offline data:** Preserve exact UTC packet-capture instants, SQLite column identity and snapshot admission failures, and cooked WASM directive literals. Cleanup cancellation retains completed EVM/WASM observations rather than losing them. ([796faa0](https://github.com/morluto/rea/commit/796faa0e4e6bf745bcdc33acef65af8ccfc3622d), [748ac7f](https://github.com/morluto/rea/commit/748ac7f0df340f0d0569eca2e803a59cd51ffdbd), [bc51d0e](https://github.com/morluto/rea/commit/bc51d0ea5df7dcee1fcc42dfae3ab0c62c9cca5e), [4f87f02](https://github.com/morluto/rea/commit/4f87f02bb19bf77349a683a5bcb2da2d1da427d0), [d694aef](https://github.com/morluto/rea/commit/d694aef227e90164e6654ea9e5ce6a854d099404), [321cacb](https://github.com/morluto/rea/commit/321cacb84a020f447e1110df5c58fa71d99b7bf1)). Thanks @himamaheswarreddy, @mertkayacs, @rollroyces, @viniciusdsandrade.
- **Kuna recovery:** Share concurrent single-function requests and cache repeats, validate warm exports once, stream string inventories beyond the former fixed buffer ceiling, and keep unproven processes in their run slots until close confirms release. Failure messages distinguish final buffer refusals from configurable deadlines. ([#4045](https://github.com/morluto/rea/pull/4045), [#4169](https://github.com/morluto/rea/pull/4169), [#4049](https://github.com/morluto/rea/pull/4049), [#4318](https://github.com/morluto/rea/pull/4318), [#4052](https://github.com/morluto/rea/pull/4052), [#4098](https://github.com/morluto/rea/pull/4098), [#4343](https://github.com/morluto/rea/pull/4343)). Thanks @kaoru0822-kitauji.
- **Flutter snapshots:** Check symbol-table ranges against loadable segments and retain completed inspection facts when cancellation occurs during snapshot cleanup. ([#3859](https://github.com/morluto/rea/pull/3859), [morluto/rea#3346](https://github.com/morluto/rea/issues/3346), [#4766](https://github.com/morluto/rea/pull/4766), [morluto/rea#4717](https://github.com/morluto/rea/issues/4717), [#4762](https://github.com/morluto/rea/pull/4762), [morluto/rea#4640](https://github.com/morluto/rea/issues/4640)). Thanks @coygeek, @kaoru0822-kitauji.
- **Native metadata recovery:** Keep unknown Objective-C category classes, empty protocol names, undecoded Swift aliases and unfinished property types explicit instead of discarding neighboring valid records. Preserve unnamed segment identity and exclude a dylib’s own install name from dependencies. ([#4093](https://github.com/morluto/rea/pull/4093), [morluto/rea#4012](https://github.com/morluto/rea/issues/4012), [#4078](https://github.com/morluto/rea/pull/4078), [morluto/rea#3873](https://github.com/morluto/rea/issues/3873), [#4085](https://github.com/morluto/rea/pull/4085), [morluto/rea#3934](https://github.com/morluto/rea/issues/3934), [#3825](https://github.com/morluto/rea/pull/3825), [morluto/rea#3345](https://github.com/morluto/rea/issues/3345), [#4051](https://github.com/morluto/rea/pull/4051), [morluto/rea#3875](https://github.com/morluto/rea/issues/3875), [#4050](https://github.com/morluto/rea/pull/4050), [morluto/rea#3872](https://github.com/morluto/rea/issues/3872)). Thanks @coygeek, @kaoru0822-kitauji.
- **Document selection:** Preserve explicitly selected plist paths and bundle defaults, and only use document fallback after confirming its applicability. Finalization keeps completed selection facts and cancellation outcomes. ([e6c4877](https://github.com/morluto/rea/commit/e6c487799bb64f559e66b69be1863e6ec5187548), [#3774](https://github.com/morluto/rea/pull/3774), [9df559b](https://github.com/morluto/rea/commit/9df559b7e712298a761ff26e9caae8d659b7e54b)). Thanks @kaoru0822-kitauji.
- **Capture and comparison accuracy:** Admit schema-valid HAR numeric values while retaining exact-publication limits, preserve empty URL path segments, and keep unrelated process traces and unnamed reference endpoints distinct or unknown. ([#3159](https://github.com/morluto/rea/pull/3159), [morluto/rea#3145](https://github.com/morluto/rea/issues/3145), [#3792](https://github.com/morluto/rea/pull/3792), [morluto/rea#3307](https://github.com/morluto/rea/issues/3307), [#4178](https://github.com/morluto/rea/pull/4178), [morluto/rea#3931](https://github.com/morluto/rea/issues/3931), [#3809](https://github.com/morluto/rea/pull/3809), [morluto/rea#3388](https://github.com/morluto/rea/issues/3388)). Thanks @coygeek, @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0, @pablodiazjorge, @xu91102.
- **Evidence publication:** Recheck staged output identity after its final write, classify missing review Evidence and duplicate ledger entries as caller input, and preserve the selected freshness requirement in comparison parameters. ([#4764](https://github.com/morluto/rea/pull/4764), [morluto/rea#4613](https://github.com/morluto/rea/issues/4613), [#4452](https://github.com/morluto/rea/pull/4452), [morluto/rea#4444](https://github.com/morluto/rea/issues/4444), [#4065](https://github.com/morluto/rea/pull/4065), [morluto/rea#4000](https://github.com/morluto/rea/issues/4000)). Thanks @amyanger, @coygeek, @kaoru0822-kitauji, @Rinkia, @Swatantra-66.
### ⚠ BREAKING CHANGES
- **Saved Evidence:** Evidence and analysis snapshots now require explicit nullable `relationship_coverage` in their identity commitments. Artifact inventories require scoped coverage and explicit `integrity_contradictions`; obsolete `coverage_status` and prose-based coverage inference are removed. Regenerate old Evidence/snapshots and inventory observations with this release: saved files are not migrated and omitted facts are not filled with guessed defaults. ([db8128d](https://github.com/morluto/rea/commit/db8128dc0d1c4f731f3d19877fa00d25cf17f657), [0405c9d](https://github.com/morluto/rea/commit/0405c9d361de6d904dfa16cc0b6d8350407f2c9b), [a9588be](https://github.com/morluto/rea/commit/a9588be4ebdd20eeda975cb63ffcdb1cd868b340)).
- **Browser capture results:** Consumers must retain resolved capture limits, event families and omission facts. Set desired budgets through the supported capture options; omitted caller inputs still select defaults, but stored observations must report the resolved values. Admitted content reads queue behind bounded concurrency. ([57a23f0](https://github.com/morluto/rea/commit/57a23f0a2da0fdc3835e203718ded8acea5a34e6)).
- **Android version codes:** `inspect_adb_package.version_code` is a decimal string rather than a JSON number. Read it as a string, or use `BigInt` for numeric comparison. ([#3485](https://github.com/morluto/rea/pull/3485), [morluto/rea#3368](https://github.com/morluto/rea/issues/3368), [7666a48](https://github.com/morluto/rea/commit/7666a482b69dc7cabdbac3bbaf89a43e32300192)). Thanks @coygeek, @kaoru0822-kitauji.
- **Native UI failures:** Failed or cancelled native UI scenarios now return typed errors with the collected report in `partial_observation`. Handle the error path and read that report instead of expecting a successful result containing failed steps. ([d909919](https://github.com/morluto/rea/commit/d9099190ab3a819bd3a9fd62a8714cef398016d5)).
- **Provider status:** `binary_session` candidate availability can be unknown during owner finalization. Preserve that state rather than treating it as unavailable; internal consumers must await the asynchronous session status API. ([150e996](https://github.com/morluto/rea/commit/150e996a86f2bec4982ba87f37bf502a8d5e8214)).
- **Swift symbol locations:** `swift_symbols` entries may have a null `address` when the provider supplies no location. Handle unknown addresses; optional `evidence.reported_address` retains the original provider value. ([8116dc0](https://github.com/morluto/rea/commit/8116dc06512b4609d8db63cebc9f2ff8cb964151)).
- **Linux Hopper admission:** Older builds previously admitted by a fixed allowlist need retained publisher-signed package evidence or an approved update to the current public demo. Update explicit `HOPPER_LAUNCHER_PATH` selections when migrating; the live feed offers only its current release. The official RPM metadata mismatch remains unresolved and is refused. ([#3590](https://github.com/morluto/rea/pull/3590), [morluto/rea#3577](https://github.com/morluto/rea/issues/3577), [70cd4cb](https://github.com/morluto/rea/commit/70cd4cbfb849b61f05d97d2690372a9782831426)). Thanks @gensokyo-dev, @kaoru0822-kitauji, @N0zoM1z0.
Full contribution record: [571 commits and 236 merged PRs](https://github.com/morluto/rea/blob/rea-agents-6.6.0/docs/releases/6.6.0.contributions.json).
## [6.5.0](https://github.com/morluto/rea/compare/rea-agents-6.4.0...rea-agents-6.5.0) (2026-10-13)
Provider prerequisites and recorded verification scope are listed in [the testing guide](docs/testing.md).
+3
View File
@@ -21,6 +21,9 @@ For analysis workflows and agent interfaces, follow the
[performance priorities](AGENTS.md#performance). Explain the selected output
scope, reuse/cache decisions, and relevant before/after measurements when these
costs change.
Use the [analysis optimization skill](.agents/skills/rea-analysis-optimization/SKILL.md)
to locate provider and shared-workflow bottlenecks, preserve Evidence, and
compare equivalent real tasks before claiming an improvement.
When adding or changing an MCP tool, follow the [tool design guide](docs/tool-design.md) and preserve the canonical contracts and generated catalog.
+10 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
**English** · [简体中文](docs/readme/README_zh.md) · [繁體中文](docs/readme/README_zh-TW.md) · [日本語](docs/readme/README_ja.md) · [한국어](docs/readme/README_ko.md) · [Türkçe](docs/readme/README_tr.md) · [Русский](docs/readme/README_ru.md) · [Tiếng Việt](docs/readme/README_vi.md) · [ไทย](docs/readme/README_th.md) · [Deutsch](docs/readme/README_de.md) · [Español](docs/readme/README_es.md) · [Français](docs/readme/README_fr.md) · [Українська](docs/readme/README_uk.md) · [Polski](docs/readme/README_pl.md) · [Português (Brasil)](docs/readme/README_pt-BR.md) · [العربية](docs/readme/README_ar.md) · [فارسی](docs/readme/README_fa.md) · [Bahasa Indonesia](docs/readme/README_id.md) · [Italiano](docs/readme/README_it.md)
· [Ελληνικά](docs/readme/README_el.md)
· [Ελληνικά](docs/readme/README_el.md) · [മലയാളം](docs/readme/README_ml.md)
# REA: Reverse Engineer Anything
@@ -132,6 +132,14 @@ For a CLI installed with `npm install --global` or `bun add --global`:
rea update
```
`rea --update` is an alias for this verified workflow and accepts the same global
output flags. Use `rea update` when combining it with other command controls.
Updater commands retain at most 4 MiB of stdout and stderr combined. Oversized
metadata replies are rejected after the command exits; verbose installs continue
with bounded diagnostics. Human progress output respects terminal backpressure
and waits for submitted writes to finish.
Bun global updates require Bun 1.2.17 or later. With an older Bun release,
upgrade Bun manually before running `rea update`.
@@ -345,7 +353,7 @@ Report vulnerabilities through [SECURITY.md](SECURITY.md).
## Star history
🎉 **250,000 GitHub stars — thank you!**
🎉 **300,000 GitHub stars — thank you!**
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
+167 -23
View File
@@ -15,11 +15,14 @@ import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
import kotlin.Unit;
import kotlin.ResultKt;
import kotlin.coroutines.Continuation;
import kotlin.coroutines.CoroutineContext;
import kotlin.coroutines.EmptyCoroutineContext;
import kotlin.coroutines.intrinsics.IntrinsicsKt;
import kotlinx.coroutines.BuildersKt;
import kotlinx.io.CoreKt;
import kotlinx.io.JvmCoreKt;
import kotlinx.serialization.json.JsonObject;
/** REA-owned metadata boundary for the unmodified jadx-headless-mcp 0.7.1 JAR. */
class ReaJadxBridge {
@@ -28,7 +31,8 @@ class ReaJadxBridge {
private JadxSession indexedSession;
private Map<String, List<ClassSnapshot>> classes = Map.of();
private record MethodSnapshot(String name, String shortId, Map<String, Object> summary) {}
private record MethodSnapshot(String name, String rawName, String shortId, List<String> bodyAbsenceMarkers,
Map<String, Object> summary) {}
private record ClassSnapshot(JavaClass node, List<MethodSnapshot> methods, Map<String, Object> summary) {}
private static final class InputFailure extends IllegalArgumentException {
@@ -44,15 +48,93 @@ class ReaJadxBridge {
private static CallToolResult json(Object value) { return text(JSON.toJson(value), false); }
/** Translate the typed load outcome before upstream drops its exception identity. */
static Object loadResult(Object result) {
try { ResultKt.throwOnFailure(result); }
catch (Throwable failure) {
if (failure instanceof java.util.concurrent.CancellationException
|| failure instanceof Error && !(failure instanceof OutOfMemoryError)) return result;
if (failure instanceof OutOfMemoryError) {
String reason = failure.getMessage();
boolean heap = "Java heap space".equals(reason) || "GC overhead limit exceeded".equals(reason);
Map<String, Object> reply = new LinkedHashMap<>();
reply.put("kind", "jvm-memory-failure");
reply.put("memory_area", heap ? "heap" : "unknown");
reply.put("exception_type", "java.lang.OutOfMemoryError");
if (reason != null) reply.put("message", reason);
reply.put("max_heap_bytes", Runtime.getRuntime().maxMemory());
return text(JSON.toJson(reply), true);
}
return text("load failed: " + failure.getMessage(), true);
}
SessionHolder.LoadResult loaded = (SessionHolder.LoadResult) result;
Map<String, Object> reply = new LinkedHashMap<>();
reply.put("state", "LOADED");
reply.put("apk_path", loaded.getApkPath());
reply.put("class_count", loaded.getClassCount());
reply.put("raw_class_count", loaded.getRawClassCount());
reply.put("resource_count", loaded.getResourceCount());
reply.put("load_duration_ms", loaded.getLoadDurationMs());
reply.put("decompile_timeout_ms", loaded.getDecompileTimeoutMs());
reply.put("threads", loaded.getThreads());
reply.put("code_cache_size", loaded.getCodeCacheSize());
reply.put("resources", loaded.getResourceMode());
if (!loaded.getIncludePackages().isEmpty()) reply.put("include_packages", loaded.getIncludePackages());
if (!loaded.getExcludePackages().isEmpty()) reply.put("exclude_packages", loaded.getExcludePackages());
return json(reply);
}
private Object load(kotlinx.serialization.json.JsonObject arguments, SessionConfig defaults,
Continuation<? super CallToolResult> continuation) {
JsonObject args = JsonParser.parseString(arguments.toString()).getAsJsonObject();
String path = string(args, "path");
SessionConfig options = defaults.withLoadOverrides(
optionalString(args, "include_packages"), optionalString(args, "exclude_packages"),
args.has("threads") ? integer(args, "threads", 1) : null,
args.has("code_cache_size") ? integer(args, "code_cache_size", 64) : null,
optionalString(args, "resources"));
return loadCall(next -> holder.load(path, options, next), continuation);
}
static Object loadCall(kotlin.jvm.functions.Function1<Continuation<SessionHolder.LoadResult>, Object> load,
Continuation<? super CallToolResult> continuation) {
var forwarded = new java.util.concurrent.atomic.AtomicBoolean();
Continuation<SessionHolder.LoadResult> resumed = new Continuation<>() {
public CoroutineContext getContext() { return continuation.getContext(); }
public void resumeWith(Object result) {
if (!forwarded.compareAndSet(false, true)) throw new IllegalStateException("Load resumed twice");
Object translated;
try { translated = loadResult(result); }
catch (Throwable failure) { translated = ResultKt.createFailure(failure); }
// Keep the consumer outside the translation catch, including inline completion.
continuation.resumeWith(translated);
}
};
Object result;
try { result = load.invoke(resumed); }
catch (Throwable failure) {
if (forwarded.get()) ResultKt.throwOnFailure(ResultKt.createFailure(failure));
result = ResultKt.createFailure(failure);
}
if (result == IntrinsicsKt.getCOROUTINE_SUSPENDED()) return result;
Object translated = loadResult(result);
ResultKt.throwOnFailure(translated);
return translated;
}
private static String optionalString(JsonObject args, String name) {
return args.has(name) ? string(args, name) : null;
}
private static String string(JsonObject args, String name) {
JsonElement value = JsonParser.parseString(args.toString()).getAsJsonObject().get(name);
JsonElement value = args.get(name);
if (value == null || !value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString())
throw new IllegalArgumentException(name + " must be a string");
return value.getAsString();
}
private static int integer(JsonObject args, String name, int fallback) {
JsonElement value = JsonParser.parseString(args.toString()).getAsJsonObject().get(name);
JsonElement value = args.get(name);
if (value == null) return fallback;
if (!value.isJsonPrimitive() || !value.getAsJsonPrimitive().isNumber())
throw new IllegalArgumentException(name + " must be a nonnegative integer");
@@ -90,10 +172,13 @@ class ReaJadxBridge {
if (!shortId.startsWith(rawName + "("))
throw new IllegalStateException("JADX method ID has no raw-name prefix: " + shortId);
String descriptor = shortId.substring(rawName.length());
List<String> bodyAbsenceMarkers = new ArrayList<>();
if (method.getAccessFlags().isNative()) bodyAbsenceMarkers.add("native_method");
if (method.getAccessFlags().isAbstract()) bodyAbsenceMarkers.add("abstract_method");
String signature = name + "(" + method.getArgTypes().stream()
.map(Object::toString).collect(Collectors.joining(", "))
+ "): " + method.getReturnType().toString();
return new MethodSnapshot(name, shortId, Map.of(
return new MethodSnapshot(name, rawName, shortId, List.copyOf(bodyAbsenceMarkers), Map.of(
"name", name, "signature", signature,
"dex_descriptor", descriptor,
"is_constructor", method.isConstructor(), "def_pos", 0));
@@ -140,16 +225,52 @@ class ReaJadxBridge {
private JadxSession.SmartCode methodBody(JadxSession current, ClassSnapshot cls,
MethodSnapshot selected, JavaMethod method) {
if (!selected.shortId().equals("<clinit>()V"))
return current.getMethodBodySmart(method, current.getMaxSourceBytes(), true);
// Access flags belong to the parsed member, before code generation rewrites it.
// These methods have no Java body; source slicing can include unrelated members.
if (!selected.bodyAbsenceMarkers().isEmpty())
return new JadxSession.SmartCode("", "java", false, selected.bodyAbsenceMarkers());
// Java code generation can fold all or part of <clinit> into field declarations.
// Its method text cannot establish coverage, even when a static block remains.
JadxSession.MethodSmali smali = current.getMethodSmali(cls.node(), method.getName());
if (!smali.getFound() || smali.getBlocks().size() != 1)
throw new IllegalArgumentException("Static initializer disassembly requires one exact method: " + selected.shortId());
if (selected.shortId().equals("<clinit>()V"))
return exactMethodSmali(current, cls, selected, List.of("static_initializer_disassembly"));
String java = current.getMethodSource(method);
if (java.startsWith("// ERROR:")) throw new IllegalArgumentException(java);
// The upstream placeholder means only that Java code was omitted, including
// methods merged into synthetic bridges. Access flags established absence above.
if (java.isEmpty() || java.equals(
"// method exists but has no decompiled body (native/abstract)"))
return exactMethodSmali(current, cls, selected, List.of("java_body_unavailable"));
List<String> markers = DecompileFailureKt.detectDecompileFailure(java);
if (markers.stream().anyMatch(DecompileFailureKt.getSTRONG_FAILURE_MARKERS()::contains))
return exactMethodSmali(current, cls, selected, markers);
return new JadxSession.SmartCode(
TextUtilKt.truncateToBytes(smali.getBlocks().get(0), current.getMaxSourceBytes()),
"smali", true, List.of("static_initializer_disassembly"));
TextUtilKt.truncateToBytes(java, current.getMaxSourceBytes()), "java", false, markers);
}
private JadxSession.SmartCode exactMethodSmali(JadxSession current, ClassSnapshot cls,
MethodSnapshot selected, List<String> markers) {
JadxSession.MethodSmali smali = current.getMethodSmali(cls.node(), selected.rawName());
String block = selectMethodSmali(smali, selected.shortId());
return new JadxSession.SmartCode(
TextUtilKt.truncateToBytes(block, current.getMaxSourceBytes()), "smali", true, markers);
}
private static String selectMethodSmali(JadxSession.MethodSmali smali, String shortId) {
if (!smali.getFound())
throw new IllegalArgumentException("JADX could not disassemble " + shortId
+ (smali.getNote() == null ? "" : ": " + smali.getNote()));
// Upstream returns every same-name overload, and can return an unterminated
// trailing block. Match the full original identity before applying output limits.
List<String> matches = smali.getBlocks().stream().filter(block -> {
String header = block.lines().findFirst().orElse("").strip();
return header.startsWith(".method ") && header.endsWith(" " + shortId);
}).toList();
if (matches.size() != 1)
throw new IllegalArgumentException("Disassembly could not establish one selected method: " + shortId);
String block = matches.get(0);
if (!block.stripTrailing().endsWith("\n.end method"))
throw new IllegalArgumentException("Selected method disassembly is incomplete: " + shortId);
return block;
}
// The local transport admits 8 MiB frames. Reserve 1 KiB for the fixed
@@ -203,7 +324,8 @@ class ReaJadxBridge {
return new DirectInvokes(sites, exhaustive[0]);
}
private CallToolResult handle(String name, JsonObject args) {
private CallToolResult handle(String name, kotlinx.serialization.json.JsonObject input) {
JsonObject args = JsonParser.parseString(input.toString()).getAsJsonObject();
if (name.equals("rea_jvm_status")) return json(Map.of(
"engine_reported_version", BuildInfo.VERSION,
"max_heap_bytes", Runtime.getRuntime().maxMemory(),
@@ -213,12 +335,25 @@ class ReaJadxBridge {
JadxSession current = session();
if (name.equals("list_classes")) {
List<String> names = current.getClassFqns();
String query = args.has("query") ? string(args, "query") : "";
int offset = integer(args, "offset", 0);
int limit = integer(args, "limit", 200);
int start = Math.min(offset, names.size());
int end = (int) Math.min((long) start + limit, names.size());
return json(Map.of("total", names.size(), "offset", offset, "limit", limit,
"items", names.subList(start, end)));
int end = start;
List<String> items;
if (query.isEmpty()) {
end = (int) Math.min((long) start + limit, names.size());
items = names.subList(start, end);
} else {
items = new ArrayList<>();
while (end < names.size() && items.size() < limit) {
String nameInInventory = names.get(end++);
if (nameInInventory.contains(query)) items.add(nameInInventory);
}
}
return json(Map.of("total_classes", names.size(), "next_offset", end,
"scope", "top_level", "offset", offset, "limit", limit,
"items", items));
}
ClassSnapshot cls = selected(args);
if (name.equals("get_class_summary")) return json(cls.summary());
@@ -230,6 +365,7 @@ class ReaJadxBridge {
JadxSession.SmartCode code = methodBody(current, cls, overloads.get(index), method);
return json(Map.of("class_name", cls.summary().get("full_name"),
"method_name", overloads.get(index).name(), "full_name", method.getFullName(),
"dex_descriptor", overloads.get(index).summary().get("dex_descriptor"),
"overload_index", index, "overload_count", overloads.size(),
"mode", code.getKind(), "fell_back", code.getFellBack(),
"markers", code.getMarkers(), "body", code.getText()));
@@ -241,7 +377,7 @@ class ReaJadxBridge {
if (name.equals("get_xrefs_to_class")) uses = cls.node().getUseIn();
else {
List<MethodSnapshot> overloads = methods(cls, args);
if (overloads.size() != 1 && !args.containsKey("overload_index"))
if (overloads.size() != 1 && !args.has("overload_index"))
throw new InputFailure("overload_index", "Select one of " + overloads.size() + " method overloads");
overloadIndex = integer(args, "overload_index", 0);
if (overloadIndex >= overloads.size())
@@ -287,11 +423,12 @@ class ReaJadxBridge {
public static void main(String[] args) throws Exception {
PrintStream protocolOut = System.out;
System.setOut(System.err);
SessionHolder holder = new SessionHolder(new SessionConfig(
1048576, 0, 90000L, 1, List.of(), List.of(), 64, ResourceMode.FULL));
SessionConfig defaults = new SessionConfig(
1048576, 0, 90000L, 1, List.of(), List.of(), 64, ResourceMode.FULL);
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", "1", null, null, null),
Server server = new Server(new Implementation("rea-jadx-bridge", "4", null, null, null),
new ServerOptions(capabilities), "", ignored -> Unit.INSTANCE);
SessionToolsKt.registerSessionTools(server, holder);
ManifestToolsKt.registerManifestTools(server, holder);
@@ -299,13 +436,17 @@ class ReaJadxBridge {
MethodToolsKt.registerMethodTools(server, holder);
XrefToolsKt.registerXrefTools(server, holder);
ReaJadxBridge bridge = new ReaJadxBridge(holder);
Tool loadTool = server.getTools().get("load_apk").getTool();
server.removeTool("load_apk");
server.addTool(loadTool, (connection, request, continuation) ->
bridge.load(request.getArguments(), defaults, continuation));
Set<String> consumed = Set.of("load_apk", "get_app_info", "get_android_manifest",
"list_classes", "get_class_summary", "get_method_body",
"get_xrefs_to_class", "get_xrefs_to_method");
for (String name : new ArrayList<>(server.getTools().keySet()))
if (!consumed.contains(name)) server.removeTool(name);
Tool diagnostics = new Tool("rea_jvm_status",
new ToolSchema(null, new JsonObject(Map.of()), List.of(), null),
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()));
for (String name : List.of("list_classes", "get_class_summary",
@@ -320,13 +461,16 @@ class ReaJadxBridge {
};
Map<String, kotlinx.serialization.json.JsonElement> properties = new LinkedHashMap<>();
for (String field : fields) properties.put(field, tool.getInputSchema().getProperties().get(field));
if (name.equals("list_classes")) properties.put("query",
new kotlinx.serialization.json.JsonObject(Map.of(
"type", kotlinx.serialization.json.JsonElementKt.JsonPrimitive("string"))));
String description = switch (name) {
case "list_classes" -> "Indexed pages of all top-level class names, with offset and limit.";
case "list_classes" -> "Pages of case-sensitive matching top-level class names; offset and next_offset are inventory positions, limit bounds matching rows. Omitted or empty query inventories all names.";
case "get_class_summary" -> "Parsed member metadata for one exact class name; no source generation.";
case "get_method_body" -> "Source for an exact class and stable same-name overload index; static initializers use smali to preserve folded field initialization.";
default -> "Complete static using-node inventory for an exact class or selected method overload; one node may contain multiple invoke instructions, and source lines are unresolved.";
};
Tool narrowed = new Tool(name, new ToolSchema(null, new JsonObject(properties),
Tool narrowed = new Tool(name, new ToolSchema(null, new kotlinx.serialization.json.JsonObject(properties),
tool.getInputSchema().getRequired(), null), description, null, null, null, null, null, null);
server.addTool(narrowed, (connection, request, continuation) -> {
try { return bridge.handle(name, request.getArguments()); }
+13 -5
View File
@@ -783,14 +783,22 @@ def _within_response_limit(value: Any) -> bool:
current = pending.pop()
if isinstance(current, str):
size += 2
if len(current) > MAX_FRAME_BYTES - size:
return False
if current.isascii():
size += len(current)
size += current.count('"') + current.count("\\")
size += sum(5 for character in current if ord(character) < 0x20)
else:
size += 4 * len(current)
size += current.count('"') + current.count("\\")
size += sum(5 for character in current if ord(character) < 0x20)
# Count UTF-8 bytes without allocating a copy of the whole output.
try:
size += sum(
len(current[start:start + 65536].encode("utf-8"))
for start in range(0, len(current), 65536)
)
except UnicodeEncodeError:
# Unencodable output also needs the signed omission fallback.
return False
size += current.count('"') + current.count("\\")
size += sum(5 for character in current if ord(character) < 0x20)
elif isinstance(current, dict):
identity = id(current)
if identity in seen:
+18
View File
@@ -140,6 +140,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
"params"
);
private static final String[] CAPABILITIES = {
"read_binary_inventory_summary",
"annotate_native_function",
"set_address_name",
"set_addresses_names",
@@ -427,6 +428,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
);
}
return switch (request.method) {
case "read_binary_inventory_summary" -> binaryInventorySummary(request.params);
case "inspect_native_load_image" -> inspectNativeLoadImage(request.params);
case "read_bytes" -> readMemoryBytes(request.params);
case "search_bytes" -> searchMemoryBytes(request.params, descriptor);
@@ -1974,6 +1976,18 @@ public final class ReaGhidraBridge extends HeadlessScript {
return result;
}
private JsonObject binaryInventorySummary(JsonObject params) throws Exception {
requireKeys(params, Set.of());
JsonObject result = new JsonObject();
result.addProperty("document", currentProgram.getName());
result.add("segments", segments());
// Count the owning inventories, preserving their exact discovery rules
// without serializing function identities or string values for counts.
result.addProperty("procedure_count", procedures().size());
result.addProperty("string_count", strings().size());
return result;
}
private JsonArray listNames(JsonObject params) throws Exception {
requireKeys(params, Set.of("document", "address"));
requireDocument(params);
@@ -2000,6 +2014,10 @@ public final class ReaGhidraBridge extends HeadlessScript {
private JsonArray listSegments(JsonObject params) {
requireKeys(params, Set.of("document"));
requireDocument(params);
return segments();
}
private JsonArray segments() {
JsonArray result = new JsonArray();
String imageBase = canonicalAddress(currentProgram.getImageBase());
MemoryBlock[] blocks = currentProgram.getMemory().getBlocks();
+15 -2
View File
@@ -20,8 +20,9 @@ def inspect(request):
root = Path(os.environ["REA_CORE_CONTEXT_REQUEST"]).parent
empty = root / "no-libraries"
empty.mkdir(mode=0o700)
for command in ["set auto-load off", "set debuginfod enabled off", "set auto-solib-add off", "set history save off", "set pagination off",
"set sysroot ./no-libraries", "set solib-search-path ./no-libraries"]:
for command in ["set auto-load off", "set debuginfod enabled off", "set auto-solib-add off", "set history save off", "set pagination off", "set target-file-system-kind unix",
"set sysroot ./no-libraries", "set solib-search-path ./no-libraries",
"set debug-file-directory ./no-libraries"]:
gdb.execute(command, to_string=True)
entry = request["gdbinit"]
try:
@@ -38,7 +39,19 @@ def inspect(request):
# relative filename in the owned cwd so no selected path becomes GDB syntax.
if Path(request["snapshot_path"]) != root.parent / "object.snapshot":
raise ContextFailure("decoder", "Core context request did not select the shared owned snapshot.")
# GDB 16 searches AT_EXECFN/NT_FILE outside sysroot when no executable BFD
# is selected. Occupy that slot with the already running, owned debugger;
# exec-file loads no symbols and never runs it. Clear it before any query.
# /proc/self/exe identifies this process, not the core's historical PID.
architecture = {"x86_64-little-endian": "i386:x86-64", "aarch64-little-endian": "aarch64"}.get(request["architecture"])
if architecture is None:
raise ContextFailure("unsupported", "Unsupported recorded core architecture.")
gdb.execute("exec-file /proc/self/exe", to_string=True)
# The placeholder must not select the core's architecture. Reuse the
# decoder's validated profile, including for cross-architecture GDB builds.
gdb.execute("set architecture " + architecture, to_string=True)
gdb.execute("core-file ../object.snapshot", to_string=True)
gdb.execute("file", to_string=True)
inferior = gdb.selected_inferior()
if inferior.connection is None or inferior.connection.type != "core" or gdb.current_progspace().filename is not None:
raise ContextFailure("decoder", "Requested core-only boundary was not established; no mapping query performed.")
+117
View File
@@ -0,0 +1,117 @@
"""Producer regressions with controlled GDB state, not native debugger qualification."""
import json
import os
from pathlib import Path
import runpy
import sys
import tempfile
import types
import unittest
from unittest.mock import patch
BRIDGE = Path(__file__).with_name("core_context.py")
class CoreContextTests(unittest.TestCase):
def inspect(self, failure=None, connection="core", symbols=None, architecture="x86_64-little-endian"):
commands, reads, queries = [], [], []
state = {"executable": None, "symbols": None, "connection": None}
gdb = types.ModuleType("gdb")
gdb.VERSION = "16.3"
gdb.selected_inferior = lambda: types.SimpleNamespace(
connection=state["connection"], pid=123)
gdb.current_progspace = lambda: types.SimpleNamespace(filename=state["symbols"])
def execute(command, to_string):
self.assertTrue(to_string)
commands.append(command)
if command == failure:
raise RuntimeError("controlled command failure")
if command == "exec-file /proc/self/exe":
state["executable"] = "/proc/self/exe"
elif command == "core-file ../object.snapshot":
if state["executable"] is None:
reads.append("recorded-executable")
state["executable"] = state["symbols"] = "recorded-executable"
state["connection"] = types.SimpleNamespace(type=connection)
elif command == "file":
state["executable"] = None
state["symbols"] = symbols
gdb.execute = execute
pwndbg = types.ModuleType("pwndbg")
pwndbg.aglib = types.ModuleType("pwndbg.aglib")
pwndbg.aglib.vmmap = types.ModuleType("pwndbg.aglib.vmmap")
pwndbg.lib = types.ModuleType("pwndbg.lib")
pwndbg.lib.version = types.ModuleType("pwndbg.lib.version")
pwndbg.lib.version.__version__ = "2026.09.15"
def maps():
self.assertIsNone(state["executable"], "Helper executable must be discarded before mapping queries")
queries.append("maps")
return [types.SimpleNamespace(start=4096, end=8192, offset=0, flags=5, objfile="recorded-executable")]
pwndbg.aglib.vmmap.get = maps
modules = {module.__name__: module for module in [
gdb, pwndbg, pwndbg.aglib, pwndbg.aglib.vmmap, pwndbg.lib, pwndbg.lib.version]}
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
stage = root / "debugger"
stage.mkdir()
plugin = root / "gdbinit.py"
plugin.write_text("")
request = stage / "request.json"
reply = stage / "reply.json"
request.write_text(json.dumps({"gdbinit": str(plugin), "architecture": architecture, "snapshot_path": str(root / "object.snapshot"), "reply_path": str(reply)}))
with patch.dict(sys.modules, modules), patch.dict(os.environ, REA_CORE_CONTEXT_REQUEST=str(request)):
runpy.run_path(str(BRIDGE))
result = json.loads(reply.read_text())
return result, commands, reads, queries
def test_core_load_never_opens_recorded_executable_and_queries_only_after_discard(self):
result, commands, reads, queries = self.inspect()
self.assertTrue(result["ok"], result)
self.assertEqual(reads, [])
self.assertEqual(queries, ["maps"])
self.assertEqual(commands[-4:], ["exec-file /proc/self/exe", "set architecture i386:x86-64", "core-file ../object.snapshot", "file"])
self.assertLess(commands.index("set debug-file-directory ./no-libraries"), commands.index("core-file ../object.snapshot"))
self.assertIsNone(result["value"]["executable"])
self.assertEqual(result["value"]["maps"][0]["current_file_identity"], "unknown")
def test_failed_guard_core_load_or_discard_never_queries_mappings(self):
for command in ["exec-file /proc/self/exe", "set architecture i386:x86-64", "core-file ../object.snapshot", "file"]:
with self.subTest(command=command):
result, commands, reads, queries = self.inspect(failure=command)
self.assertFalse(result["ok"])
self.assertEqual(reads, [])
self.assertEqual(queries, [])
if command in ["exec-file /proc/self/exe", "set architecture i386:x86-64"]:
self.assertNotIn("core-file ../object.snapshot", commands)
def test_cross_architecture_uses_the_validated_decoder_profile(self):
result, commands, reads, queries = self.inspect(architecture="aarch64-little-endian")
self.assertTrue(result["ok"], result)
self.assertEqual(reads, [])
self.assertEqual(queries, ["maps"])
self.assertLess(commands.index("set architecture aarch64"), commands.index("core-file ../object.snapshot"))
def test_unknown_architecture_refuses_before_loading_core(self):
result, commands, reads, queries = self.inspect(architecture="unknown")
self.assertFalse(result["ok"])
self.assertEqual(result["reason"], "unsupported")
self.assertNotIn("core-file ../object.snapshot", commands)
self.assertEqual(reads, [])
self.assertEqual(queries, [])
def test_wrong_connection_or_remaining_symbols_never_queries_mappings(self):
for options in [{"connection": "native"}, {"symbols": "unexpected-symbols"}]:
with self.subTest(options=options):
result, _, reads, queries = self.inspect(**options)
self.assertFalse(result["ok"])
self.assertEqual(reads, [])
self.assertEqual(queries, [])
if __name__ == "__main__":
unittest.main()
+14 -6
View File
@@ -98,16 +98,24 @@ existing analysis families directly, for example
| `collect_adb_bugreport` | read | Device-generated bugreport zip, digested |
| `push_adb_file` | **mutates device** | One local file to a device path (e.g. pushing tools into `/data/local/tmp`); checks for existing targets and refuses them without explicit overwrite (the check is not atomic); compares digests when device `sha256sum` is available |
| `install_adb_package` | **mutates device** | Local APK via `adb install [-r]`; preserves its Success/Failure verdict, records `replace_requested`, and leaves actual replacement `null` because prior package state is not observed |
| `uninstall_adb_package` | **mutates device** | Removes a package and its data for user 0 |
| `uninstall_adb_package` | **mutates device** | Requests package removal for user 0 via `adb shell pm uninstall --user 0`, without data retention |
| `start_adb_app` | **mutates device** | Resolves the package's launcher activity (`cmd package resolve-activity --brief`) and starts it (`am start -n`) |
| `start_adb_activity` | **mutates device** | Starts an intent (`am start -a` with optional URI, component, and up to 16 typed extras); preserves the activity manager's verdict |
| `stop_adb_app` | **mutates device** | Force-stops every process of a package, ending a dynamic-analysis run |
For `inspect_adb_window`, an explicitly printed null focus reference becomes
JSON `null`. `observed_lines` retains the original focus declarations, including
their field names, so explicit absence can be distinguished from omitted
declarations. REA reads the displays section only when the windows section
declares neither focus field. If both sections omit them, focus remains unknown.
For `inspect_adb_window`, `focus_contexts` retains each display header, its exact
display ID when recognized, and every focus declaration with its original line.
Declarations without a display header are explicitly `unscoped`. A missing
declaration differs from a declaration whose `value` is JSON `null`.
`source_section` identifies the selected dumpsys section; `observed_lines`
preserves its focus declarations and display headers in source order.
`focus_summary` is `single_context` only for one context with no repeated focus
field. The singular `focused_window` and `focused_app` summarize that context;
they do not establish device-wide focus. Multiple contexts or repeated fields
produce `ambiguous` with null singular fields and all declarations retained.
When no focus field was declared, the status is `unavailable`. REA reads the
displays section only when the windows section declares neither focus field.
For `install_adb_package`, `replace_requested` records whether `-r` was sent.
The `replaced` result is `null`: the successful install response does not say
+37 -11
View File
@@ -103,9 +103,10 @@ that every class or engine operation will load successfully. Discovery limits
each ZIP metadata read to 8 MiB before allocation; a larger directory reports
the exhausted read budget and the selected JAR path.
The current metadata bridge is verified on macOS arm64 with OpenJDK 21 and the
public Appium ApiDemos fixture. The POSIX adapter also supports Linux; the new
bridge has not yet undergone real verification on Linux/JDK 25.
The filtered class-page bridge (protocol 2) is verified on Linux x86-64 with
Temurin 21, public Appium ApiDemos 6.0.18 and NewPipe 0.29.1 APKs. Earlier
metadata-bridge records covered macOS arm64/OpenJDK 21 and Windows x64/JDK 21;
this protocol revision has not been rerun on those hosts or Linux/JDK 25.
Windows x64 uses an owned Job Object with bidirectional stdio, atomic job
assignment and kill-on-owner-close. Real Windows verification uses JDK 21 and
the pinned JADX 0.7.1 JAR; see the real verification lane below.
@@ -146,10 +147,20 @@ queries accept the same `overload_index`; the bridge resolves the selected
method node and the result reports its index and displayed signature. These
indices are tied to the current artifact and engine, not stable across builds.
The engine's smali fallback also joins same-name overloads; REA rejects that
fallback for an overloaded method instead of attributing all bodies to one
selected overload. Native/abstract methods with no decompiled body report
`body_status: "not_available"` without inferring which implementation flag caused it.
Smali fallbacks select one complete block using the original method name and DEX
descriptor, before applying the source byte limit. This preserves the selected
overload even when Java code generation renames a method. If the selected Java
body was omitted, including a method merged into a synthetic bridge, REA returns
its original smali with the `java_body_unavailable` marker. The marker describes
missing Java; it does not infer why the method was omitted or name a replacement.
Unresolved or duplicate disassembly identities fail instead of attributing another
method's instructions to the selection.
Native and abstract methods are identified from access flags
captured before code generation. They report `body_status: "not_available"`, an
empty source, and the `native_method` or `abstract_method` marker; their declarations
are not passed through the engine's source slicer. Other missing decompiled bodies
do not establish either access flag.
Static initializers (`<clinit>`) return smali with the
`static_initializer_disassembly` marker. Java decompilation can move their
@@ -163,7 +174,10 @@ the same source byte limit and explicit truncation reporting.
permissions and class/resource counts. Summary fields are extracted by the
upstream engine and should be checked against the retained XML when needed.
Signature verification is explicitly `not_performed`.
- Class search consumes all pages and checks their counts. An empty `query`
- Class search filters the engine's cached top-level names before transferring
pages, then follows contiguous inventory positions without rescanning earlier
rows. It checks selection, scope, examined ranges and counts before reporting
complete coverage. Complete producer replies stay in Evidence; an empty `query`
inventories all class-name rows; class names are decompiler representations.
Repeated names remain repeated in `matches` so the inventory row count and
producer evidence stay visible. `duplicate_names` identifies matching names
@@ -233,8 +247,12 @@ rea project-android-application-graph '{"inventory_evidence":[<inventory_artifac
```
The projection reports exact component paths and hashes, runtime-family hints,
and path-based bridge hypotheses. It does not decode DEX or claim observed
runtime calls. Framework hints match complete native library names, such as
and path-based bridge hypotheses. File and slice occurrences supply component
endpoints; directory trees and symlinks retain their identities in the source
inventory without being classified as code files. It does not decode DEX or
claim observed runtime calls. DEX/JVM runtime hints summarize the classified
bytecode component lists. Framework hints match complete native library names,
such as
`libreactnativejni.so`, `libreactnative.so`, `libhermes.so`,
`libhermes_executor.so`, `libflutter.so`, and `libunity.so`; unrelated names
such as `libcommunity.so` and `libreactivity.so` do not identify those families.
@@ -299,7 +317,15 @@ settings. Evidence reports the worker's observed `Runtime.maxMemory()` rounded
down to MiB and retains exact bytes, Java version and visible processors in its
raw runtime response. The observed allocatable heap can differ from configured
`-Xmx`, especially with Serial GC. Heap is not a total RSS cap: the JVM also
uses native memory. Independent REA instances have independent queues. Whole
uses native memory. A typed JVM memory allocation failure during APK loading
reports `resource_constraint` with the observed maximum heap in bytes. Known
heap failures name `REA_JADX_HEAP_MIB` in remediation; other memory regions
remain unknown. A healthy doctor configuration check does not establish that
any particular APK fits. Failures before the bridge can report a typed result
and upstream errors from other operations retain their existing diagnostics;
error text alone does not establish memory exhaustion.
Independent REA instances have independent queues. Whole
operations have a **120-second** execution deadline by default, starting after
they reach the queue's front. For a known slow cold load, such as a large
multidex APK, select another finite deadline:
+57 -8
View File
@@ -24,6 +24,30 @@ missing launcher reports `capability_unavailable` with the
`binary_session` uses the same host probe for tool availability; it does not
validate a particular APK or guarantee that the selected input can be decoded.
Client inspection and decode results disclose the following reported-version
advisory windows without refusing otherwise compatible launchers:
| Advisory | Reported version window | Host scope |
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ---------- |
| [CVE-2024-21633](https://github.com/iBotPeaches/Apktool/security/advisories/GHSA-2hqv-2xv4-5h5w) | Before 2.9.2 | All |
| [GHSA-vgwr-4w3p-xmjv](https://github.com/iBotPeaches/Apktool/security/advisories/GHSA-vgwr-4w3p-xmjv) | Before 2.9.3 | Windows |
| [CVE-2026-39973](https://github.com/iBotPeaches/Apktool/security/advisories/GHSA-m8mh-x359-vm8m) | 3.0.0 release line through versions before 3.0.2 | All |
The 2026 advisory names 3.0.1 and its 3.0.2 fix. Inclusion of 3.0.0 is
source-derived: [tagged 3.0.0](https://github.com/iBotPeaches/Apktool/blob/f770b39e425af4fa6ac4ca1e9ea6c4824339c6d3/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResTypeSpec.java)
passes type names through unchanged; the [3.0.2 patch](https://github.com/iBotPeaches/Apktool/commit/65dd8480dfcb63068562ffaa527f71bb0a9f772c)
validates those names at their owner before they reach the output-path producer.
Prereleases before the fixed release are conservatively disclosed; the exact
`-dirty` downstream marker is compared as a release while preserving its spelling.
This is version guidance, not verification of a particular prerelease or decoder.
A launcher version does not prove the decoder's contents, execution platform,
downstream backports, or overall safety. Windows applicability uses the selected
local host; an opaque wrapper may run another engine. A missing warning means
only that none of these version/host windows matched. Verify the selected
decoder's patches before decoding untrusted APKs; the compatibility floor above
is not a security recommendation. REA does not fetch advisories at runtime.
On Windows, a `.bat` or `.cmd` launcher (such as Chocolatey's `apktool.bat`)
runs through an explicit `cmd.exe /d /s /c` call. That call has no AutoRun,
no delayed expansion, and quotes every argument. A launcher path that
@@ -38,13 +62,15 @@ reports `capability_unavailable`.
rea inspect-apktool-client
rea decode-android-resources /targets/Example.apk
rea decode-android-resources /targets/Example.apk --locale de
rea decode-android-resources /targets/Example.apk --locales de --locales pt-BR
rea decode-android-resources /targets/Example.apk --no-strings
```
Equivalent MCP methods are `inspect_apktool_client` and
`decode_android_resources`. The decode request takes `path`, an optional
`locale` (project `res/values-<locale>/strings.xml` instead of the default
table), and `include_strings` (default true). Regional locales such as `pt-BR`
primary `locale` (project `res/values-<locale>/strings.xml` instead of the default
table), `locales` (repeatable array of additional localized string tables to project
from the same single decode pass), and `include_strings` (default true). Regional locales such as `pt-BR`
select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
`b+zh+Hans+CN` may also be supplied directly.
@@ -52,6 +78,8 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
- **An owned APK snapshot is digested and decoded.** `target.sha256` and
`target.bytes` bind the observation to the exact APK that was decoded.
The Evidence subject carries the same snapshot digest and caller-selected
path, including when the original file changes during decoding.
- **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.
@@ -59,9 +87,28 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
truncated when larger.
- **Strings are projected verbatim.** Escaped entities stay escaped, and
entries containing nested markup (`<b>`, `<xliff:g>`) are counted as
unparsed rather than flattened — the limitation names the count. The
default table is bounded to 2000 entries with partial coverage when more
exist; `locales` lists every `values-<locale>` that has a strings table.
unparsed rather than flattened — the limitation names the examined count.
Malformed XML and a wrong document root are whole-document projection
failures: the result is partial, the failure reason is disclosed, and entry
counts remain unknown. They are not counted as one unsupported string.
The default table is bounded to 2000 entries with partial coverage when more
exist. `locales` lists observed regular `strings.xml` tables whose exact
`values-<locale>` directory is selectable by the request's locale grammar.
Locale suffixes allow up to 23 ASCII characters, derived from Apktool's
language, script, region, and variant fields; for example,
`b+sr+Latn+RS+REVISED` selects that exact table.
Other table directories, including combined qualifiers such as
`values-en-rUS-v21` and `values-mcc310-fr`, are named in limitations with
their source spelling. They are not advertised as selectable locales;
REA does not infer Android's runtime resource matching. Non-regular
strings-table paths are disclosed with partial coverage. Discovery uses
the same bounded traversal as the file count; filesystem failures remain
failures rather than being interpreted as missing tables.
When multiple tables are requested with `locales`, `string_tables` records
each projected table with its locale, status (`present`, `missing`,
`oversized`, `malformed`, or `skipped`), entry counts, and coverage,
bounded at an aggregate budget of 10,000 strings and 32 MiB XML. When `locales`
is omitted, legacy single-table payloads are preserved without adding `string_tables`.
- **Smali is skipped by design** (`apktool d --no-src`): Java-source
recovery belongs to the JADX family. Resource smali edits and rebuild are
a follow-up lane with mutation authority.
@@ -81,9 +128,11 @@ select Android's `values-pt-rBR`; Android qualifiers such as `pt-rBR` and
coverage and an explicit limit, rather than reported as missing.
- `decoded_file_count` is capped at 100,000 files; the cap is reported in
the limitations when hit.
- Apktool's own decode failures (`AndrolibException`, directory traversal
refusals) surface as `unsupported_target` with apktool's reason preserved
verbatim.
- An ordinary nonzero decode exit surfaces as `unsupported_target` naming
the caller-selected APK, with Apktool's diagnostic and captured output.
Launcher startup, ownership preparation, signal termination and incomplete
output collection remain provider failures; they do not establish that the
selected APK is unsupported.
## Real verification
+18
View File
@@ -60,6 +60,15 @@ states that absence is unknown. Component arrays remain complete when candidate
hypotheses are omitted; component arrays still include every component from
the supplied inventory pages, and overall coverage is `partial` in that case.
Inventoried files whose bytes were not read, such as encrypted archive members,
are listed in `unavailable_components` with their original path, format,
encryption flag, limitations, and null content identity. The same application-root
and AppleDouble attribution rules apply. These files make overall coverage
`partial`; component absence is unknown even when `inventory_complete` is true.
Directories have no file bytes and symlinks remain in `symlinks`, so neither is
an unavailable file component. The additive field participates in `projection_id`,
including when empty, so Apple projection identifiers change.
## Application roots
| Inventory root | Application root |
@@ -68,6 +77,15 @@ the supplied inventory pages, and overall coverage is `partial` in that case.
| `.app` directory | `.`, the inventoried bundle itself |
| Directory, ZIP, or DMG containing apps | Each outermost `<Name>.app` followed by `Contents/` |
File and slice occurrences supply component endpoints. Directory tree identities
remain in source inventory and bundle anatomy, and links remain in `symlinks`.
Root and layout discovery use known directories and ancestors implied by deeper
inventory paths. A leaf file or symlink named `*.app`, `Contents`, or `Versions`
does not establish that directory. Directory and authenticated-file identity are
selected before applying anatomy case preferences, so a file cannot shadow a
folded directory name or a directory shadow a metadata/signature file.
ZIP archives made with `ditto -c -k --keepParent` report `<Name>.app`. A DMG
reports `<image>.dmg/<Volume>/<Name>.app`; DMG child inventory needs the native
macOS mounting adapter. When a DMG has only its root identity, the projection is
+8
View File
@@ -285,6 +285,14 @@ REA establishes a main-frame origin boundary before enabling Runtime, Debugger,
## Data minimization
The Link projection parses repeated CDP header field lines independently and
retains their declarations in order, including derived untrusted agent hints.
Commas inside URI targets or quoted parameters remain part of those values.
COOP and COEP projections retain the exact declared token after validating the
complete Structured Field Item, including parameters such as `report-to`.
These are declarations, not an assessment of the document's effective policy;
absent, malformed or non-token items project as `null`.
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`.
+12
View File
@@ -144,6 +144,18 @@ 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.
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,
cache and origin storage. Later REA runs currently do not reclaim these paths.
Playwright 1.58.2 can also leave an artifacts directory when launch preparation
fails before a browser process exists, such as for a missing executable.
POSIX wrappers can request awaited cancellation with `SIGINT` or `SIGTERM`;
Windows process termination is not an equivalent graceful-cancellation channel.
Do not identify owned artifacts by directory prefix or creation time alone.
See [#4659](https://github.com/morluto/rea/issues/4659) for the remaining recovery
and wrapper-cancellation work.
Keeping that browser alive does not guarantee its emulation state survives.
Chromium can clear caller-owned `navigator.platform` emulation when a page CDP
session disconnects, including sessions that sent no emulation commands. REA
+9 -2
View File
@@ -56,8 +56,15 @@ rea inspect-electron-page http://127.0.0.1:9223 TARGET_ID \
The normalized result contains canonical local paths, frame and DOM
structure, resource metadata, stable script/resource identities, explicit
completeness, and content-addressed script artifacts. Script metadata
retains its execution-context frame ID when CDP supplies one. The capture also
completeness, and content-addressed script artifacts. Resource sizes are unknown
when omitted or invalid; supplied invalid sizes also produce an explicit
completeness diagnostic.
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.
Script metadata retains its execution-context frame ID when CDP supplies one. The capture also
inventories worker, service-worker, and shared-worker targets with
validated opener-target and parent-frame IDs. Worker discovery uses passive
target metadata; REA does not attach to or execute code in those targets.
+8
View File
@@ -124,6 +124,10 @@ FileBytes digests, every source mapping and its memory digest, relocation record
module partitions, relocation fixups and linear coordinates rather than relying
on the imported executable SHA alone.
Expected DOS relocation records retain each fixup's pre-application bytes and
applied value. Their memory-byte windows come from the final relocated image,
including changes made by later overlapping fixups.
The result is `verified`, `mismatch`, or `unsupported`. Every check retains its
expected and observed values. A memory-digest mismatch identifies the source
range's file offset and analysis address; it does not locate the first differing
@@ -134,6 +138,10 @@ their contents and DOS runtime semantics are not verified. Independent verificat
also covers explicit [raw-binary imports](raw-binary.md); other formats return
`unsupported` with measured observations.
MZ verification retains the initialized image described by the header's page
count and streams appended overlay bytes into the complete original and modified
source digests. Overlay size does not increase the retained image allocation.
`read_bytes` returns initialized provider memory, including loader fixups; an
unmapped or uninitialized byte ends the read with an explicit returned length and
`complete: false`. `address_to_file_offset` uses the provider's source mapping;
+8
View File
@@ -65,6 +65,14 @@ PDB, or change analyzer settings.
## Loaded addresses and file offsets
Ghidra computes overview procedure and string counts from the same inventories
used by `list_procedures` and `list_strings`, without transporting those rows
solely to count them. Counts include external functions and only Ghidra-defined
strings; they do not establish discovery of unidentified functions or undefined
string bytes. Complete inventories remain available through the list tools.
Overview reuse follows the target/profile snapshot lifetime and is invalidated
by session metadata edits.
`rea analyze <path> --provider ghidra --json` and MCP `binary_overview` report
the observed loaded `image_base` in `normalized_result`. They retain each
segment's reported `image_base` and `address_space`. A provider that does not
+6
View File
@@ -45,6 +45,12 @@ The MCP tool `project_harmony_application_graph` takes the same
- path-based N-API bridge hypotheses between bytecode and `libs/<abi>` native
libraries
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
classified bytecode and JavaScript lists; supported source extensions share the
same classification rule as their component rows.
Every claim is path-presence only. Manifest semantics (module identity,
abilities, entry points, permissions, dependencies), Ark bytecode contents and
versions, resource resolution, signing verification, and observed native
+1 -1
View File
@@ -41,7 +41,7 @@ rea function /absolute/path/to/program main --json
rea decompile /absolute/path/to/program main --json
```
Open the **original input binary** in REA, not an `.idb` or `.i64` database. Its SHA-256 must match IDA's recorded input hash. REA checks the attached identity and image base around each analysis request. A mismatch or target switch fails with recovery guidance. The original input must remain readable by REA; WSL can use its mounted alias while the GUI runs on Windows.
Open the **original input binary** in REA, not an `.idb` or `.i64` database. Its SHA-256 must match IDA's recorded input hash. REA checks the attached identity and image base around each analysis request. A mismatch or target switch fails with recovery guidance. The original input must remain readable by REA; WSL can use its mounted alias while the GUI runs on Windows. Attached profiles, including native mode, refuse universal Mach-O inputs at admission: every slice shares the recorded whole-file hash, so REA cannot verify which slice the GUI loaded. Open a thin file extracted with `lipo -thin` in both IDA and REA, or use headless mode, which analyzes the selected slice.
REA's close operation releases its MCP connection or proxy. It never saves or closes the existing GUI database. External edits remain visible because results are live and are not replayed from snapshots. These checks do not lock the GUI or prove that the database is unpatched.
+48 -5
View File
@@ -57,14 +57,26 @@ Before applying changes, REA checks your current configuration. The plan lists:
Malformed or unsafe existing configuration blocks the whole transaction before
Hopper installation or any file write. Declining or pressing Ctrl-C makes no
changes. Agent configuration writes preserve unrelated entries and comments,
create backups, use atomic replacement, and verify their result. Setup and
uninstall retain an existing `.rea.backup` rather than replacing the first snapshot.
create backups, stage changes in a private directory, and verify their result.
Before publication, they refuse detected changes to the selected configuration.
Replacement uses an explicit destination under the selected canonical parent;
it does not follow a newly inserted destination symlink. First-run setup uses
an exclusive hard link and fails without overwriting a newly created destination;
filesystems without hard-link support cannot publish a first-run configuration.
Setup and uninstall retain an existing `.rea.backup` rather than replacing the
first snapshot.
If that snapshot differs from the current configuration, setup and uninstall
preserve a verified `.rea.backup.<sha256>.recovery` copy of the current bytes
before editing; setup also previews it. Both snapshots remain available.
When an edit made a backup, a failed uninstall update or restore, and a failed
setup readback or rollback, name the backup path that holds the bytes from just
before that edit.
If setup cannot verify a newly created configuration, it retains the file and
reports manual recovery instead of deleting a pathname that may have changed.
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 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`.
@@ -264,14 +276,14 @@ Register with the variable unset:
<!-- x-release-please-start-version -->
```bash
claude mcp add --scope local rea -- npx -y rea-agents@6.5.0 mcp
claude mcp add --scope local rea -- npx -y rea-agents@6.7.0 mcp
```
On native Windows, use the same project directory and wrap the package-runner
shim so the stdio client can launch it:
```powershell
claude mcp add --scope local rea -- cmd.exe /d /c npx -y rea-agents@6.5.0 mcp
claude mcp add --scope local rea -- cmd.exe /d /c npx -y rea-agents@6.7.0 mcp
```
<!-- x-release-please-end -->
@@ -901,6 +913,12 @@ Properties format limit. Reads preserve Ghidra's Latin-1 byte mapping and check
the descriptor and selected name for changes. Permission failures and resource
refusals remain explicit; failed descriptor cleanup must succeed before that
owner admits another inspection.
Native decompiler compatibility inspection follows the selected executable symlink
and reads at most the first 4096 bytes through the same descriptor owner. It
checks the full extent and selected name for changes without reading the remainder.
An unreadable or unrecognized header leaves compatibility unknown; diagnostics
retain read failures. Cancellation and incomplete cleanup propagate as failures,
and failed cleanup retains the exact descriptor for retry.
This coordinate selects only REA's session-private configuration directory, not
the installation or an existing user configuration directory.
@@ -919,6 +937,10 @@ ownership inspection, so retaining those wrappers would prevent verified
process-group cancellation during startup.
If ownership remains unverifiable, it reports the reason and retains the process
supervisor and private runtime instead of removing files beneath a live provider.
Startup preserves an observed launch failure when cancellation arrives during
rollback. Producer cancellation retains the caller's exact reason separately
from LaunchSupport warnings and cleanup failures. Failed rollback keeps the
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.
@@ -1014,6 +1036,8 @@ export REA_GHIDRA_COMPILER_SPEC_ID="borlandcpp" # optional; requires a languag
REA passes `-processor`/`-cspec`, checks both against the installation's `.ldefs`, and records them in the analysis profile. DOS imports reject an override.
Language definitions must be well-formed XML encoded as UTF-8 or BOM-marked UTF-16, with any encoding declaration matching the bytes. Literal Unicode replacement characters (U+FFFD) are accepted; malformed source bytes are rejected.
To seed code that auto-analysis cannot reach (computed jumps, pointers in data):
```bash
@@ -1113,6 +1137,10 @@ compiler remains distinguishable from a compiler that exited with an error.
The helper compile deadline defaults to 120,000 ms; set
`REA_SWIFTC_COMPILE_TIMEOUT_MS` to an integer between 1 and 2,147,483,647 when
a busy host needs longer.
On macOS, the Java prerequisite probe waits for this independently bounded
preparation before starting its five-second command deadline. Caller cancellation
still interrupts preparation, and failed helper cleanup remains owned for retry.
Linux process-table preparation remains inside the command deadline.
Other rejection values retain their primitive value or an explicit type.
Shutdown warnings include the failure
kind, message, and diagnostics, while process and temporary-project cleanup
@@ -1159,7 +1187,7 @@ For a client that requires manual configuration, use:
"mcpServers": {
"rea": {
"command": "npx",
"args": ["-y", "rea-agents@6.5.0", "mcp"]
"args": ["-y", "rea-agents@6.7.0", "mcp"]
}
}
}
@@ -1224,6 +1252,21 @@ on the shell `PATH`. Use the setup command above for the guided setup
journey, `npx -y rea-agents@latest` for unattended one-off commands, or install globally
with `npm install --global rea-agents` for a shell-visible `rea` command.
For many concurrent agent sessions, run setup directly from a global installation
to avoid keeping a separate npm launcher process for each MCP connection:
```bash
npm install --global rea-agents
rea setup
```
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.
The optional curl wrapper installs only the global npm package:
```bash
+21
View File
@@ -288,6 +288,27 @@ and the result includes its basis, candidates, changed dimensions, Evidence
links, limitations, and a `changed_from` graph containing all compared nodes,
their observations, and relationships.
A matched pair whose only differing dimension is `location` counts as
`unchanged` when both input graphs have complete coverage and its neighboring
relationship identities are resolved. This includes an
identical module shifted by an earlier bundle edit and a named IPC channel
observed at a new offset. The item still reports `dimensions: ["location"]`
and both node IDs; the graph retains both original observations and coordinates.
Content, property, and complete relationship differences still count as
`changed`. With incomplete coverage, relocation alone remains `unknown` and
retains the location and coverage dimensions. Matching confidence is unchanged:
an inferred pair is not promoted to exact identity by this classification.
Complete inventory does not resolve ambiguous or unmatched relationship targets.
A matched module with identical bytes can therefore remain `unknown` when a
neighbor, including its containing chunk, has no cross-version match. The item
retains its exact content match, coordinates, candidate inventory, and an explicit
relationship-identity limitation. `coverage` is added to its dimensions only for
incomplete inventory. Definite content, property, or complete topology differences
remain `changed` while retaining any separate relationship uncertainty.
An unknown item with no observed content, property, or relationship difference
does not emit a `changed_from` edge; its pairing and uncertainty remain in the item.
One-sided absence is `added` or `removed` only when the opposite input graph has
complete coverage. With partial, unavailable, or truncated input, the same
condition is `unknown`. The comparison retains every classified item and
@@ -586,6 +586,21 @@ not bypass worker heap, execution deadline or parent result admission. Truncated
coverage reports both effective node ceilings; omitted relationships remain
unknown.
Unknown records have independent defaults of 100000 across the application and
20000 per source. Select `max_semantic_unknowns` and
`max_semantic_unknowns_per_file` (CLI: `--max-semantic-unknowns` and
`--max-semantic-unknowns-per-file`), each from 1 to 1000000. The parent offers the
remaining capacity to the worker, and rejects excess records before adoption.
Unknown admission happens before canonical identity and provenance construction.
When capacity is exhausted, coverage is partial and truncated and names both
effective unknown ceilings. `coverage.omitted_unknown_occurrences` counts examined
emission occurrences by family and reason, including repeated emissions. It does
not claim distinct discarded identities or count frontiers in unexamined source.
Omitted unknown provenance and IDs are not retained. Existing source, node,
execution and memory limits continue to determine examined coverage. Raising only
a node capacity does not raise the unknown capacity. Graphs without unknown
omissions omit this optional coverage field, preserving their existing identities.
While sources remain, the sequential worker reserves one next compact static
checkpoint at its 8 MiB bound with the same 6x retention expansion used at
admission. Earlier checkpoints are already charged to retained bytes; the
+5 -2
View File
@@ -133,8 +133,11 @@ Each operation uses one worker, a 1 GiB address-space ceiling and a 120-second
deadline; it accepts up to 64 MiB of total input across all selected files and
128 MiB/10000 entries of staged
output, with 8 MiB per diagnostic/report stream. Exceeding a limit is an explicit
failure with rollback. These limits apply per operation and do not claim aggregate
host containment across concurrent callers.
failure with rollback. Selected inputs beyond the total input allowance return a
non-retryable `resource_constraint` with `resource: "file-size"` and
`reported_limits.maximum_input_bytes`/`remaining_input_bytes`; input that is not
valid UTF-8 is an `invalid_format` request issue. These limits apply per
operation and do not claim aggregate host containment across concurrent callers.
See [testing.md](testing.md#javascript-source-recovery) for the focused real
Wakaru CLI/MCP lane and its source-owned compiler fixtures. Other host platforms
+3 -1
View File
@@ -109,7 +109,9 @@ The direct observations are:
- `Runtime.executionContextCreated`,
`Runtime.executionContextDestroyed`, and
`Runtime.executionContextsCleared`, establishing context lifecycle within
the capture window.
the capture window. A created or destroyed event whose context ID is
missing or not a safe integer adds no context record; it is retained only
as a count reported in `unknowns`.
The Inspector protocol does not directly expose require/import caller edges,
EventEmitter emissions or listener invocation, Electron IPC messages or
+21 -1
View File
@@ -22,6 +22,8 @@ Select it explicitly with `--provider kuna`, MCP's `open_binary.provider_id: "ku
| `REA_KUNA_TIMEOUT_MS` | 120 s | Deadline for one single-function decompile, and for the inventory run REA makes when the export ends without one. |
| `REA_KUNA_JOBS` | 1 | `decompile-project --jobs`. 1 is Kuna's reference answer; more jobs finish sooner but lose callee-first prototypes, and change about 40–60% of function bodies on the measured binaries. |
A single-function decompile, inventory, string, graph or xref run that exceeds its deadline fails as `provider_timeout`, naming the setting that owns the deadline and that raising it takes a restart. A project export that exceeds `REA_KUNA_PROJECT_TIMEOUT_MS` is an export failure instead: requests that need the export report `capability_unavailable` with the export's own retry guidance.
Windows is not supported yet. Supported targets are ELF and thin Mach-O executables for x86-64, AArch64 and ARM; PE and universal Mach-O are rejected with a typed reason.
## What Kuna answers
@@ -68,7 +70,7 @@ Single-function subprocess output and each cached source facet share a 16 MiB bu
Results keep exact u64 virtual addresses, decoded text, native encoding, terminator status and byte length including any terminator. Kuna scans mapped sections or segments for runs of at least five characters; unterminated fragments can include instruction bytes. `all` includes ASCII, UTF-8 and the engine's Latin-range UTF-16LE reading. Other text, including short strings, non-Latin wide text and UTF-16BE, can remain undiscovered. An empty result does not prove absence.
Use `search_strings` for the matching rows or `list_strings` with an exact address for that location. Literal and regex matching run in REA, preserving the existing case and ECMAScript Unicode semantics instead of substituting Kuna's different regex dialect. Procedure and string regex queries share one worker slot per session. Input projections are materialized only after admission, so queued queries retain no per-query inventory arrays. Close cancels and drains matching. Native metadata queries also share one admission slot, including references; a failed stop retains admission until cleanup is proven.
Use `search_strings` for the matching rows or `list_strings` with an exact address for that location. The validated inventory is sorted by numeric address and encoding. Once cached, exact-address reads use binary search and return every encoding at that address without scanning the full inventory or retaining another lookup index. Literal and regex matching run in REA, preserving the existing case and ECMAScript Unicode semantics instead of substituting Kuna's different regex dialect. Procedure and string regex queries share one worker slot per session. Input projections are materialized only after admission, so queued queries retain no per-query inventory arrays. Close cancels and drains matching. Native metadata queries also share one admission slot, including references; a failed stop retains admission until cleanup is proven.
`raw_result.strings` reports the source JSON digest/size, scanned scope, extraction policy, complete inventory count and selected count without copying unrequested text into the answer. Omit the address from `list_strings` to retrieve the complete inventory as Evidence; normal session retention and bundle export apply, including transport-capacity errors for oversized inline replies. These operations preserve their complete-result contracts and do not add paging. Function-referenced string facets in `analyze_function` remain unavailable; call `xrefs` explicitly when references to one returned string are needed.
@@ -82,6 +84,24 @@ REA parses the graph as Kuna writes it, like the string scan, so the graph has n
Evidence includes only selected addresses or dossier neighbors, the producing JSON's SHA-256/byte count, coverage and relevant function facts; unrequested program-wide JSON and instruction text are omitted. Reference caches are in memory and expire on close: a fresh CLI process or MCP server rebuilds them. A first call query therefore costs a whole-program reference walk even when a C export is warm. These operations do not establish full Ghidra/IDA feature parity.
Failures from shared installation or inventory work identify the operation the
caller requested. `diagnostics.producer_operation` retains the internal producer
name when it differs. Caller-specific failures keep the producer's typed outcome,
captured output, partial facts and live cleanup dependencies; cleanup retry
updates every projection rather than preserving an independent stale marker.
Installation acquisition is shared, with independently cancellable caller waits.
The final departing caller stops the probe and joins its cleanup; session close
also stops and joins acquisition. A cleanly cancelled acquisition can be retried,
while a retained cleanup failure blocks replacement until its owner is closed.
Shared string and reference queries preserve caller cancellation reasons and
join the final departing caller's command cleanup. A command cleanup error keeps
its typed primary failure and captured output. Its live resource list follows
both process and workspace ownership: proving process exit does not prove that
the private workspace was removed, and retry updates earlier caller errors.
If workspace setup fails, an unsuccessful rollback retains the original target
or read failure together with its cleanup owner. Replacement stays blocked until
that rollback is resolved; a clean rollback permits another setup attempt.
## Provenance and limitations
- Addresses and bytes are Kuna's observations of the image. Procedure entries and extents are its derivations: extents are upper bounds clipped at the next entry, and Kuna can split one function at an entry its own analysis infers. Pseudocode is its reconstruction, never original source.
+25
View File
@@ -524,6 +524,12 @@ analysis runtime. These failures are reported at the operation that needs
them. A configured provider or an endpoint alone does not establish that a
target is supported.
Composite Hopper regex searches report failures against the accepted
`search_strings` or `search_procedures` operation. The underlying inventory
method and request ID remain in `details.diagnostics.provider_request`, with
the bridge error code and diagnostic type when available. Reattribution
preserves the failure class, captured output, and live cleanup ownership.
Evidence bundles, snapshots, and extraction use the paths and output behavior
declared by their tools. Artifact extraction materializes the selected regular
files into a fresh REA-chosen temporary directory and reports its path.
@@ -534,6 +540,25 @@ temporary source files are declared as `launchesProcess` and `writesFilesystem`,
including for a single JavaScript source. This internal analysis does not execute
the supplied application code.
## Static Ghidra bytes and source mappings
`read_bytes` returns initialized analysis memory, including loader fixups, rather
than live process memory. Check `returned_bytes` and `complete` before decoding:
reads stop at unmapped or uninitialized bytes. Missing bytes are unknown; do not
pad an incomplete read with zeros and treat the result as an observation.
`list_segments` reports memory-block initialization and address-space facts.
`address_to_file_offset` maps one address through the provider's source-byte
mapping. A successful start-address mapping does not establish that an entire
range is contiguous in the original file, or that its bytes equal analysis
memory after loader fixups. Uninitialized, missing, and ambiguous mappings fail
explicitly; preserve the reported failure rather than guessing an offset.
For constructor-populated pointer or resource slots, a static zero is not proof
of a later null value. Inspect the slot's `xrefs` and the writer's assembly or
pseudocode, retaining uncertainty about execution order and runtime values.
These operations inspect static evidence and do not execute the target.
## Ghidra first-query deadlines and recovery
A successful MCP initialize handshake establishes the REA connection.
+56 -3
View File
@@ -261,6 +261,23 @@ Mach-O fixtures check each case against source-owned return values.
## Static inspection
`inspect_plist.format` describes the selected source, not plutil's conversion
format. Sources explicitly identified as XML, binary or JSON retain those
labels. For generic text, a bounded source-prefix probe recognizes leading XML
markup, including UTF-8 and BOM-marked UTF-16 sources. Unidentified text and
OpenStep plists, including a data-only value such as `<deadbeef>`, report
`unknown` even when plutil decodes their values through an XML conversion.
A plist explicitly selected through the path input or as the active plist target
reports an unreadable or malformed selection as `invalid_request`. A missing or
unreadable default plist of another target reports `capability_unavailable`.
Permission failures remain `access_denied`; output and cleanup failures retain
their own error categories.
A plist decode refusal includes plutil's diagnostic from either output stream.
`details.captured_output` retains bounded stdout/stderr excerpts, observed byte
totals and exit status. `truncated: true` means those excerpts are incomplete.
`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
@@ -317,12 +334,16 @@ complete observation.
shared/cyclic references, class descriptors, raw serialized fields and
malformed/unresolved/nil references. Missing fields stay absent; unknown
classes are preserved. Select `root`, `offset` and `limit` explicitly.
Object `kind` describes the decoded archive value: data, dates and numbers
remain `scalar` when their JSON value uses a `$plist_type` wrapper. An actual
dictionary with the same fields remains `dictionary`.
UID 0 cannot distinguish conditional nil from ordinary nil. Limits are
64 MiB of input, 200,000 objects/references and 128 nesting levels.
XML dictionary entries decoded as `__proto__` are omitted with an explicit
count because REA results cannot represent that key. XML tag whitespace and
comments do not change that handling. Other values and the original archive
digest are preserved; key interpretation follows the pinned plist decoder.
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.
- `decode_interface_builder` / `rea decode-interface-builder <app>` reads
compiled storyboard and nib resources into objects, outlets, actions,
connections and controller/class names. A full app graph is often several
@@ -418,7 +439,11 @@ decrement scrolling and text-value entry, or bounded waits. No global event
injection is used. Unsupported AX actions fail explicitly. The result preserves
ordered before/after captures and gaps; an action may have occurred before a
post-action capture fails. Application state is left as-is; REA does not attempt
to restore it.
to restore it. Failed or cancelled scenarios return a typed error with the
collected report in `partial_observation`, including ordered step outcomes.
Cancellation preserves the caller's reason and remains observable through helper
cleanup. A later abort does not replace an earlier helper or output failure.
Cleanup failures retain their runtime owner until a confirmed cleanup retry.
Scenarios accept caller-selected action lists and accessibility node counts.
Individual waits cannot exceed the operation's 180-second deadline, and the
@@ -572,6 +597,10 @@ digests identify the original serialized bytes.
## Keyed archive integer precision
The archive reader observes XML number element types and binary number markers.
XML values and their number facts are interpreted together from the validated
DOM. Hexadecimal `<integer>` text, including an optional sign, retains its value;
`<real>` text and CDATA segments are combined without inferring text from nested
elements. The XML path does not serialize or reparse character references.
Integers beyond the exact range of a JSON number are reported with the original
decimal text as `{ "$plist_type": "integer", "decimal": "<exact digits>" }` when
that source value can be associated unambiguously. Integral real values remain
@@ -609,6 +638,30 @@ or a negative year, is reported as `{ "$plist_type": "date", "iso8601": null }`
with a counted limitation; the rest of the plist or archive is still decoded.
`inspect_plist` and Interface Builder decoding use the same projection.
A negative-zero real is reported as `{ "$plist_type": "real", "value": "-0" }`
because a JSON number cannot carry the sign of zero. `inspect_plist` and
`inspect_keyed_archive` count these values in a limitation, and Interface
Builder node attributes use the same value. Positive zero and integer zero,
including an `<integer>-0</integer>` literal, remain the number `0`.
Known non-finite reals are reported as
`{ "$plist_type": "real", "value": "nan" | "+infinity" | "-infinity" }`.
These are canonical numeric labels, not a claim about original source spelling.
Binary IEEE reals retain NaN versus signed infinity; NaN payload bits and sign
are not represented in the JSON value, and the original bytes remain the source
for those details. XML CFPropertyList literals (`nan`, `+infinity`, `-infinity`,
`infinity`, `inf`, `+inf`, `-inf`, case-insensitively) decode to the same known
values. Case and aliases normalize; original archive bytes retain source text.
XML numeric text whose identity the decoder cannot establish, including
unrecognized non-finite text and finite literals that overflow the numeric
representation, remains `{ "$plist_type": "real", "value": null }` with a
counted limitation. The XML decoder marks these values explicitly before shared
projection, so they cannot be confused with known binary IEEE values.
Incomplete numeric markup retains its existing compatibility behavior described
above. Known non-finite and unresolved numeric values have separate counts.
Native `inspect_plist` uses these same labels for plutil's XML conversion.
## Locate a byte signature
Use `search_bytes` after opening a target with Ghidra to locate a known constant
+5
View File
@@ -58,6 +58,11 @@ tools read that copy, which is hashed again after analysis. Capture metadata and
literal field values are producer observations; address/protocol counts and DNS
associations are derivations. Capture Evidence has historical-reference authority.
`capture_start` and `capture_end` are RFC 3339 UTC instants derived from
`capinfos -S` epoch seconds, retaining all producer fractional digits (up to
nanoseconds). Empty captures, malformed timestamps and instants outside years
0000–9999 remain `null`; host-local timestamps without a zone are not inferred.
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.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · **العربية** · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: هندسة عكسية لأي شيء
@@ -274,7 +274,7 @@ npx rea-agents@latest setup
## سجل النجوم
🎉 **250,000 نجمة على GitHub — شكرًا لكم!**
🎉 **300,000 نجمة على GitHub — شكرًا لكم!**
شكرًا لكل من يستخدم REA، ويبلّغ عن الأخطاء، ويقترح ميزات، ويختبر إصدارات البناء، ويساهم بالإصلاحات.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · **Deutsch** · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Alles reverse-engineeren
@@ -272,7 +272,7 @@ Melde Sicherheitslücken gemäß [SECURITY.md](../../SECURITY.md).
## Sternverlauf
🎉 **250.000 GitHub-Sterne – vielen Dank!**
🎉 **300.000 GitHub-Sterne – vielen Dank!**
Danke an alle, die REA nutzen, Fehler melden, Funktionswünsche äußern, Builds testen und Fehlerbehebungen beitragen.
+2 -2
View File
@@ -1,6 +1,6 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md) · **Ελληνικά**
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md) · **Ελληνικά** · [മലയാളം](README_ml.md)
# REA: Reverse Engineer Anything
@@ -285,7 +285,7 @@ npx rea-agents@latest setup
## Ιστορικό αστεριών
🎉 **250.000 αστέρια στο GitHub — σας ευχαριστούμε!**
🎉 **300.000 αστέρια στο GitHub — σας ευχαριστούμε!**
Ευχαριστούμε όλους όσοι χρησιμοποιούν το REA, αναφέρουν σφάλματα, ζητούν νέες λειτουργίες, δοκιμάζουν builds και συνεισφέρουν διορθώσεις.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · **Español** · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Ingeniería inversa de cualquier cosa
@@ -272,7 +272,7 @@ Informa de vulnerabilidades siguiendo [SECURITY.md](../../SECURITY.md).
## Historial de estrellas
🎉 **250.000 estrellas en GitHub: ¡gracias!**
🎉 **300.000 estrellas en GitHub: ¡gracias!**
Gracias a quienes usan REA, informan de errores, solicitan funciones, prueban compilaciones y contribuyen con correcciones.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center" dir="rtl">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · **فارسی** · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: مهندسی معکوس هر چیزی
@@ -257,7 +257,7 @@ npx rea-agents@latest setup
## تاریخچهٔ ستاره‌ها
🎉 **۲۵۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
🎉 **۳۰۰٬۰۰۰ ستارهٔ GitHub — سپاسگزاریم!**
از همهٔ کسانی که از REA استفاده می‌کنند، خطاها را گزارش می‌دهند، قابلیت‌های جدید پیشنهاد می‌کنند، buildها را آزمایش می‌کنند و در بهبود پروژه مشارکت دارند سپاسگزاریم.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · **Français** · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA : rétro-ingénierie de tout
@@ -276,7 +276,7 @@ Signalez les vulnérabilités via [SECURITY.md](../../SECURITY.md).
## Historique des étoiles
🎉 **250 000 étoiles GitHub — merci !**
🎉 **300 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.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · **Bahasa Indonesia** · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Rekayasa Balik Apa Pun
@@ -297,7 +297,7 @@ Laporkan kerentanan melalui [SECURITY.md](../../SECURITY.md).
## Riwayat Bintang
🎉 **250.000 bintang GitHub, terima kasih!**
🎉 **300.000 bintang GitHub, terima kasih!**
Terima kasih kepada semua orang yang menggunakan REA, melaporkan bug, meminta fitur, menguji build, dan berkontribusi dalam perbaikan.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · **Italiano**
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Reverse Engineer Anything
@@ -276,7 +276,7 @@ Segnala vulnerabilità tramite [SECURITY.md](../../SECURITY.md).
## Cronologia delle stelle
🎉 **250.000 stelle su GitHub — grazie!**
🎉 **300.000 stelle su GitHub — grazie!**
Grazie a tutti coloro che usano REA, segnalano bug, propongono funzionalità, testano le build e contribuiscono con correzioni.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · **日本語** · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA:あらゆるものをリバースエンジニアリング
@@ -274,7 +274,7 @@ npx rea-agents@latest setup
## スター履歴
🎉 **GitHub スター 250,000 件、ありがとうございます!**
🎉 **GitHub スター 300,000 件、ありがとうございます!**
REA の利用、バグ報告、機能の要望、ビルドのテスト、修正への貢献に感謝します。
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · **한국어** · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: 무엇이든 리버스 엔지니어링
@@ -283,7 +283,7 @@ npx rea-agents@latest setup
## 스타 기록
🎉 **GitHub 스타 250,000개, 감사합니다!**
🎉 **GitHub 스타 300,000개, 감사합니다!**
REA를 사용하고, 버그를 보고하고, 기능을 요청하고, 빌드를 테스트하고, 수정에 기여해 주신 모든 분께 감사드립니다.
+325
View File
@@ -0,0 +1,325 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md) · **മലയാളം**
# REA: എന്തും Reverse Engineer ചെയ്യുക
### Binaries, applications, runtime behavior എന്നിവയുടെ Reverse Engineering-നായി ഒരൊറ്റ MCP.
**നിങ്ങൾക്ക് ഇഷ്ടപ്പെട്ട ഒരു feature കണ്ടോ? അത് എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്ന് binary തലത്തിലേക്ക് വരെ മനസ്സിലാക്കൂ.**
[![npm version](https://img.shields.io/npm/v/rea-agents?style=flat-square&color=cb3837)](https://www.npmjs.com/package/rea-agents)
[![MCP tool catalog](https://img.shields.io/badge/MCP-tool_catalog-5c4ee5?style=flat-square)](../mcp-contracts.md#generated-catalog)
[![Node.js requirements](https://img.shields.io/badge/Node.js-requirements-339933?style=flat-square&logo=nodedotjs&logoColor=white)](#what-you-can-analyze)
[![skills.sh](https://skills.sh/b/morluto/rea?style=flat-square)](https://skills.sh/morluto/rea/reverse-engineer-anything)
[![MIT license](https://img.shields.io/badge/license-MIT-f4c430?style=flat-square)](../../LICENSE)
[![Discord](https://img.shields.io/discord/1556595354999332884?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://discord.gg/GkcryMnJDM)
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&amp;utm_medium=badge&amp;utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
**[വെബ്സൈറ്റ്](https://rea.tools/) · [ഗൈഡുകൾ](https://rea.tools/guides/) · [ഉദാഹരണങ്ങൾ](https://rea.tools/showcase/)**
[ദ്രുതാരംഭം](#ദ്രുതാരംഭം) · [REA എങ്ങനെ പ്രവർത്തിക്കുന്നു](#rea-എങ്ങനെ-പ്രവർത്തിക്കുന്നു) · [എന്തൊക്കെ വിശകലനം ചെയ്യാം](#എന്തൊക്കെ-വിശകലനം-ചെയ്യാം) · [ഉദാഹരണങ്ങൾ](#ഉദാഹരണങ്ങൾ) · [പതിവുചോദ്യങ്ങൾ](#പതിവുചോദ്യങ്ങൾ) · [ഡോക്യുമെന്റേഷൻ](#ഡോക്യുമെന്റേഷൻ)
<code>npx rea-agents setup</code>
</div>
> [!IMPORTANT]
> REA ലഭ്യമാക്കേണ്ടത് [morluto/rea](https://github.com/morluto/rea),
> [rea.tools](https://rea.tools/), അല്ലെങ്കിൽ [rea-agents npm package](https://www.npmjs.com/package/rea-agents) എന്നിവയിൽ നിന്നാണ്.
> ഈ ഔദ്യോഗിക ഉറവിടങ്ങളിലെ ഇൻസ്റ്റലേഷൻ, റിലീസ് ലിങ്കുകൾ പിന്തുടരുക. സമാനമായ
> repository പേരോ പകർത്തിയ README-യോ മാത്രം ഒരു download ഔദ്യോഗികമാണെന്ന് ഉറപ്പാക്കുന്നില്ല.
<div align="center">
<br />
<img src="../assets/rea-hopper-analysis.png" alt="ഒരു native binary പരിശോധിക്കുന്നതിനിടെ Hopper-ൽ REA അതിന്റെ analysis bridge ആരംഭിക്കുന്നു" width="1200" />
<br /><br />
<table aria-label="REA community">
<tr>
<td align="center" width="360">
<a href="https://discord.gg/GkcryMnJDM">
<img src="../assets/discord.svg" height="42" alt="Discord" /><br />
<strong>Reverse Engineering കമ്മ്യൂണിറ്റിയിൽ ചേരുക</strong>
</a><br />
<sub>Discord · ചോദ്യോത്തരങ്ങൾ · അനുഭവങ്ങളും കണ്ടെത്തലുകളും പങ്കിടുക</sub>
</td>
</tr>
</table>
<br />
</div>
---
നിങ്ങളുടെ സ്വന്തം product-ൽ ഉൾപ്പെടുത്താൻ ആഗ്രഹിക്കുന്ന ഒരു feature ഏതെങ്കിലും app-ൽ കണ്ടോ? REA ഉപയോഗിച്ച് അത് പരിശോധിക്കാൻ നിങ്ങളുടെ agent-നോട് ആവശ്യപ്പെടുക. source code ഇല്ലാതെയും അതിന് app പരിശോധിക്കാനും feature എങ്ങനെ പ്രവർത്തിക്കുന്നുവെന്ന് വിശദീകരിക്കാനും അതിനുള്ള തെളിവുകൾ കാണിക്കാനും നിങ്ങളുടെ project-നായി അതിന് സമാനമായൊരു പതിപ്പ് നിർമ്മിക്കാനും കഴിയും.
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 ആവശ്യമില്ല.
> **[REA വെബ്സൈറ്റ് സന്ദർശിക്കുക](https://rea.tools/)** — setup നിർദ്ദേശങ്ങൾക്കും ചിത്രങ്ങളോടുകൂടിയ ഗൈഡുകൾക്കും യഥാർത്ഥ case study-കൾക്കും.
## ദ്രുതാരംഭം
Linux-ൽ Ghidra, JADX, firmware tool launches, static JavaScript/Electron analysis എന്നിവയ്ക്ക് process ownership പരിശോധിക്കാൻ REA-യുടെ `PATH`-ൽ procps-compatible `ps` ആവശ്യമാണ്. പരിഹാര നടപടികൾ `docs/installation.md`-യിലെ "Linux owned-process prerequisite" എന്ന വിഭാഗത്തിൽ ലഭ്യമാണ്.
### നിങ്ങളുടെ agent സജ്ജമാക്കുക
Node.js-ഉം npm-ഉം ഇൻസ്റ്റാൾ ചെയ്തശേഷം ഈ command പ്രവർത്തിപ്പിക്കുക:
```bash
npx rea-agents setup
```
നിങ്ങൾ ഉപയോഗിക്കുന്ന agents തിരഞ്ഞെടുക്കുക, നിർദ്ദേശിച്ച മാറ്റങ്ങൾ പരിശോധിക്കുക, തുടർന്ന് അവയ്ക്ക് അനുമതി നൽകുക. നിലവിലുള്ള configuration-ന്റെ backup-ുകൾ സൂക്ഷിച്ചുകൊണ്ട് setup, REA-യുടെ MCP server-ഉം അനുയോജ്യമായ workflow നിർദ്ദേശങ്ങളും ചേർക്കും. അതിനുശേഷം നിങ്ങളുടെ agent വീണ്ടും ആരംഭിക്കുക.
Claude Code, Codex, Cursor, Gemini CLI, Grok Build, കൂടാതെ [മറ്റ് agents](../installation.md#supported-agents) എന്നിവയെ setup പിന്തുണയ്ക്കുന്നു. provider configuration-നും manual MCP registration-നും [installation and setup](../installation.md) കാണുക.
### നിങ്ങളുടെ agent-നോട് ആവശ്യപ്പെടുക
```text
Notes app-ൽ search എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്ന് മനസ്സിലാക്കി, അതിനുള്ള തെളിവുകൾ കാണിച്ചുതരികയും എന്റെ project-നായി സമാനമായൊരു feature നിർമ്മിക്കുകയും ചെയ്യുക.
```
`Notes` എന്നതിന് പകരം നിങ്ങൾ പരിശോധിക്കാൻ ആഗ്രഹിക്കുന്ന app-ിന്റെയും മനസ്സിലാക്കേണ്ട feature-ിന്റെയും പേരുകൾ നൽകുക.
### Terminal ഉപയോഗിക്കുക
Extract ചെയ്ത JavaScript/Electron app directory അല്ലെങ്കിൽ ASAR പരിശോധിക്കുക:
```bash
npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json
```
ഫലത്തിൽ modules, imports, Electron boundaries, അവയ്ക്കുള്ള തെളിവുകൾ എന്നിവ ഉൾപ്പെടും. `/absolute/path/to/app` എന്നതിന് പകരം നിങ്ങളുടെ target-ന്റെ path നൽകുക; Windows-ൽ ഉദാഹരണത്തിന് `"D:/apps/example"` ഉപയോഗിക്കാം.
സാധാരണ ഉപയോഗത്തിനായി `rea` command ഇൻസ്റ്റാൾ ചെയ്യാൻ:
```bash
npm install --global rea-agents
rea --help
```
Native analysis നടത്തുന്നതിന് മുമ്പ് ഒരു provider ക്രമീകരിക്കുക. Native commands, provider തിരഞ്ഞെടുക്കൽ, snapshots, scripting എന്നിവയ്ക്കായി [CLI and Evidence guide](../cli.md) കാണുക.
### REA അപ്‌ഡേറ്റ് ചെയ്യുക
REA-യിൽ പതിവായി മാറ്റങ്ങൾ വരുന്നു; പുതിയ releases-ൽ പല bug fixes-ഉം ഉൾപ്പെടുന്നു. നിങ്ങളുടെ installation ഏറ്റവും പുതിയ പതിപ്പിലേക്ക് അപ്‌ഡേറ്റ് ചെയ്യുക.
`npm install --global` അല്ലെങ്കിൽ `bun add --global` ഉപയോഗിച്ച് ഇൻസ്റ്റാൾ ചെയ്ത CLI-ക്കായി:
```bash
rea update
```
Bun-ന്റെ global updates-ന് Bun 1.2.17 അല്ലെങ്കിൽ അതിനുശേഷമുള്ള പതിപ്പ് ആവശ്യമാണ്. പഴയ Bun പതിപ്പാണെങ്കിൽ `rea update` പ്രവർത്തിപ്പിക്കുന്നതിന് മുമ്പ് Bun സ്വമേധയാ അപ്‌ഗ്രേഡ് ചെയ്യുക.
Agent registrations-ഉം skill-ഉം പുതുക്കാൻ, update കാണിക്കുന്ന setup command പ്രവർത്തിപ്പിക്കുക.
`npx` ഉപയോഗിക്കുന്നുവെങ്കിൽ, agent setup പുതുക്കാൻ:
```bash
npx rea-agents@latest setup
```
Setup-ൽ വരുത്തുന്ന മാറ്റങ്ങൾ പരിശോധിച്ച് നിങ്ങളുടെ agent വീണ്ടും ആരംഭിക്കുക. ഒറ്റത്തവണ മാത്രം ഉപയോഗിക്കുന്ന CLI commands-നായി command-ന് മുമ്പ് `npx rea-agents@latest` ഉപയോഗിക്കുക. Bun ഉപയോഗിക്കുമ്പോൾ `npx rea-agents@latest`-ന് പകരം `bunx rea-agents@latest` ഉപയോഗിക്കുക.
## REA എങ്ങനെ പ്രവർത്തിക്കുന്നു
Target പരിശോധിക്കാനും പ്രസക്തമായ code-ന്റെ പാത പിന്തുടരാനും നിങ്ങളുടെ agent MCP വഴി REA-യെ വിളിക്കുന്നു. REA കണ്ടെത്തലുകളും അവയ്ക്കുള്ള തെളിവുകളും തിരികെ നൽകുന്നു. തുടർന്ന് agent കൂടുതൽ ചോദ്യങ്ങൾ ചോദിക്കാനും പെരുമാറ്റം വിശദീകരിക്കാനും implementation എഴുതുകയും പരിശോധിക്കുകയും ചെയ്യാനും അവ ഉപയോഗിക്കുന്നു. CLI commands-ഉം ഇതേ workflows ഉപയോഗിക്കുന്നു.
![REA അന്വേഷണ പ്രവാഹം: നിങ്ങളുടെ agent ഒരു local target-നെക്കുറിച്ച് ചോദിക്കുന്നു; REA analysis tools ഉപയോഗിച്ച് അത് പരിശോധിക്കുകയും code-ന്റെ പാത പിന്തുടരുകയും ചെയ്യുന്നു; തിരികെ ലഭിക്കുന്ന code, references, അറിയാത്ത കാര്യങ്ങൾ എന്നിവ ഉപയോഗിച്ച് agent വിശദീകരിക്കുകയും implementation നടത്തുകയും പരിശോധിക്കുകയും ചെയ്യുന്നു.](../../website/public/assets/figures/rea-investigation-flow.svg)
[പൂർണ്ണ വലുപ്പത്തിലുള്ള ചിത്രം തുറക്കുക](../../website/public/assets/figures/rea-investigation-flow.svg).
<a id="current-status"></a>
## എന്തൊക്കെ വിശകലനം ചെയ്യാം
REA-യ്ക്ക് Node.js 22.x (>=22.19), 24.x (>=24.11), അല്ലെങ്കിൽ 26+ പതിപ്പും npm-ഉം ആവശ്യമാണ്. Target അനുസരിച്ച് അധിക tools-ഉം host support-ഉം വ്യത്യാസപ്പെടും:
| Target | REA നൽകുന്ന ഫലങ്ങൾ | ആവശ്യകതകളും ഗൈഡും |
| ---------------------- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Native binaries | Pseudocode, assembly, strings, symbols, calls, references | Hopper, Ghidra അല്ലെങ്കിൽ IDA; [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) |
| WASM artifact | Validation, sections, കൃത്യമായ import/export WAT രൂപങ്ങൾ, decoded WAT | Caller നൽകുന്ന WABT 1.0.42; `inspect_wasm_artifact` |
| EVM bytecode | Dispatch selectors, byte offsets, അനുമാനിച്ച arguments, mutability | Linux x64-ൽ local raw/hex carrier; [offline EVM guide](../evm-bytecode.md) |
| SQLite databases | Tables, columns, indexes, views, triggers, തിരഞ്ഞെടുത്ത സാധാരണ table rows | Local database/WAL snapshot; native SQLite പരിമിതികളോടെ Node.js 24.x >=24.15 അല്ലെങ്കിൽ 26+ |
| Recorded Linux crashes | Raw notes, രേഖപ്പെടുത്തിയ ഓരോ thread-ന്റെയും registers/signals, ഐച്ഛിക mapping candidates | Linux x64-ൽ caller നൽകുന്ന pwntools; ഐച്ഛിക GDB/pwndbg; [recorded crashes](../recorded-crashes.md) |
| JavaScript / Electron | Modules, imports, source maps, routes, IPC, native add-on ബന്ധങ്ങൾ | Node.js, npm; Linux: procps-compatible `ps`; [application analysis](../javascript-application-workflows.md) |
| Websites | Page structure, scripts, network observations, ആവശ്യപ്പെട്ട screenshots | Chrome-family browser; [browser analysis](../browser-observation.md) |
| Saved network captures | Requests, responses, പുറത്തുകാണുന്ന payload-ുകൾ, source locations | HAR അല്ലെങ്കിൽ Fiddler Everywhere SAZ; native mitmproxy-നായി Linux-ൽ mitmdump; [capture guide](../web-network-captures.md) |
| .NET assemblies | Metadata, CIL instructions, പ്രഖ്യാപിച്ച native dependencies, build comparisons | ഒന്നും ആവശ്യമില്ല (static മാത്രം); [managed-code guide](../managed-code-analysis.md) |
| Android APKs | Manifest declarations, classes, decompiled methods, references | Linux/macOS/Windows x64-ൽ Headless JADX-ഉം full JDK-ഉം; [Android guide](../android-analysis.md) |
| Android devices | Devices, packages, processes, logs, dumps, screen captures, APK/file transfers | Caller നൽകുന്ന adb (emulator അല്ലെങ്കിൽ hardware); [ADB guide](../adb-device-analysis.md) |
| JEB projects | Engine-backed project units, artifact digests, type/method pseudo-code | MCP സേവനം നൽകുന്ന caller ആരംഭിച്ച JEB client; REA_JEB_MCP_URL ഉപയോഗിച്ച് തിരഞ്ഞെടുക്കുക; [JEB guide](../jeb-analysis.md) |
| Android resources | Decoded manifest, string tables, locales, version വിവരങ്ങൾ | Caller നൽകുന്ന Apktool launcher; [resource guide](../apktool-resource-analysis.md) |
| Flutter apps | Dart snapshot hash, ഓരോ ABI-യിലെയും library digests, engine build provenance | ഒന്നും ആവശ്യമില്ല (static APK parsing); [Flutter guide](../flutter-analysis.md) |
| Firmware | Regions, extraction results, native-analysis handoffs | Linux-ൽ Binwalk / Unblob; [firmware guide](../firmware-analysis.md) |
| Recorded packets | തിരഞ്ഞെടുത്ത fields, ആവർത്തിക്കുന്ന values, filters, decode-as rules | Linux: TShark 4.x + prlimit; [capture guide](../packet-captures.md) |
| Packet summaries | Endpoints, DNS, TLS SNI, protocol distribution, HTTP requests | Caller നൽകുന്ന tshark, capinfos (Linux-ൽ പരിശോധിച്ചത്); [pcap guide](../pcap-analysis.md) |
| Recorded logic signals | Decoder annotations, sample ranges, diagnostics | Linux: sigrok-cli 0.7.2 + prlimit; [signal recordings](../signal-recordings.md) |
| Packages and resources | File inventories, digests, plists, Apple bundle ഘടന, extracted resources | [Artifact and JavaScript guide](../javascript-artifact-reconstruction.md), [Apple applications](../apple-application-analysis.md) |
| Process behavior | Terminal output, interactions, exit, filesystem observations, run comparisons | Native PTY ഉള്ള Linux/macOS; [process capture](../process-capture.md) |
Static JavaScript, .NET പരിശോധനകൾ application പ്രവർത്തിപ്പിക്കാതെ നൽകിയ files വായിച്ചാണ് നടത്തുന്നത്. Runtime capture, നിങ്ങളുടെ user permissions ഉപയോഗിച്ച് തിരഞ്ഞെടുത്ത target പ്രവർത്തിപ്പിക്കുകയോ അതുമായി ഇടപെടുകയോ ചെയ്യുന്നു; ഓരോ runtime guide-ലും അതിന്റെ പ്രത്യാഘാതങ്ങൾ വിശദീകരിച്ചിട്ടുണ്ട്.
Offline native-binary പരിശോധനയ്ക്കായി REA, caller നൽകുന്ന GNU objdump, Rizin എന്നിവയും പിന്തുണയ്ക്കുന്നു. Provider setup, CLI commands, Evidence-ന്റെ പരിമിതികൾ എന്നിവയ്ക്കായി [reverse-engineering tools guide](../reverse-engineering-tools.md) കാണുക. ഈ providers ഒന്നും REA ഇൻസ്റ്റാൾ ചെയ്യുകയോ അപ്‌ഡേറ്റ് ചെയ്യുകയോ ചെയ്യുന്നില്ല.
<a id="choosing-a-deep-analysis-provider"></a>
Native formats-ഉം host support-ഉം provider അനുസരിച്ച് വ്യത്യാസപ്പെടും. [Hopper and Ghidra setup](../installation.md#hopper), [IDA guide](../ida-provider.md) (ഐച്ഛിക native MCP bridge ഉൾപ്പെടെ), [Kuna decompiler guide](../kuna-provider.md), [പരീക്ഷണഘട്ടത്തിലുള്ള Windows Ghidra support](../windows-ghidra-p0.md) എന്നിവ കാണുക.
Ghidra, [16-bit DOS analysis](../ghidra-dos.md)-ഉം പിന്തുണയ്ക്കുന്നു.
വലിയ binaries-നായി `REA_GHIDRA_STARTUP_TIMEOUT_MS` അല്ലെങ്കിൽ `REA_HOPPER_STARTUP_TIMEOUT_MS` ഉപയോഗിച്ച് provider-ന്റെ startup deadline വർധിപ്പിക്കുക.
Provider തിരഞ്ഞെടുക്കാൻ [CLI guide](../cli.md#choose-a-provider) കാണുക.
ഏറ്റവും പുതിയ npm release-നുശേഷം ചേർത്ത features അറിയാൻ [release availability](../installation.md#released-package-and-main) പരിശോധിക്കുക.
## ഉദാഹരണങ്ങൾ
[![DX-Ball sound-pan, Notion clipboard-bridge, TH04 bullet-ring എന്നിവയുടെ ചിത്രീകരണങ്ങൾ](../assets/rea-showcases.png)](https://rea.tools/showcase/)
### DX-Ball: sound-pan കണക്കുകൂട്ടൽ പുനർനിർമ്മിക്കുക
ഒരു sound call-നെ അതിന്റെ position-to-pan helper വരെ പിന്തുടരുക, instructions പരിശോധിക്കുക, അപൂർണ്ണമായ pseudocode-നെ C-യാക്കി മാറ്റുക. ഈ പുനർനിർമ്മാണം യഥാർത്ഥ x86-ലെ 3,205 test cases വിജയിക്കുകയും compile ചെയ്ത function-ന്റെ 63 bytes-ഉം അതേപടി പുനരുത്പാദിപ്പിക്കുകയും ചെയ്യുന്നു.
[Case study വായിക്കുക](https://rea.tools/showcase/dx-ball/) ·
[പുനർനിർമ്മാണ repository](https://github.com/N0zoM1z0/dx-ball)
### Notion: Electron clipboard bridge പിന്തുടരുക
Renderer-ന്റെ clipboard API കണ്ടെത്തി, അതിനെ preload-ഉം IPC-ഉം വഴി main process വരെ പിന്തുടർന്ന് rich clipboard format പരിശോധിക്കുക.
[Case study വായിക്കുക](https://rea.tools/showcase/notion/)
### TH04: DOS bullet-ring കണക്കുകൂട്ടൽ വീണ്ടെടുക്കുക
യഥാർത്ഥ PC-98 game-ന്റെ 16-bit instructions പരിശോധിക്കുക, fixed, aimed angle കണക്കുകൂട്ടലുകൾ വീണ്ടെടുക്കുക, പുനർനിർമ്മിച്ച C++-നെ ചരിത്രപരമായ compiler output-ുമായി താരതമ്യം ചെയ്യുക.
[Case study വായിക്കുക](https://rea.tools/showcase/th04/) ·
[പുനർനിർമ്മാണ repository](https://github.com/N0zoM1z0/th04)
REA ഉപയോഗിച്ച് നിങ്ങൾ രസകരമായ എന്തെങ്കിലും പരിശോധിച്ചിട്ടുണ്ടെങ്കിൽ അത് കാണാൻ ഞങ്ങൾ ആഗ്രഹിക്കുന്നു. പരിശോധിച്ച target, നിങ്ങളുടെ ചോദ്യം, REA എങ്ങനെ സഹായിച്ചു, നിങ്ങൾ കണ്ടെത്തിയത് എന്നിവ ഉൾപ്പെടുത്തി [issue](https://github.com/morluto/rea/issues) അല്ലെങ്കിൽ [pull request](https://github.com/morluto/rea/pulls) വഴി നിങ്ങളുടെ case പങ്കിടുക.
## പതിവുചോദ്യങ്ങൾ
<details>
<summary><strong>ഏതൊക്കെ agents-ന് REA ഉപയോഗിക്കാം?</strong></summary>
Local MCP servers പിന്തുണയ്ക്കുന്ന ഏത് agent-നും REA ഉപയോഗിക്കാം. Setup, [പിന്തുണയ്ക്കുന്ന agents](../installation.md#supported-agents) ക്രമീകരിക്കുന്നു; മറ്റ് clients-ന് [manual MCP registration](../installation.md#mcp-registry) ഉപയോഗിക്കാം.
</details>
<details>
<summary><strong>Hopper, Ghidra അല്ലെങ്കിൽ IDA ആവശ്യമാണോ?</strong></summary>
ആഴത്തിലുള്ള native analysis-ന് ഇവയിൽ ഒന്ന് ആവശ്യമാണ്. Static JavaScript, .NET പരിശോധനകൾ native analysis engine ഇല്ലാതെയും പ്രവർത്തിക്കും. അനുമതി ലഭിച്ചാൽ setup-ന് Hopper ഇൻസ്റ്റാൾ ചെയ്യാം; Ghidra, IDA എന്നിവയ്ക്കായി നിങ്ങളുടെ നിലവിലുള്ള installations ഉപയോഗിക്കുന്നു. [Provider setup](../installation.md#hopper) കാണുക.
</details>
<details>
<summary><strong>Hopper ആദ്യം ആരംഭിക്കേണ്ടതുണ്ടോ?</strong></summary>
ഒരു operation-ന് ആവശ്യമാകുമ്പോൾ REA Hopper ആരംഭിക്കും. macOS-ൽ ആദ്യമായി പ്രവർത്തിപ്പിക്കുമ്പോൾ demo mode തിരഞ്ഞെടുക്കാനോ license activate ചെയ്യാനോ ആവശ്യപ്പെടുന്ന dialog പ്രത്യക്ഷപ്പെടാം. ആദ്യ CLI/MCP operation അല്ലെങ്കിൽ unattended job നടത്തുന്നതിന് മുമ്പ് അതേ user session-ൽ ആ prompt പൂർത്തിയാക്കുക. ആവശ്യമെങ്കിൽ Hopper സ്വമേധയാ തുറക്കുക. [Hopper startup and troubleshooting](../installation.md#launcher-paths-and-troubleshooting) കാണുക.
</details>
<details>
<summary><strong>skills.sh-ൽ നിന്ന് skill ഇൻസ്റ്റാൾ ചെയ്യുന്നത് എന്താണ് ചെയ്യുന്നത്?</strong></summary>
ഈ skill നിങ്ങളുടെ agent-ന് അന്വേഷണ നിർദ്ദേശങ്ങൾ നൽകുന്നു. REA-യുടെ MCP server രജിസ്റ്റർ ചെയ്യാനും അനുയോജ്യമായ നിർദ്ദേശങ്ങൾ ഇൻസ്റ്റാൾ ചെയ്യാനും `npx rea-agents setup` ഉപയോഗിക്കുക; തുടർന്ന് നിങ്ങളുടെ agent വീണ്ടും ആരംഭിക്കുക. [Skill-only installation](../installation.md#skill-only-installation) കാണുക.
</details>
<details>
<summary><strong>REA ഏത് തരത്തിലുള്ള code ആണ് നൽകുന്നത്?</strong></summary>
Native analysis pseudocode-ഉം assembly-ഉം നൽകുന്നു. JavaScript/Electron analysis modules-ഉം അവയുടെ ബന്ധങ്ങളും വീണ്ടെടുക്കുന്നു. ഈ കണ്ടെത്തലുകൾ ഉപയോഗിച്ച് നിങ്ങളുടെ agent implementation എഴുതുകയും പരിശോധിക്കുകയും ചെയ്യും; പ്രായോഗിക ഉദാഹരണങ്ങൾക്കായി [ഉദാഹരണങ്ങൾ](#showcases) കാണുക.
</details>
<details>
<summary><strong>REA എന്റെ app upload ചെയ്യുമോ?</strong></summary>
REA targets local ആയി വിശകലനം ചെയ്യുന്നു. Tool-ൽ നിന്നുള്ള ഫലങ്ങൾ നിങ്ങളുടെ agent-ന് ലഭിക്കും; അതിന്റെ model provider-ന് സ്വന്തമായ data policy ഉണ്ടായിരിക്കും.
</details>
<details>
<summary><strong>ഒരു bug നേരിട്ടാൽ എന്തുചെയ്യണം?</strong></summary>
ആദ്യം അപ്‌ഡേറ്റ് ചെയ്യുക; പുതിയ release-ൽ ആ പ്രശ്നത്തിനുള്ള പരിഹാരം ഇതിനകം ഉണ്ടായേക്കാം.
`npm install --global` അല്ലെങ്കിൽ `bun add --global` ഉപയോഗിച്ച് ഇൻസ്റ്റാൾ ചെയ്ത CLI-ക്കായി:
```bash
rea update
```
`npx` വഴി agent setup നടത്തുന്നതിനായി:
```bash
npx rea-agents@latest setup
```
നിങ്ങൾ agent ഉപയോഗിക്കുന്നുണ്ടെങ്കിൽ, [setup പുതുക്കൽ](#update-rea) പൂർത്തിയാക്കി അത് വീണ്ടും ആരംഭിക്കുക. അതേ task വീണ്ടും ശ്രമിക്കുക. പ്രശ്നം തുടരുകയാണെങ്കിൽ, നിങ്ങളുടെ REA version, target type, പ്രശ്നം ആവർത്തിക്കാൻ ആവശ്യമായ ഘട്ടങ്ങൾ, error output എന്നിവ ഉൾപ്പെടുത്തി [issue തുറക്കുക](https://github.com/morluto/rea/issues).
</details>
## ഡോക്യുമെന്റേഷൻ
വെബ്സൈറ്റിലെ [പ്രായോഗിക ഗൈഡുകൾ](https://rea.tools/guides/) ഉപയോഗിച്ച് തുടങ്ങുക.
കൃത്യമായ options, prerequisites, result contracts എന്നിവയ്ക്കായി:
- [Installation and setup](../installation.md): agent registration, provider configuration, updates, uninstall.
- [Readiness and troubleshooting](../installation.md#check-readiness-for-your-task): ഒരു agent-ന്റെയോ analysis engine-ന്റെയോ പ്രശ്നങ്ങൾ കണ്ടെത്തുക.
- [CLI and Evidence](../cli.md): commands, provider തിരഞ്ഞെടുക്കൽ, snapshots, import/export, exit statuses.
- [MCP contracts](../mcp-contracts.md), [agent prompts](../mcp-prompts.md): tool results, sessions, guided investigations.
- [Tool catalog](../mcp-contracts.md#generated-catalog): tools, providers, CLI commands എന്നിവയുടെ സ്വയമേവ സൃഷ്ടിച്ച പട്ടിക.
- [Roadmap](../roadmap.md): ആസൂത്രണം ചെയ്ത പ്രവർത്തനങ്ങളും capability trackers-ഉം.
സുരക്ഷാ ദുർബലതകൾ [SECURITY.md](../../SECURITY.md) വഴി റിപ്പോർട്ട് ചെയ്യുക.
## Star ചരിത്രം
🎉 **250,000 GitHub stars — നന്ദി!**
REA ഉപയോഗിക്കുന്നവർക്കും, bugs റിപ്പോർട്ട് ചെയ്യുന്നവർക്കും, features ആവശ്യപ്പെടുന്നവർക്കും, builds പരിശോധിക്കുന്നവർക്കും, fixes സംഭാവന ചെയ്യുന്നവർക്കും നന്ദി.
<a href="https://www.star-history.com/?repos=morluto%2Frea&amp;type=date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date&amp;theme=dark&amp;legend=top-left" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
<img alt="REA GitHub star ചരിത്രം" src="https://api.star-history.com/chart?repos=morluto/rea&amp;type=date" />
</picture>
</a>
## നിരാകരണം
ഉത്തരവാദിത്തത്തോടെ ഉപയോഗിക്കുന്നതിനുള്ള മാർഗനിർദ്ദേശങ്ങൾക്ക് [DISCLAIMER.md](../../DISCLAIMER.md) കാണുക.
നിയമവിരുദ്ധമോ അനുമതിയില്ലാത്തതോ ആയ ഉപയോഗത്തെക്കുറിച്ചുള്ള project-ന്റെ നിലപാട് എല്ലാ REA versions-നും distribution channels-നും platforms-നും ബാധകമാണ്; ഓരോ copy-യും അതിന് ബാധകമായ licenses നിലനിർത്തുന്നു.
നിയമാനുസൃതമായ research, education, interoperability, software preservation, കൂടാതെ നിങ്ങൾക്ക് സ്വന്തമായതോ പരിശോധിക്കാൻ അനുമതിയുള്ളതോ ആയ software-ന്റെ analysis എന്നിവയ്ക്കാണ് REA ഉദ്ദേശിച്ചിരിക്കുന്നത്.
## സംഭാവനകൾ
REA-യ്ക്കായി നിങ്ങളുടെ സഹായം ഞങ്ങൾ സ്വാഗതം ചെയ്യുന്നു! bug റിപ്പോർട്ട് ചെയ്യാനോ feature നിർദ്ദേശിക്കാനോ [issue തുറക്കുക](https://github.com/morluto/rea/issues), code അല്ലെങ്കിൽ docs മെച്ചപ്പെടുത്താൻ [pull request അയയ്ക്കുക](https://github.com/morluto/rea/pulls).
Development setup-നും checks-നും [CONTRIBUTING.md](../../CONTRIBUTING.md), verification lanes-നായി [testing](../testing.md), project ഘടനയ്ക്കായി [architecture map](../architecture.mermaid) എന്നിവ കാണുക.
## ലൈസൻസ്
[MIT](../../LICENSE)
REA-യുടെ രചയിതാക്കൾ സൃഷ്ടിച്ച code MIT license പ്രകാരമാണ് ലൈസൻസ് ചെയ്തിരിക്കുന്നത്. Third-party material അതിന്റെ സ്വന്തം licenses-ഉം copyright notices-ഉം നിലനിർത്തുന്നു; dependencies-ന്റെ പട്ടിക, നിലനിർത്തിയ license text-ുകൾ, external tool നിബന്ധനകൾ എന്നിവയ്ക്കായി [Third-party notices](../../THIRD_PARTY_NOTICES.md) കാണുക.
**IDA Pro / Hex-Rays decompilers, Hopper, JEB എന്നിവ ഉൾപ്പെടെയുള്ള commercial tools നിയമാനുസൃതമായി സ്വന്തമാക്കുകയും അവയുടെ ബാധകമായ licenses പ്രകാരം ഉപയോഗിക്കാൻ അനുമതിയുണ്ടെന്ന് ഉറപ്പാക്കുകയും വേണം.** REA ഒരു tool license-ഓ key-യോ activation entitlement-ഓ നൽകുന്നില്ല. Trials-ഉം demos-ഉം ഉൾപ്പെടെ vendor നിബന്ധനകൾക്ക് വിധേയമാണ്; ഇതിൽ user, feature, automation, output sharing നിയന്ത്രണങ്ങളും ഉൾപ്പെടാം. Cracked copies, മോഷ്ടിച്ച keys, അനുമതിയില്ലാത്ത key sharing, license നിയന്ത്രണങ്ങൾ മറികടക്കൽ എന്നിവയ്ക്ക് അനുമതിയില്ല. ഈ മാർഗനിർദ്ദേശം MIT അല്ലെങ്കിൽ third-party licenses-ൽ മാറ്റം വരുത്തുന്നില്ല.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · **Polski** · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Reverse Engineer Anything
@@ -272,7 +272,7 @@ Zgłaszaj podatności zgodnie z [SECURITY.md](../../SECURITY.md).
## Historia gwiazdek
🎉 **250 000 gwiazdek na GitHubie — dziękujemy!**
🎉 **300 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.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · **Português (Brasil)** · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Faça engenharia reversa de qualquer coisa
@@ -272,7 +272,7 @@ Relate vulnerabilidades conforme [SECURITY.md](../../SECURITY.md).
## Histórico de estrelas
🎉 **250.000 estrelas no GitHub — muito obrigado!**
🎉 **300.000 estrelas no GitHub — muito obrigado!**
Obrigado a todos que usam o REA, relatam bugs, sugerem funcionalidades, testam builds e contribuem com correções.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · **Русский** · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Реверс-инжиниринг чего угодно
@@ -272,7 +272,7 @@ npx rea-agents@latest setup
## История звёзд
🎉 **250 000 звёзд на GitHub — спасибо!**
🎉 **300 000 звёзд на GitHub — спасибо!**
Спасибо всем, кто использует REA, сообщает об ошибках, предлагает новые функции, тестирует сборки и помогает с исправлениями.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · **ไทย** · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Reverse Engineer Anything
@@ -272,7 +272,7 @@ npx rea-agents@latest setup
## ประวัติดาว
🎉 **250,000 ดาวบน GitHub — ขอบคุณทุกคน!**
🎉 **300,000 ดาวบน GitHub — ขอบคุณทุกคน!**
ขอบคุณทุกคนที่ใช้ REA รายงานบั๊ก เสนอฟีเจอร์ ทดสอบบิลด์ และช่วยแก้ไข
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · **Türkçe** · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Her şeyi tersine mühendislikle inceleyin
@@ -277,7 +277,7 @@ Güvenlik açıklarını [SECURITY.md](../../SECURITY.md) üzerinden bildirin.
## Yıldız geçmişi
🎉 **GitHub'da 250.000 yıldız — teşekkürler!**
🎉 **GitHub'da 300.000 yıldız — teşekkürler!**
REA'yı kullanan, hata bildiren, özellik talep eden, derlemeleri test eden ve düzeltmelere katkıda bulunan herkese teşekkürler.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · **Українська** · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Реверс-інжиніринг будь-чого
@@ -272,7 +272,7 @@ npx rea-agents@latest setup
## Історія зірок
🎉 **250 000 зірок на GitHub — дякуємо!**
🎉 **300 000 зірок на GitHub — дякуємо!**
Дякуємо всім, хто використовує REA, повідомляє про помилки, пропонує нові функції, тестує збірки й допомагає з виправленнями.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · **Tiếng Việt** · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA: Kỹ thuật dịch ngược cho mọi thứ
@@ -272,7 +272,7 @@ Báo cáo lỗ hổng theo [SECURITY.md](../../SECURITY.md).
## Lịch sử sao
🎉 **250.000 sao trên GitHub — xin cảm ơn!**
🎉 **300.000 sao trên GitHub — xin cảm ơn!**
Cảm ơn mọi người đã sử dụng REA, báo lỗi, đề xuất tính năng, kiểm thử bản dựng và đóng góp bản sửa lỗi.
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · [简体中文](README_zh.md) · **繁體中文** · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA:逆向一切
@@ -278,7 +278,7 @@ npx rea-agents@latest setup
## Star 歷史
🎉 **GitHub Star 達到 250,000 個,感謝大家!**
🎉 **GitHub Star 達到 300,000 個,感謝大家!**
感謝每一位使用 REA、報告錯誤、提出功能需求、測試建置和貢獻修復的朋友。
+2 -2
View File
@@ -1,7 +1,7 @@
<div align="center">
[English](../../README.md) · **简体中文** · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md) · [Bahasa Indonesia](README_id.md) · [Italiano](README_it.md)
· [Ελληνικά](README_el.md)
· [Ελληνικά](README_el.md) · [മലയാളം](README_ml.md)
# REA:逆向一切
@@ -278,7 +278,7 @@ npx rea-agents@latest setup
## Star 历史
🎉 **GitHub Star 达到 250,000 个,感谢大家!**
🎉 **GitHub Star 达到 300,000 个,感谢大家!**
感谢每一位使用 REA、报告错误、提出功能需求、测试构建和贡献修复的朋友。
+18 -4
View File
@@ -61,9 +61,21 @@ The outer provider owns both processes and one stable core snapshot. An owned
Python launcher lowers inherited soft limits before replacing itself with GDB.
GDB starts without initfiles, auto-load, debuginfod or automatic shared-library
loading. Owned empty library search paths and caches are used, with plugin
updates disabled. Fixed package code verifies a core connection and no paired
executable before querying mapping candidates. No caller GDB command language is
exposed. The exact observed GDB/plugin version strings are retained.
updates disabled. Debug-file lookup is also restricted to the owned empty
search directory. GDB 16 can otherwise locate the recorded executable independently
of these settings. While opening the core, fixed package code temporarily selects
`/proc/self/exe` (the already running debugger) with `exec-file`, without loading
symbols or running an inferior. This occupies GDB's executable slot and prevents
its automatic executable discovery. The validated decoder profile selects the
core architecture explicitly, so the placeholder cannot select it instead. The
bridge discards that selection with `file` before querying mapping candidates,
and verifies the core connection and absence of a main symbol file. Before launching GDB, the provider also checks
source-bound `NT_FILE` descriptors: mapping names must be absolute Unix paths
without dot segments. Relative names bypass GDB's sysroot, and traversal can
escape it. Unresolved or unsafe mapping coverage refuses debugger enrichment
while retaining the basic decoded observation and original bytes. No caller GDB
command language is exposed. The exact observed GDB/plugin version strings are
retained.
Mapping names are producer display metadata, with unknown current file identity.
Map permissions are derived from reported flags; zero/unfamiliar flags leave
@@ -93,4 +105,6 @@ GDB/Python/pwndbg/strace. Fixture generation explicitly launches its owned test
program; subsequent inspection only reads the resulting core. Real acceptance
checks recorded threads, high registers, missing/malformed notes, opaque owners,
CLI/MCP parity, optional debugger context and historical PID collision with an
owned live sentinel. Original inputs and host configuration remain unchanged.
owned live sentinel. The syscall trace also rejects access to the still-present
source executable. The CI workflow defines Ubuntu 24.04 and Debian 13 (GDB 16)
container lanes. Original inputs and host configuration remain unchanged.
File diff suppressed because it is too large. Load diff
+112
View File
@@ -0,0 +1,112 @@
{
"schemaVersion": 1,
"repository": "morluto/rea",
"version": "6.7.0",
"base": "2c4338db1fdb7773e05376301c558cff2a0b4b80",
"target": "b83b9caf4a5f0241a5fd370792f1aed1bffbb2cf",
"commits": [
{
"sha": "8cbaf6c7021b97dd4de6b5771c35fbed06b240e9",
"subject": "fix(tests): isolate command finalization module mocks",
"body": "fix(tests): isolate command finalization module mocks\n\nMove the five registered WASM finalization cases into the existing per-file isolated project. Preserve all result, exit-code, observation and cleanup assertions. A preloaded shared CLI graph reproduces three failures before the move; the isolated covered packet passes.\n\nFixes #4959\n",
"parents": ["2c4338db1fdb7773e05376301c558cff2a0b4b80"],
"authors": [
{
"name": "morluto",
"email": "76467478+morluto@users.noreply.github.com",
"user": {
"login": "morluto",
"__typename": "User"
}
}
],
"pullRequests": []
},
{
"sha": "6b180783ed04ebc87548c8385c80e05725804c47",
"subject": "fix(tests): budget CLI coverage from parsed options",
"body": "fix(tests): budget CLI coverage from parsed options\n\nUse the pinned Vitest parser for coverage and shard flags. Keep ordinary CLI workers at 384 MiB and covered workers at the tested 512 MiB with unchanged concurrency. Retain complete coverage and add actual-config regressions for false, provider-only and spaced-shard options.\n\nValidation: 27 focused cases; 16 covered cases with CLI preloaded; 5 docs checks; typecheck/lint; exact discovery of 1578 files. Measured covered control: 22.18s elapsed, 46.52s CPU, about 2.33 GiB sampled summed process-family RSS on macOS arm64. Full Linux CI pending. No runtime/device verification claimed.\n\nFixes #4960\n",
"parents": ["8cbaf6c7021b97dd4de6b5771c35fbed06b240e9"],
"authors": [
{
"name": "morluto",
"email": "76467478+morluto@users.noreply.github.com",
"user": {
"login": "morluto",
"__typename": "User"
}
}
],
"pullRequests": []
},
{
"sha": "bb212ffecb47e129cc569b9867b2b6e7c9b65685",
"subject": "fix(tests): inherit server identity deadline policy",
"body": "fix(tests): inherit server identity deadline policy\n\nRemove per-case ten-second overrides from MCP catalog and identity checks. Keep the suite-owned bounded ordinary and coverage deadlines, all assertions, and session cleanup.\n\nFixes #4967\n",
"parents": ["6b180783ed04ebc87548c8385c80e05725804c47"],
"authors": [
{
"name": "morluto",
"email": "76467478+morluto@users.noreply.github.com",
"user": {
"login": "morluto",
"__typename": "User"
}
}
],
"pullRequests": []
},
{
"sha": "b83b9caf4a5f0241a5fd370792f1aed1bffbb2cf",
"subject": "fix(setup): edit the duplicate JSON member that clients read (#4957)",
"body": "fix(setup): edit the duplicate JSON member that clients read (#4957)\n\nJSON.parse, JSONC parse, and native Claude Code keep the last duplicate\nobject member, and parseClientConfiguration therefore validates the last\none. The shared setup/uninstall serializer instead edited text through\njsonc-parser's modify and findNodeAtLocation, which select the first\nmatching member, so setup and uninstall on configurations with repeated\nserver tables or rea members wrote into a shadowed member and failed\nreadback.\n\nLocate every JSON text edit by the effective (last) member in one place,\nreplacing the first-member modify path. Removing an effective member\nthat shadows an earlier duplicate would activate that duplicate, whatever\nits ownership, so the serializer now returns a tagged shadowed_member\nfailure and setup and uninstall refuse before writing a backup or the\nconfiguration.\n\nFixes #4952\n\nCo-authored-by: Claude Opus 5.5 <noreply@anthropic.com>",
"parents": ["bb212ffecb47e129cc569b9867b2b6e7c9b65685"],
"authors": [
{
"name": "Kaoru0822",
"email": "kanadekitauji@proton.me",
"user": {
"login": "kaoru0822-kitauji",
"__typename": "User"
}
},
{
"name": "Claude Opus 5.5",
"email": "noreply@anthropic.com",
"user": {
"login": "claude",
"__typename": "User"
}
}
],
"pullRequests": [4957]
}
],
"pullRequests": [
{
"number": 4957,
"title": "fix(setup): edit the duplicate JSON member that clients read",
"url": "https://github.com/morluto/rea/pull/4957",
"author": {
"login": "kaoru0822-kitauji",
"__typename": "User"
},
"mergeCommit": {
"oid": "b83b9caf4a5f0241a5fd370792f1aed1bffbb2cf"
},
"issues": [
{
"number": 4952,
"url": "https://github.com/morluto/rea/issues/4952",
"author": {
"login": "xu91102",
"__typename": "User"
},
"repository": {
"nameWithOwner": "morluto/rea"
}
}
]
}
]
}
+4 -1
View File
@@ -57,7 +57,10 @@ triggers or arbitrary SQL.
Rows are optional. `table` selects one exact ordinary-table name. `columns`
(CLI repeated `--column`) selects exact visible column names in the requested
order; omission selects all visible columns, including generated columns.
Unselected cells are not evaluated or projected. Column selection requires a
Unselected cells are not evaluated or projected. Malformed column-name bytes
cause a format refusal when all columns are requested. In inventory scope, an explicit valid subset can
still be sampled without decoding unrelated malformed column names.
Column selection requires a
table and at least one name; empty-string identifiers are valid. `row_limit`
requires `table`, defaults to 20 and accepts positive safe integers. Samples
remain subject to the byte and worker resource limits below, regardless of row count. The result reports
+45 -6
View File
@@ -110,9 +110,14 @@ rendered declarations. Keep canonical rejection checks separate from the
intentionally reduced compact advertisement, and probe actual client renderers
when changing schema representations.
The reused CLI boundary workers cap V8 old space at 384 MiB, based on their
profiled allocation and cleanup behavior. This encourages collection between
files; spawned REA processes retain their own heap settings.
The reused CLI boundary workers cap V8 old space at 384 MiB for ordinary runs
and 512 MiB with coverage enabled. Covered ADB fixtures exhaust the ordinary
384 MiB budget; those fixtures also complete with the shared CLI graph preloaded
at 512 MiB. This is a measured capacity control, not a suite-wide speedup claim.
Both profiles keep the
same bounded worker count, and spawned REA processes retain their own heap
settings. Explicitly disabling coverage retains the ordinary profile; coverage
provider options alone do not enable instrumentation.
Vitest worker limits do not bound subprocesses launched within a test. Bound
those batches separately so repeated CLI validation cannot oversubscribe the
@@ -216,6 +221,12 @@ controlled production seam for interleavings that cannot be reproduced reliably.
| Cleanup fails after success or primary failure | Public output retains the completed observation or primary diagnostic, remaining resources, and owner recovery action. Restore the denied resource and verify the owning cleanup retry. |
| Target exits without an acknowledgement, or transport disappears while it stays alive | Positive owned exit proof resolves target lifetime; other resources still need cleanup. Lost transport alone does not prove exit. Verify unrelated/attached targets survive and same-connection recovery works when supported. |
Shared process-supervision controls separate leader exit from output closure.
Cover output during held or failed cleanup, bounded retention and drain timeout,
retry, and borrowed stream authority. The POSIX inherited-stderr control uses a
separate pipe as a release barrier after leader exit; it does not establish
native Windows Job Object behavior.
Synchronize cancellation with the finalization boundary being tested; a fixed
delay after dispatch does not establish that phase. Use markers, barriers, or
owned cleanup seams while preserving real cleanup where feasible. Check server
@@ -225,6 +236,21 @@ cover cancellation during final cleanup.
Use explicit abort reasons and assert their identity at admission and after
provider completion, alongside retained observations and cleanup state.
Electron fuse regressions cover actual descriptor close denial and retry through
the built CLI, same-connection MCP recovery, mixed descriptor outcomes, and
server shutdown. Controlled seams cover cancellation during final close and
after reader finalization, plus active-provider shutdown during preflight.
They preserve real filesystem cleanup where possible; mocked launch boundaries
do not establish real Electron teardown or naturally occurring OS failures.
Active Electron cleanup controls retain independent transport and process-family
owners, block replacement captures until recovery, and retry only unresolved
owners. Cover late close acknowledgement and rejection after a wait deadline,
opaque rejection reasons, cancellation during failed finalization, and missing
lineage followed by a confirmed passive family census. Windows controls require
a fresh lineage observation and do not signal cached descendant PIDs after root
termination. Simulated Windows controls do not establish native Windows behavior.
For atomic writes, exercise cancellation on both sides of the documented commit
point and preserve any publication receipt. A late interruption does not prove
that no output was published.
@@ -503,7 +529,7 @@ costs. Its queue, execution, and failures are independent of the required gate
and publication. CPU time and peak process-family memory are not measured by this API.
The build job saves portable Turbo outputs across runs. Eight Linux real-system
lanes restore this cache without waiting for the build job. The shared action
lanes reuse its current-run artifact; standalone dispatches restore the cross-run cache. The shared action
derives its key from `test:prepare --dry=json` task hashes, runner OS and
architecture, `.npmrc`, `.nvmrc`, and the lockfile; test-only changes can reuse compiled outputs. Every
build and verification command still runs, so Turbo checks task inputs and
@@ -513,7 +539,15 @@ that generator's entry. Native outputs are not stored in this cache.
Native package jobs, the Windows curated lane, and the Apple artifact lane reuse
the same workflow's Turbo cache for portable compiled JavaScript, skills, and
catalogs. The Windows lane relies on the Linux static job for typechecking. They retain the normal build and prepack
catalogs. The key parser retains the validated `test:prepare` task identities in
`.cache/ci-build-plan.json`; staging reads this plan without starting another
Turbo run that could evict cache entries. The producer stages matching archives,
metadata, and available manifests into `.cache/ci-build-cache/`.
`portable-build-cache.json` records availability per task. Evicted or partially
missing entries are omitted as whole entries, and consumers rebuild cache misses,
including when every entry is unavailable. Malformed plans, non-file entries,
and I/O errors other than disappearance still fail publication. Older cross-run entries stay in the
original cache. The Windows lane relies on the Linux static job for typechecking. They retain the normal build and prepack
commands, which restore matching outputs or rebuild on a cache miss. Native
artifacts, dependency installs, package archives, and runtime verification remain
host-local. Keep platform-dependent outputs out of this shared cache.
@@ -1536,7 +1570,12 @@ NUL-containing names. It compares exact WAT,
section output and selected/tool digests through the compiled CLI and real MCP
SDK, validates advertised schemas, checks identical CLI/MCP Evidence IDs and
session bundle readback, retains invalid/truncated module diagnostics, preserves
all inputs and checks workspace cleanup. Pass an installed package's
all inputs and checks workspace cleanup.
The lane also injects one cleanup denial for exact private runtime roots and
input descriptors, checks recovered CLI errors, and verifies retry on the same
MCP connection after repeated runtime-removal denial. These are controlled
faults, not naturally occurring permission failures; no WASM target is executed.
Pass an installed package's
`scripts/rea.mjs` as the first argument to run the same lane against the package.
`npm run verify:wasm:package` packs and installs REA into an isolated temporary
prefix with lifecycle scripts disabled and runs the same required real-tool lane.
+7
View File
@@ -79,6 +79,13 @@ providers need not expose identical state machines.
and resource release separate. A valid process handle, successful launcher,
or selected target establishes only its own fact. Publish available identity
and exit observations even when launch fails; retain unknown ownership.
- Process exit does not establish output closure. The shared process supervisor
retains at most 64 KiB of additional diagnostics from owned stop entry,
including pending cleanup and retries, and drains for up to one second after
verified stop. It marks output incomplete when closure cannot be
observed and releases owned event-loop references without changing the proven
process-cleanup outcome. Failed process cleanup retains capture for retry;
borrowed processes and streams retain their own lifetime and reference state.
- Authenticate and capture identity through the same boundary on initial and
recovery handshakes. Bound abandoned unauthenticated listeners where the
protocol permits it; that deadline must not expire authenticated idle sessions
@@ -1,5 +1,12 @@
# Analysis efficiency measurements
For authentic old Evidence and mixed investigations, see the
[retained-query checkpoint](retained-investigation-workflows.md).
`retained-investigation.mjs` compares existing complete delivery with selected
pages, including capacity-refusal recovery and original-record round trips.
It records negative model results and separates imported-format validation work
from the query contract.
For genuine Fiddler captures, see the [SAZ selection checkpoint](saz-selection-workflows.md).
`measure.mjs --saz-selection baseline|focused|retained` compares default complete
delivery (including retained-reference recovery), caller-selected ordinals, and
+13 -119
View File
@@ -4,7 +4,6 @@ import argparse
import hashlib
import json
import os
import re
from pathlib import Path
import shutil
import signal
@@ -23,31 +22,7 @@ def file_digest(path):
return digest.hexdigest()
def pinned_experimental_engine(settings):
expected = settings.get('REA_ATOMIC_NATIVE_IR_ENGINE_SHA256')
if expected is None:
return None
if not re.fullmatch(r'[0-9a-f]{64}', expected):
raise ValueError('Experimental native engine pin must be a SHA-256')
path = Path(settings.get('REA_KUNA_COMMAND', ''))
if not path.is_absolute() or not path.is_file() or not os.access(path, os.X_OK):
raise ValueError('Pinned experimental engine requires an absolute executable file')
actual = file_digest(path)
if actual != expected:
raise ValueError('Experimental engine digest differs from its pin; use a preserved build artifact')
return {'path': str(path), 'sha256': actual}
def experimental_engine_unchanged(receipt):
if receipt is None:
return None
try:
return file_digest(Path(receipt['path'])) == receipt['sha256']
except OSError:
return False
def runtime_fingerprint(root, entrypoint=None):
def runtime_fingerprint(root):
files = []
for name in ['dist', 'bridge']:
for path in sorted((root / name).rglob('*')):
@@ -55,18 +30,6 @@ def runtime_fingerprint(root, entrypoint=None):
raise ValueError('Runtime fingerprint does not follow symlinks')
if path.is_file():
files.append({'path': path.relative_to(root).as_posix(), 'sha256': file_digest(path)})
if entrypoint is not None:
# Include the experimental modules and their installed QuickJS JS/WASM,
# plus the shared fact owner; the entrypoint alone does not pin them.
for directory in [entrypoint.parent, root / 'experiments/atomic-re-tools']:
for path in sorted(directory.rglob('*')):
if path.suffix not in {'.mjs', '.cjs', '.js', '.wasm'} and path.name not in {'package.json', 'package-lock.json'}:
continue
if path.is_symlink():
raise ValueError('Experimental runtime fingerprint does not follow symlinks')
if path.is_file():
label = path.relative_to(root).as_posix() if path.is_relative_to(root) else path.as_posix()
files.append({'path': label, 'sha256': file_digest(path)})
files.sort(key=lambda row: row['path'])
text = json.dumps(files, separators=(',', ':'), ensure_ascii=False)
return files, hashlib.sha256(text.encode()).hexdigest()
@@ -76,12 +39,6 @@ def main():
parser = argparse.ArgumentParser()
parser.add_argument('--mode', choices=['direct', 'client-code'], default='direct')
parser.add_argument('--runtime-root', type=Path, required=True)
parser.add_argument('--mcp-entrypoint', type=Path,
help='Caller-selected experimental stdio MCP entrypoint; leaves production dispatcher unchanged')
parser.add_argument('--server-name', default='rea')
parser.add_argument('--protocol-profile', choices=['canonical', 'atomic', 'atomic-direct'], default='canonical')
parser.add_argument('--profile-parent', type=Path,
help='Absolute parent outside the repository for the isolated model workspace')
parser.add_argument('--revision', required=True)
parser.add_argument('--prompt', type=Path, required=True)
parser.add_argument('--artifact-path', help='Replace {{artifact_path}} in a question template')
@@ -97,10 +54,6 @@ def main():
help='Retain owned tool/usage items; excludes account/ambient state')
parser.add_argument('--guide-enabled-tools', action='store_true',
help='Opt-in exact-name discovery guidance for selected REA tools')
parser.add_argument('--normalize-mcp-guidance', action='store_true',
help='Opt-in common envelope/stopping guidance, identical across protocol lanes')
parser.add_argument('--guide-long-waits', action='store_true',
help='Opt-in common client wait guidance; does not change analysis contracts or deadlines')
args = parser.parse_args()
if args.guide_enabled_tools and args.enabled_tools is None:
parser.error('--guide-enabled-tools requires --enabled-tools')
@@ -141,19 +94,13 @@ def main():
if undeclared:
raise ValueError('Declare inherited provider settings explicitly in --providers: '
+ ', '.join(undeclared) + '. Values are not logged.')
# Fail before copying credentials or spending model tokens. Cargo test/build
# can replace a mutable target/release path with a different feature build.
experimental_engine = pinned_experimental_engine(provider_env)
source_auth_home = (Path(os.environ['CODEX_HOME']) if 'CODEX_HOME' in os.environ
else Path.home() / '.codex')
source_auth = source_auth_home / 'auth.json'
args.output.mkdir(parents=True, exist_ok=False, mode=0o700)
runtime_files, runtime_digest = runtime_fingerprint(repository, args.mcp_entrypoint)
runtime_files, runtime_digest = runtime_fingerprint(repository)
(args.output / 'runtime-files.json').write_text(json.dumps(runtime_files))
if args.profile_parent and (not args.profile_parent.is_absolute()
or args.profile_parent.resolve().is_relative_to(repository.resolve())):
raise ValueError('profile-parent must be an absolute directory outside runtime-root')
profile = Path(tempfile.mkdtemp(prefix='rea-model-profile-', dir=args.profile_parent or args.output))
profile = Path(tempfile.mkdtemp(prefix='profile-', dir=args.output))
trial_codex_home = profile / 'codex'
account = profile / 'account'
workspace = profile / 'workspace'
@@ -172,12 +119,7 @@ def main():
'NODE_OPTIONS': '--max-old-space-size=512',
})
target_digest = file_digest(Path(args.artifact_path)) if args.artifact_path else None
if not args.server_name.replace('-', '').replace('_', '').isalnum():
raise ValueError('server-name must contain only letters, digits, hyphens or underscores')
if args.mcp_entrypoint and not args.mcp_entrypoint.is_absolute():
raise ValueError('mcp-entrypoint must be absolute')
command_args = ([str(args.mcp_entrypoint)] if args.mcp_entrypoint
else [str(repository / 'scripts/rea.mjs'), 'mcp'])
command_args = [str(repository / 'scripts/rea.mjs'), 'mcp']
instruction = (
'Use the registered REA MCP server for this investigation. Static analysis '
'only: do not execute target code, fetch URLs, launch a GUI, or modify targets. '
@@ -190,23 +132,6 @@ def main():
'Prefer summary/focused views where appropriate. Do not invent successful facts '
'after a tool error. No other agents. Stop once the requested facts are supported.'
)
if args.protocol_profile in {'atomic', 'atomic-direct'}:
instruction = (
'Use the registered ' + args.server_name + ' MCP server for this static binary investigation. '
'Call reference to inspect API contracts, then compose the supported analysis calls. '
'Do not execute target code, fetch URLs, launch a GUI, modify targets, use shell/file tools, '
'or use other agents. API methods return {ok,context,data} or {ok:false,error}; '
'execute_javascript returns the script value, with script-derived authority. '
'Preserve real evidence_id values, artifact digest, uncertainty and traversal boundaries. '
'Check failures before reading data. Do not infer absence from partial coverage. '
'Do not return complete inventories or source reports when a focused answer suffices. '
'Close the binary when finished. No precomputed answer is available to you.'
)
if args.protocol_profile == 'atomic-direct':
instruction = instruction.replace(
'execute_javascript returns the script value, with script-derived authority. ',
'Call the registered facts_* tools directly; no JavaScript execution tool is registered. '
)
if args.authority == 'browser':
instruction = (
'Use the registered REA tools for the explicitly selected public browser scenario. '
@@ -222,31 +147,14 @@ def main():
'possible and select the requested normalized_result fields before returning '
'intermediate output to model context. Keep real Evidence IDs and limitations.'
)
if args.normalize_mcp_guidance:
instruction += (
' MCP calls return transport envelopes: prefer structuredContent when present; '
'otherwise parse the text content JSON. Do not print both duplicate encodings. '
'Apply the same rule to every tool. Stop once the requested facts are supported, '
'state missing coverage explicitly, and close the binary when finished.'
)
if args.guide_enabled_tools:
instruction += (
' Configured REA server label: ' + json.dumps(args.server_name)
+ '. Enabled tool base names for this trial: ' + json.dumps(enabled_tools)
+ '. Discover their actual registered callable names from ALL_TOOLS metadata; '
'do not construct a namespace from the server label. Select only matching '
'enabled base names and return only their metadata. Preserve the original analyst question, '
' Configured REA tool function names for this trial: '
+ json.dumps(['mcp__rea__' + name for name in enabled_tools])
+ '. For discovery select only these exact names from ALL_TOOLS and '
'return only their metadata. Preserve the original analyst question, '
'dependency order and source Evidence.'
)
if args.guide_long_waits:
instruction += (
' When the client executor reports a running cell during a long analysis, '
'resume that same cell with wait and yield_time_ms:30000, within the '
'advertised tool schema, rather than repeated one-second polls. '
'The wait may return early when the result is ready. Do not sleep or '
'start duplicate analysis calls just to check completion. Keep the '
'original analysis dependencies, evidence and stopping requirements.'
)
quote = json.dumps
config = '\n'.join([
'approval_policy = "never"', 'sandbox_mode = "read-only"',
@@ -258,16 +166,16 @@ def main():
'code_mode = ' + ('true' if args.mode == 'client-code' else 'false'),
'code_mode_only = ' + ('true' if args.mode == 'client-code' else 'false'),
'[history]', 'persistence = "none"',
'[mcp_servers.' + args.server_name + ']', 'command = ' + quote(node),
'[mcp_servers.rea]', 'command = ' + quote(node),
'args = ' + quote(command_args), 'startup_timeout_sec = 60',
'tool_timeout_sec = 600',
*([] if enabled_tools is None else ['enabled_tools = ' + quote(enabled_tools)]),
'[mcp_servers.' + args.server_name + '.env]',
'[mcp_servers.rea.env]',
*[key + ' = ' + quote(value) for key, value in provider_env.items()],
]) + '\n'
# MCP read-only hints cover normal static tools. Explicitly authorize only
# the session-opening primitive needed by the requested native tasks.
config += '[mcp_servers.' + args.server_name + '.tools.open_binary]\napproval_mode = "approve"\n'
config += '[mcp_servers.rea.tools.open_binary]\napproval_mode = "approve"\n'
for tool in ['analyze_javascript_application', 'inspect_analysis_view',
'inspect_android_package', 'search_android_classes',
'inspect_android_class', 'inspect_android_method',
@@ -279,9 +187,10 @@ def main():
'inspect_managed_members', 'inspect_managed_native_boundaries',
'inspect_artifact', 'inspect_wasm_artifact',
'inspect_evm_interface', 'get_evidence_bundle', 'export_evidence_bundle',
'import_evidence_bundle', 'list_unknowns', 'verify_unknown_resolution',
'capture_browser_scenario',
'resolve_containing_procedure', 'analyze_function', 'close_binary']:
config += '[mcp_servers.' + args.server_name + '.tools.' + tool + ']\napproval_mode = "approve"\n'
config += '[mcp_servers.rea.tools.' + tool + ']\napproval_mode = "approve"\n'
try:
if source_auth.exists():
shutil.copyfile(source_auth, auth)
@@ -301,17 +210,10 @@ def main():
'mode': args.mode, 'model': args.model, 'reasoning': args.reasoning,
'capture_tool_context': args.capture_tool_context,
'guide_enabled_tools': args.guide_enabled_tools,
'normalize_mcp_guidance': args.normalize_mcp_guidance,
'guide_long_waits': args.guide_long_waits,
'driver_commit': subprocess.check_output(
['git', 'rev-parse', 'HEAD'], cwd=driver_repository, text=True).strip(),
'runtime_revision': args.revision,
'runtime_root': str(repository),
'mcp_server_name': args.server_name,
'protocol_profile': args.protocol_profile,
'isolated_profile_parent': str(args.profile_parent) if args.profile_parent else str(args.output),
'mcp_entrypoint': str(args.mcp_entrypoint) if args.mcp_entrypoint else None,
'mcp_entrypoint_sha256': file_digest(args.mcp_entrypoint) if args.mcp_entrypoint else None,
'selected_artifact_path': args.artifact_path,
'selected_artifact_sha256_before': target_digest,
'enabled_tools': enabled_tools,
@@ -329,7 +231,6 @@ def main():
'question_template_sha256': template_digest,
'provider_settings_sha256': hashlib.sha256(
json.dumps(provider_env, sort_keys=True).encode()).hexdigest(),
'experimental_engine': experimental_engine,
'provider_search_path_sha256': hashlib.sha256(
provider_env.get('PATH', os.environ.get('PATH', '')).encode()).hexdigest(),
'provider_environment_policy_sha256': hashlib.sha256(
@@ -382,9 +283,6 @@ def main():
summary = {
'mode': args.mode, 'requested_model': args.model, 'reasoning': args.reasoning,
'runtime_revision': args.revision,
'runtime_inputs_unchanged': runtime_fingerprint(repository, args.mcp_entrypoint)[1] == runtime_digest,
'experimental_engine': experimental_engine,
'experimental_engine_unchanged': experimental_engine_unchanged(experimental_engine),
'capture_tool_context_requested': args.capture_tool_context,
'selected_artifact_sha256_before': target_digest,
'selected_artifact_sha256_after': final_target_digest,
@@ -399,10 +297,6 @@ def main():
}
(args.output / 'summary.json').write_text(json.dumps(summary, indent=2) + '\n')
print(json.dumps(summary))
if not summary['runtime_inputs_unchanged']:
raise RuntimeError('Runtime inputs changed during the trial; retain costs but reject the comparison')
if summary['experimental_engine_unchanged'] is False:
raise RuntimeError('Experimental engine changed during the trial; retain costs but reject the comparison')
finally:
try:
if args.capture_tool_context:
@@ -68,15 +68,10 @@ def stop_owned_scope(unit, process, group):
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--task-ceiling', type=int, default=192)
parser.add_argument('--early-stop-mib', type=int, default=3072,
help='Memory pre-stop threshold; hard cap remains 4 GiB (default 3072 MiB)')
parser.add_argument('--observe-payload-exit', action='store_true',
help='Observe payload-exit counters before the cgroup observer exits')
parser.add_argument('command', nargs=argparse.REMAINDER)
options = parser.parse_args()
if not 1 <= options.early_stop_mib <= 3584:
parser.error('--early-stop-mib must leave at least 512 MiB below the 4 GiB hard cap')
early_stop_bytes = options.early_stop_mib * 1024 * 1024
if options.task_ceiling <= 0:
parser.error('--task-ceiling must be positive')
if options.observe_payload_exit and options.task_ceiling < 2:
@@ -100,7 +95,7 @@ def main():
]
command = [
'systemd-run', '--user', '--scope', '--unit=' + unit,
'-p', 'MemoryMax=4G', '-p', f'MemoryHigh={early_stop_bytes}', '-p', 'MemorySwapMax=0',
'-p', 'MemoryMax=4G', '-p', 'MemoryHigh=3G', '-p', 'MemorySwapMax=0',
'-p', 'CPUQuota=100%', '-p', 'TasksMax=' + str(options.task_ceiling),
'taskset', '-c', str(cpu), *payload,
]
@@ -163,7 +158,7 @@ def main():
except FileNotFoundError:
# A completed transient scope can disappear between reads.
pass
if peak > early_stop_bytes:
if peak > 3 * gib:
abort = 'scope_memory_early_stop'
elif available_bytes() < 4 * gib:
abort = 'host_available_memory_early_stop'
@@ -189,7 +184,7 @@ def main():
'resource_scope': unit, 'peak_cgroup_bytes_sampled': peak,
'elapsed_seconds': round(time.monotonic() - started, 3),
'abort': abort, 'hard_memory_bytes': 4 * gib,
'early_stop_bytes': early_stop_bytes, 'cpu_quota_percent': 100,
'early_stop_bytes': 3 * gib, 'cpu_quota_percent': 100,
'cpu_affinity': [cpu],
'task_ceiling': options.task_ceiling, 'peak_tasks_sampled': peak_tasks,
'resource_events_last_observed': events,
@@ -0,0 +1,635 @@
{
"runtime_revision": "f4322b15ed1423d736bd2572cf7a8eadf2b466e1",
"host": "Linux x86-64",
"node": "24.18.0",
"npm": "11.16.0",
"codex_cli": "0.161.0",
"requested_model": "gpt-6.1-sol",
"reasoning": "high",
"resolved_model_identity": "unknown",
"code_mode": false,
"client_enabled_tools": [
"import_evidence_bundle",
"get_evidence_bundle",
"inspect_analysis_view",
"list_unknowns"
],
"catalog": {
"tools": 207,
"serialized_bytes": 3152125,
"sha256": "4f31d9d56c400bc48f5639a9dc4b4cdad7faf862e4be81641d94fa70552438e4"
},
"bounds": {
"cpu_quota_percent": 100,
"family_hard_mib": 8192,
"early_stop_mib": 7168,
"swap": false,
"tasks": 192
},
"counter_scope": "Payload-exit counters with observer alive; kernel family peaks include file cache; terminal whole-scope counters and remote model compute unknown",
"sources": {
"native": {
"target_sha256": "2e6eef9a727f081f0d453b4e5e6cbd8b9ef8b6f86cbf7681cbad444d3b0b55c8",
"sections": 26,
"symbols": 1479,
"relocations": 2963,
"all_symbol_locations_names_values_agree_with_independent_ELF_parser": true
},
"javascript": {
"package": "npm",
"version": "11.16.0",
"source_files": [
{
"path": "package.json",
"sha256": "60ff022e32b5d8291d3e09849fd0cee6bbbff4e4d8352ad258214b1adf070714"
},
{
"path": "bin/npm-cli.js",
"sha256": "8e5f6f3429f8cdbe693cdc29904e9d5a7b127a494bd15c804bd54c7403bfcbe7"
},
{
"path": "lib/cli.js",
"sha256": "67666f06479f9b0bbc01412c198caadd4287d34d5ed74a02871ea78f186451e7"
},
{
"path": "lib/cli/entry.js",
"sha256": "667a44c1fa8795fdbba8ad843736ca7f8f24e64511985e9a7060b002123560c6"
},
{
"path": "lib/commands/install.js",
"sha256": "f7a60e8b40ab1bece76a2441b8b15378d199f05c6050eebe455cd9961f67b816"
}
],
"lib_cli_module": {
"node_id": "jag_node_131257ad52f3333971c2a5ed325c64357e52604489e42ccc67a8849770cb5b10",
"kind": "javascript-module",
"path": "lib/cli.js"
},
"source_bytes_checked": true,
"inventory_completeness": "producer-relative, not independently established",
"unselected_sources": 1416
}
},
"sdk": [
{
"name": "sdk-native-complete-1",
"status": "passed",
"answer_sha256": "4e28c2c2a25620576d27abe846a05835ec49386b889779e33410c31971523b54",
"query_ms": 1328.7,
"query_reply_bytes": 11224227,
"rpc_count": 7,
"elapsed_seconds": 14.117,
"cpu_seconds": 13.915,
"peak_family_mib": 1160.8,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": false,
"warm_page_ms": []
},
{
"name": "sdk-native-complete-2",
"status": "passed",
"answer_sha256": "4e28c2c2a25620576d27abe846a05835ec49386b889779e33410c31971523b54",
"query_ms": 1385.4,
"query_reply_bytes": 11224227,
"rpc_count": 7,
"elapsed_seconds": 14.722,
"cpu_seconds": 14.485,
"peak_family_mib": 1109.9,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": false,
"warm_page_ms": []
},
{
"name": "sdk-native-focused-1",
"status": "passed",
"answer_sha256": "4e28c2c2a25620576d27abe846a05835ec49386b889779e33410c31971523b54",
"query_ms": 529.7,
"query_reply_bytes": 167985,
"rpc_count": 25,
"elapsed_seconds": 12.907,
"cpu_seconds": 12.679,
"peak_family_mib": 934.8,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": false,
"warm_page_ms": [44.1, 59.6, 24.0, 30.8, 26.7, 47.4]
},
{
"name": "sdk-native-focused-2",
"status": "passed",
"answer_sha256": "4e28c2c2a25620576d27abe846a05835ec49386b889779e33410c31971523b54",
"query_ms": 572.2,
"query_reply_bytes": 167985,
"rpc_count": 25,
"elapsed_seconds": 13.316,
"cpu_seconds": 13.116,
"peak_family_mib": 1000.0,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": false,
"warm_page_ms": [44.0, 64.6, 26.8, 33.2, 29.8, 50.4]
},
{
"name": "sdk-javascript-complete-1",
"status": "passed",
"answer_sha256": "0fe3ad249eb1a7233a4966a56652c173667c48fdaf395b6c08fc6901ef3b46f7",
"query_ms": 11241.5,
"query_reply_bytes": 212856,
"rpc_count": 31,
"elapsed_seconds": 26.3,
"cpu_seconds": 26.1,
"peak_family_mib": 1333.5,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": true,
"warm_page_ms": [1124.6, 1073.8, 1474.7, 1074.7, 1081.6, 1109.5]
},
{
"name": "sdk-javascript-complete-2",
"status": "passed",
"answer_sha256": "0fe3ad249eb1a7233a4966a56652c173667c48fdaf395b6c08fc6901ef3b46f7",
"query_ms": 11938.1,
"query_reply_bytes": 212856,
"rpc_count": 31,
"elapsed_seconds": 27.105,
"cpu_seconds": 26.87,
"peak_family_mib": 1320.9,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": true,
"warm_page_ms": [1155.4, 1096.2, 1489.3, 1121.3, 1088.3, 1484.6]
},
{
"name": "sdk-javascript-focused-2",
"status": "passed",
"answer_sha256": "0fe3ad249eb1a7233a4966a56652c173667c48fdaf395b6c08fc6901ef3b46f7",
"query_ms": 10967.3,
"query_reply_bytes": 208350,
"rpc_count": 28,
"elapsed_seconds": 25.708,
"cpu_seconds": 25.505,
"peak_family_mib": 1344.0,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": false,
"warm_page_ms": [1342.7, 1085.1, 1055.0, 1034.6, 1082.7, 1440.7]
},
{
"name": "sdk-javascript-focused-3",
"status": "passed",
"answer_sha256": "0fe3ad249eb1a7233a4966a56652c173667c48fdaf395b6c08fc6901ef3b46f7",
"query_ms": 10990.4,
"query_reply_bytes": 208350,
"rpc_count": 28,
"elapsed_seconds": 26.197,
"cpu_seconds": 25.98,
"peak_family_mib": 1336.0,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": false,
"warm_page_ms": [1338.1, 1088.5, 1069.1, 1038.3, 1087.5, 1483.0]
},
{
"name": "sdk-mixed-native",
"status": "passed",
"answer_sha256": "4e28c2c2a25620576d27abe846a05835ec49386b889779e33410c31971523b54",
"query_ms": 560.0,
"query_reply_bytes": 167991,
"rpc_count": 25,
"elapsed_seconds": 16.933,
"cpu_seconds": 16.714,
"peak_family_mib": 1261.4,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": false,
"warm_page_ms": [46.9, 51.0, 36.3, 24.4, 38.6, 43.8]
},
{
"name": "sdk-mixed-javascript",
"status": "passed",
"answer_sha256": "0fe3ad249eb1a7233a4966a56652c173667c48fdaf395b6c08fc6901ef3b46f7",
"query_ms": 10904.5,
"query_reply_bytes": 208356,
"rpc_count": 28,
"elapsed_seconds": 26.5,
"cpu_seconds": 26.297,
"peak_family_mib": 1346.5,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
},
"payload_cleanup_verified": true,
"response_capacity_refused": false,
"warm_page_ms": [1321.9, 1063.3, 1070.8, 1309.9, 1041.7, 1074.2]
}
],
"model_trials": [
{
"name": "model-javascript-complete-1",
"facts_pass": true,
"elapsed_seconds": 76.49,
"cpu_seconds": 24.687,
"peak_family_mib": 818.7,
"input_tokens": 454491,
"cached_input_tokens": 396288,
"uncached_input_tokens": 58203,
"output_tokens": 2033,
"reported_reasoning_output_tokens": 207,
"mcp_calls_including_discovery": 9,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-javascript-complete-2",
"facts_pass": true,
"elapsed_seconds": 58.335,
"cpu_seconds": 14.993,
"peak_family_mib": 971.4,
"input_tokens": 328066,
"cached_input_tokens": 280704,
"uncached_input_tokens": 47362,
"output_tokens": 1676,
"reported_reasoning_output_tokens": 129,
"mcp_calls_including_discovery": 9,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-javascript-focused-1",
"facts_pass": false,
"elapsed_seconds": 34.206,
"cpu_seconds": 16.31,
"peak_family_mib": 811.9,
"input_tokens": 167470,
"cached_input_tokens": 136320,
"uncached_input_tokens": 31150,
"output_tokens": 633,
"reported_reasoning_output_tokens": 172,
"mcp_calls_including_discovery": 4,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-javascript-focused-2",
"facts_pass": true,
"elapsed_seconds": 66.455,
"cpu_seconds": 14.337,
"peak_family_mib": 955.3,
"input_tokens": 339528,
"cached_input_tokens": 307456,
"uncached_input_tokens": 32072,
"output_tokens": 2051,
"reported_reasoning_output_tokens": 169,
"mcp_calls_including_discovery": 10,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-javascript-guided-complete-1",
"facts_pass": true,
"elapsed_seconds": 69.206,
"cpu_seconds": 13.65,
"peak_family_mib": 888.8,
"input_tokens": 168862,
"cached_input_tokens": 121728,
"uncached_input_tokens": 47134,
"output_tokens": 2385,
"reported_reasoning_output_tokens": 737,
"mcp_calls_including_discovery": 6,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-javascript-guided-complete-2",
"facts_pass": false,
"elapsed_seconds": 29.187,
"cpu_seconds": 15.105,
"peak_family_mib": 697.4,
"input_tokens": 28696,
"cached_input_tokens": 23296,
"uncached_input_tokens": 5400,
"output_tokens": 610,
"reported_reasoning_output_tokens": 379,
"mcp_calls_including_discovery": 0,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-javascript-guided-focused-1",
"facts_pass": true,
"elapsed_seconds": 53.464,
"cpu_seconds": 12.059,
"peak_family_mib": 944.5,
"input_tokens": 124218,
"cached_input_tokens": 92416,
"uncached_input_tokens": 31802,
"output_tokens": 1746,
"reported_reasoning_output_tokens": 330,
"mcp_calls_including_discovery": 5,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-javascript-guided-focused-2",
"facts_pass": true,
"elapsed_seconds": 58.526,
"cpu_seconds": 22.852,
"peak_family_mib": 924.2,
"input_tokens": 129134,
"cached_input_tokens": 97536,
"uncached_input_tokens": 31598,
"output_tokens": 1478,
"reported_reasoning_output_tokens": 69,
"mcp_calls_including_discovery": 5,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-native-complete-1",
"facts_pass": true,
"elapsed_seconds": 52.103,
"cpu_seconds": 8.686,
"peak_family_mib": 1028.5,
"input_tokens": 287913,
"cached_input_tokens": 249984,
"uncached_input_tokens": 37929,
"output_tokens": 1724,
"reported_reasoning_output_tokens": 121,
"mcp_calls_including_discovery": 4,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-native-complete-2",
"facts_pass": true,
"elapsed_seconds": 58.261,
"cpu_seconds": 9.102,
"peak_family_mib": 837.4,
"input_tokens": 348976,
"cached_input_tokens": 286976,
"uncached_input_tokens": 62000,
"output_tokens": 2009,
"reported_reasoning_output_tokens": 246,
"mcp_calls_including_discovery": 5,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-native-focused-1",
"facts_pass": true,
"elapsed_seconds": 62.078,
"cpu_seconds": 10.198,
"peak_family_mib": 823.9,
"input_tokens": 335445,
"cached_input_tokens": 293120,
"uncached_input_tokens": 42325,
"output_tokens": 1924,
"reported_reasoning_output_tokens": 87,
"mcp_calls_including_discovery": 8,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
},
{
"name": "model-native-focused-2",
"facts_pass": true,
"elapsed_seconds": 57.933,
"cpu_seconds": 8.058,
"peak_family_mib": 821.3,
"input_tokens": 286938,
"cached_input_tokens": 256384,
"uncached_input_tokens": 30554,
"output_tokens": 1831,
"reported_reasoning_output_tokens": 106,
"mcp_calls_including_discovery": 8,
"payload_cleanup_verified": true,
"memory_events": {
"low": 0,
"high": 0,
"max": 0,
"oom": 0,
"oom_kill": 0,
"oom_group_kill": 0
}
}
],
"failed_trials": {
"model-javascript-focused-1": "Wrong connector discovery; approval-policy refusal; no source facts established.",
"model-javascript-guided-complete-2": "Premature agent refusal with no REA RPC; asserted tool unavailability not established by a connection/discovery observation."
},
"pilot_failures": [
"Private pilot oracle read view.item instead of view.items; corrected before the committed SDK cohorts. No product failure inferred."
],
"decision": "Existing query APIs suffice for these bounded questions; no general token/time advantage established. Separate imported immutable-format validation optimization is tracked in #4810.",
"review_followup_verification": {
"review-mixed-native": {
"status": "passed",
"checks": {
"heads_checked": 64,
"pages": 32,
"revised_unknown_id": "unk_057c8f2dbf30ec98851a66ee054366bc6e2e168874581e6f99cb80673d0ff9b8",
"revision_checked": 2,
"stale_update_rejected": true,
"tampered_import_rejected_atomically": true,
"unknowns_after_close": 0,
"old_reference_refused": true
},
"original_records_preserved": true,
"elapsed_seconds": 18.444,
"cpu_seconds": 18.16515,
"peak_family_mib": 1401.6328125,
"oom_events_at_payload_exit": 0,
"payload_cleanup_verified": true
},
"review-mixed-javascript": {
"status": "passed",
"checks": {
"heads_checked": 64,
"pages": 32,
"revised_unknown_id": "unk_057c8f2dbf30ec98851a66ee054366bc6e2e168874581e6f99cb80673d0ff9b8",
"revision_checked": 2,
"stale_update_rejected": true,
"tampered_import_rejected_atomically": true,
"unknowns_after_close": 0,
"old_reference_refused": true
},
"original_records_preserved": true,
"elapsed_seconds": 27.617,
"cpu_seconds": 27.275299,
"peak_family_mib": 1444.30859375,
"oom_events_at_payload_exit": 0,
"payload_cleanup_verified": true
},
"deterministic_receipt_tests": {
"passed": 4,
"scope": "Rejected SDK call, protocol error, receipt-write failure, simultaneous call/write failure; not real-provider evidence"
},
"cleanup_receipt_regressions": {
"passed": 6,
"scope": "Real stream/file refusals, independent peer close, and injected partial publication at the filesystem boundary. Original failure and call costs survive; failed cleanup retains workspace ownership. Harness failure checks, not real-provider evidence.",
"baseline_reproduction": {
"revision": "b025a919b36ec091ca888339df6b24e78e89b79b",
"method": "Execute the prior committed finalization block with deterministic workspace or log rejection; not a production-provider reproduction.",
"workspace_error": {
"file_receipt_attempts": 0,
"stdout_receipt_attempts": 0
},
"log_error": {
"file_receipt_attempts": 0,
"stdout_receipt_attempts": 0
}
},
"partial_retry_baseline": {
"revision": "5d6259e658ee54fc9829b9143a8721a2ab426e80",
"regression_exit_code": 1,
"observed_saved_report": "partial",
"method": "Run the unchanged partial-write regression against the prior committed finalizer with deterministic filesystem-boundary failure injection."
}
}
}
}
@@ -0,0 +1,201 @@
# Retained investigation query checkpoint
[#3134](https://github.com/morluto/rea/issues/3134) measured existing retained
queries on Linux. Selected reads preserved the requested facts, original
Evidence and Unknown revisions, including a mixed investigation. Existing
contracts suffice for these questions; this checkpoint adds no production API,
cache, persistence or default change.
Imported JavaScript pages repeatedly validated their entire source graph. That
separate, observed bottleneck is owned by
[#4810](https://github.com/morluto/rea/issues/4810). Smaller replies did not
establish a general model-token or whole-task latency improvement.
The [curated measurements](retained-investigation-results.json) retain individual
SDK/model costs and unsuccessful attempts. Raw bundles, transcripts, profiles
and detailed receipts stay private and are not build inputs.
## Sources and questions
Runtime: `f4322b15ed1423d736bd2572cf7a8eadf2b466e1`, Linux x86-64,
Node 24.18.0/npm 11.16.0. The SDK discovered all 207 advertised tools
(3,152,125 serialized catalog bytes). Model trials used Codex CLI 0.161.0,
requested `gpt-6.1-sol`/high, direct MCP, and the same four enabled tool names:
`import_evidence_bundle`, `get_evidence_bundle`, `inspect_analysis_view`, and
`list_unknowns`. The resolved service-side model identity is unknown. These are
selected-client-tool trials, not an evaluation of full-catalog agent discovery.
Two public source workflows produced authentic bundles through production MCP:
- Native: `inspect_binary_layout` on Debian's `libsqlite3.so.0.8.6`, SHA-256
`2e6eef9a727f081f0d453b4e5e6cbd8b9ef8b6f86cbf7681cbad444d3b0b55c8`.
Pwntools 4.15.0/pyelftools 0.33/Unicorn 2.1.2 observed 26 sections, 1,479
symbols and 2,963 relocations. An independent ELF64 decoder checked section
and relocation counts and every symbol's table/entry index, value, raw name
bytes and source entry range against the original file.
- JavaScript: shipped npm 11.16.0, directory inventory digest
`f8e576a7d162542c616168b25a95a5f62b9accf29467cc37e149905ad4b8e603`.
`analyze_javascript_application` selected exactly `package.json`,
`bin/npm-cli.js`, `lib/cli.js`, `lib/cli/entry.js`, and
`lib/commands/install.js`. It parsed four JavaScript files; 1,416 other
relevant files remained unselected. The complete retained result contained
2,822 application nodes, 1,796 semantic nodes and 13,682 semantic unknowns.
Source-file digests and the `lib/cli.js` source-module identity were checked
against shipped bytes. Inventory/discovery completeness remains producer-relative.
Analyst-recorded Unknowns came from the actual source limitations: five native
and seven JavaScript questions. These registry heads are distinct from the
13,682 semantic-graph unknowns. The exported histories contained 15 and 17
records, respectively, and approximately 1.75 and 21.06 MB of canonical JSON.
No synthetic payload arrays were used.
The SDK task read the first six original symbol/module rows and the relevant
current Unknown heads. Complete delivery and selected delivery answered the
same question; selected delivery intentionally exercised two-row pages. Each
fresh server performed three traversals, exported again and closed. The model
task additionally requested native identity/counts, or the five JavaScript source
choices and exact `lib/cli.js` source module, with explicit runtime uncertainty.
Compare arms within each declared task, not SDK costs against model costs.
## Correctness, capacity and lifetime
Both fresh-server SDK repetitions passed in both delivery arms. Selected rows,
ordering and counts agreed with original records; all original records and
Unknown revisions survived export/import, including links, omitted fields,
nulls and scalar types. Query calls did not rerun either producer. The resumed
servers had no native producer configuration.
The JavaScript complete bundle exceeded the default 10 MiB receive-buffer
boundary. Its typed capacity refusal preserved the complete retained data and a
usable connection. Complete-arm costs include that refusal and subsequent
selected-view recovery; they are not timings for a successful complete transfer.
A mixed history combined both authentic investigations and promoted 64 actual
semantic unknowns to separately identified analyst follow-ups. One follow-up
was updated to investigating. It contained 97 records, 76 heads and 77 revisions.
Both source queries preserved all original records/revisions. Thirty-two
two-head pages verified every semantic-follow-up head, including revision two.
A stale update and a tampered bundle import were rejected without changing the
ledger. Export reproduced the complete original mixed bundle. Closing cleared
records/Unknowns and made the old reference unavailable; no implicit persistence
or producer restart was introduced.
Public CLI `inspect-evidence-bundle` summary and inline `inspect-analysis-view`
summary also passed on both authentic sources. Portable CLI input still requires
complete input admission/validation; small output does not remove that cost.
## SDK costs
Each row spans two fresh MCP servers. Query time is the sum of SDK RPC elapsed
times over three traversals. Local post-call contract validation, oracle checks
and transcript writes are included only in the whole harness, along with startup,
full discovery, file reads, import, export and close. OS caches were uncontrolled/warm. A fresh imported
session is not a cold native-analysis measurement.
| Source / arm | Three traversals | Query reply bytes | Whole elapsed | Local family CPU | Family peak |
| ------------------------------ | ---------------: | ----------------: | --------------: | ---------------: | --------------: |
| Native complete | 1.329–1.385 s | 11,224,227 | 14.117–14.722 s | 13.915–14.485 s | 1,110–1,161 MiB |
| Native selected | 0.530–0.572 s | 167,985 | 12.907–13.316 s | 12.679–13.116 s | 935–1,000 MiB |
| JavaScript complete + recovery | 11.242–11.938 s | 212,856 | 26.300–27.105 s | 26.100–26.870 s | 1,321–1,334 MiB |
| JavaScript selected | 10.967–10.990 s | 208,350 | 25.708–26.197 s | 25.505–25.980 s | 1,336–1,344 MiB |
Mixed-history selected tasks took 16.933 s native and 26.500 s JavaScript,
including the larger import and complete round-trip checks. Their family peaks
were 1,261 and 1,347 MiB. This does not establish scaling to thousands of
registry heads or every provider.
Original-session npm warm pages measured 8–31 ms; after import, repeated pages
cost about 1.1–1.4 s. Source inspection shows that imported immutable Evidence
does not carry the format owner's private graph proofs, so each view repeats
full validation. Native layout views also parse the complete layout on each
page. #4810 owns equivalent before/after verification of a correction; this
checkpoint claims no speedup from an unimplemented cache.
## Actual model tasks
All twelve attempts retained their costs. Ten supplied every checked fact and
current Unknown identity/status; runtime and unselected-source coverage stayed
unknown. One initial JavaScript selected attempt searched the wrong connector
and received an approval-policy refusal. One guided complete attempt stopped
without an REA RPC and asserted tool unavailability without a supporting
connection/discovery observation. Both are failed tasks, despite CLI exit zero.
| Cohort / arm | Successful tasks | Total input tokens | Elapsed |
| ------------------------------------- | ---------------: | -----------------------: | -----------------------: |
| Native complete | 2/2 | 287,913 / 348,976 | 52.103 / 58.261 s |
| Native selected, two-head pages | 2/2 | 335,445 / 286,938 | 62.078 / 57.933 s |
| JavaScript complete + recovery | 2/2 | 454,491 / 328,066 | 76.490 / 58.335 s |
| JavaScript selected, two-head pages | 1/2 | 167,470 failed / 339,528 | 34.206 failed / 66.455 s |
| JavaScript guided complete + recovery | 1/2 | 168,862 / 28,696 failed | 69.206 / 29.187 failed s |
| JavaScript guided selected | 2/2 | 124,218 / 129,134 | 53.464 / 58.526 s |
The separate guided JavaScript cohort named the exact configured tools and
allowed one sufficiently large Unknown page for this bounded question. Both
arms received the same discovery guidance. Its single completed complete-arm
sample is insufficient for a stable repeated-pair benefit claim. Native total
input/time overlapped; extra pages and model turns can consume the reply saving.
Do not pool failed tasks as fast answers or attribute guidance changes to REA.
The JSON report records total/cached/uncached input, output, local CPU and peak
memory per attempt. These are client-reported usage counters, not tokenizer
estimates; output includes the client's reported reasoning accounting without
adding it again. Schema/discovery, errors, retries and continuations remain in
the task. Remote model compute, full-catalog model behavior and other hosts were
not measured.
Heavy runs were serial, one CPU, 8 GiB family hard limit, 7 GiB early stop,
no swap. Kernel peaks include charged file cache. Counter observations were
taken at payload exit while the owned observer remained alive; terminal
whole-scope counters remain unknown. Observed payload OOM/capacity events were
zero, all payloads exited and cleanup was verified. The expected MCP response
refusal is a separate transport-capacity outcome.
## Reproduce
Build the pinned runtime, acquire the matching real artifacts and produce the
two authentic histories with the public operations above. Export before close.
Keep bundles, transcripts and model profiles private. For a known source ID:
```sh
node experiments/analysis-efficiency/retained-investigation.mjs \
--runtime-root /absolute/built-rea \
--revision f4322b15ed1423d736bd2572cf7a8eadf2b466e1 \
--bundle /absolute/authentic-history.json \
--evidence-id ev_ORIGINAL_SHA256 \
--scenario native --delivery focused \
--output /absolute/new-receipt-directory
```
Run under the existing process-family resource wrapper, with sufficient bounds
for the selected source. Repeat with `--delivery complete`; use
`--scenario javascript` for module rows. The task's Unknown domain is
`retained-native` or `retained-javascript`. Output is never overwritten.
`agent-trial.py --mode direct` supports the same four enabled names; its success
exit only establishes client completion. Grade original IDs/digests, exact
facts, coverage and Unknowns from the retained transcript and final answer.
For a privately supplied authentic mixed bundle, add `--verify-mixed`. Besides
the normal source query and original-record round trip, this pages every current
head in `javascript-semantic-followup`, checks the current updated revision,
submits a deliberately stale update and a tampered copy of the bundle, verifies
atomic refusal, then checks Unknown/reference lifetime after close. The bundle
must contain genuine follow-ups and at least one updated head. The checkpoint's
64-head bundle passed this mode for both source scenarios. Its extra verification
costs are separate from the original SDK comparison rows above.
Rejected SDK calls are recorded before propagating the original failure, with
request, phase and elapsed time. Reply bytes stay null when no usable reply was
received. Receipt-write failures remain distinct; simultaneous call/write
failures retain both causes. Deterministic failure tests run with
`python3 -m unittest discover -s experiments/analysis-efficiency -p test_retained_queries.py`.
Finalization independently attempts client/transport close, log completion and
both receipt outputs. Cleanup failures preserve the original task failure and
call costs, record the failing phase and retain the workspace for retry. A file
receipt refusal still permits stdout; a broken stdout write is recorded in a
file retry. Files publish through a sibling temporary file and rename; an
interrupted retry preserves the previous receipt. Failed publication files stay
in the owned output directory. Cleanup or receipt-output failures make the
command fail. Six additional regressions exercise stream/file errors, partial
publication and peer cleanup; these are harness failure checks, not real-provider
evidence.
@@ -0,0 +1,310 @@
/** Measure public retained queries against an authentic, previously exported bundle. */
import assert from "node:assert/strict";
import { createHash } from "node:crypto";
import { createWriteStream } from "node:fs";
import {
appendFile,
mkdir,
mkdtemp,
readFile,
writeFile,
} from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, isAbsolute, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { parseArgs } from "node:util";
import { finished } from "node:stream/promises";
import canonicalize from "canonicalize";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import {
requireMcpOperationResult,
requireMcpToolError,
} from "../../scripts/lib/mcp-verifier-results.mjs";
import { createRetainedQueryCaller } from "./retained-query-calls.mjs";
import { finalizeRetainedQueryReceipt } from "./retained-query-finalization.mjs";
import {
verifyMixedRetainedHistory,
verifyMixedRetainedClosure,
retainedUnknownHeads,
} from "./retained-mixed-verification.mjs";
const { values } = parseArgs({
options: {
"runtime-root": {
type: "string",
default: resolve(dirname(fileURLToPath(import.meta.url)), "../.."),
},
revision: { type: "string" },
bundle: { type: "string" },
"evidence-id": { type: "string" },
scenario: { type: "string" },
delivery: { type: "string" },
output: { type: "string" },
"verify-mixed": { type: "boolean", default: false },
},
});
for (const key of ["runtime-root", "bundle", "output"])
assert.ok(values[key] && isAbsolute(values[key]), `${key} must be absolute`);
assert.ok(values.revision && values["evidence-id"]);
assert.ok(["native", "javascript"].includes(values.scenario));
assert.ok(["complete", "focused"].includes(values.delivery));
const root = values["runtime-root"];
const output = values.output;
await mkdir(output, { recursive: false, mode: 0o700 });
const digest = (bytes) => createHash("sha256").update(bytes).digest("hex");
const sourceBytes = await readFile(values.bundle);
const original = JSON.parse(sourceBytes);
const source = original.records.find(
(record) => record.evidence_id === values["evidence-id"],
);
const operation =
values.scenario === "native"
? "inspect_binary_layout"
: "analyze_javascript_application";
assert.equal(source?.operation, operation);
const unknownDomain = `retained-${values.scenario}`;
const expectedUnknowns = retainedUnknownHeads(original.unknowns, unknownDomain);
// These oracles check selected original facts, not producer discovery completeness.
const expectedRows =
values.scenario === "native"
? source.normalized_result.symbols
: source.normalized_result.graph.nodes
.filter((node) =>
["javascript-asset", "javascript-module", "source-module"].includes(
node.kind,
),
)
.map((node) => {
const candidates = node.observations.flatMap((observation) => {
const property = observation.properties.path;
const where = observation.evidence.location;
return [
...(typeof property === "string" ? [property] : []),
...(where.available && where.value.kind === "artifact-path"
? [where.value.path]
: where.available && where.value.kind === "source-range"
? [where.value.source]
: []),
];
});
return {
node_id: node.node_id,
kind: node.kind,
path:
node.identity.strategy === "canonical-path"
? node.identity.path
: node.identity.strategy === "source-map-original"
? node.identity.original_source
: (candidates[0] ?? null),
};
});
assert.ok(expectedRows.length >= 6, "This task needs six original rows");
const runtimeEntrySha256 = digest(
await readFile(join(root, "dist/mcp/main.js")),
);
const account = await mkdtemp(join(tmpdir(), "rea-retained-query-"));
const transport = new StdioClientTransport({
command: process.execPath,
args: [join(root, "scripts/rea.mjs"), "mcp"],
env: {
PATH: process.env.PATH,
HOME: account,
NODE_OPTIONS: "--max-old-space-size=2048",
REA_LOG_LEVEL: "silent",
},
stderr: "pipe",
});
const serverLog = createWriteStream(join(output, "server.log"));
const serverLogFinished = finished(serverLog);
serverLogFinished.catch(() => {});
transport.stderr?.pipe(serverLog);
const client = new Client({
name: "retained-investigation-measurement",
version: "1",
});
const report = {
revision: values.revision,
runtime_entry_sha256: runtimeEntrySha256,
bundle_sha256: digest(sourceBytes),
bundle_bytes: sourceBytes.length,
source_evidence_id: source.evidence_id,
scenario: values.scenario,
delivery: values.delivery,
verify_mixed: values["verify-mixed"],
calls: [],
status: "running",
};
const call = createRetainedQueryCaller(client, async (receipt, event) => {
report.calls.push(receipt);
await appendFile(
join(output, "transcript.jsonl"),
JSON.stringify(event) + "\n",
);
});
const result = (reply, name) => requireMcpOperationResult(reply, name);
try {
await client.connect(transport);
const started = performance.now();
const catalog = await client.listTools();
report.catalog = {
elapsed_ms: performance.now() - started,
tools: catalog.tools.length,
bytes: Buffer.byteLength(JSON.stringify(catalog)),
sha256: digest(JSON.stringify(catalog)),
};
assert.equal(catalog.nextCursor, undefined);
await writeFile(join(output, "catalog.json"), JSON.stringify(catalog));
result(
await call("import_evidence_bundle", { path: values.bundle }, "import"),
"import_evidence_bundle",
);
const answers = [];
for (let repeat = 0; repeat < 3; repeat += 1) {
let answer;
if (values.delivery === "complete") {
const reply = await call("get_evidence_bundle", {}, `complete-${repeat}`);
if (reply.isError !== true) {
const bundle = result(reply, "get_evidence_bundle");
assert.deepEqual(
bundle.records.find(
(record) => record.evidence_id === source.evidence_id,
),
source,
);
assert.deepEqual(bundle.unknowns, original.unknowns);
answer = [expectedRows.slice(0, 6), expectedUnknowns];
} else {
// Keep capacity refusals and every recovery RPC in the completed task.
const failure = requireMcpToolError(reply);
assert.equal(failure.code, "resource_constraint");
assert.equal(failure.details?.resource, "transport");
report.complete_delivery_refused = true;
}
}
if (answer === undefined) {
const metadata = result(
await call(
"get_evidence_bundle",
{
detail: "summary",
filters: { evidence_id: source.evidence_id },
},
`discovery-${repeat}`,
),
"get_evidence_bundle",
);
assert.equal(metadata.matching_records, 1);
assert.equal(metadata.records[0].evidence_id, source.evidence_id);
const rows = [];
for (const offset of [0, 2, 4]) {
const view = result(
await call(
"inspect_analysis_view",
{
source: {
kind: "retained-evidence",
evidence_id: source.evidence_id,
},
view: {
kind: "page",
collection:
values.scenario === "native" ? "symbols" : "modules",
offset,
limit: 2,
},
},
`page-${repeat}-${offset}`,
),
"inspect_analysis_view",
);
assert.equal(view.parent_evidence_id, source.evidence_id);
assert.equal(view.coverage.total, expectedRows.length);
assert.equal(view.coverage.examined, 2);
assert.equal(
view.coverage.next_offset,
offset + 2 < expectedRows.length ? offset + 2 : null,
);
assert.deepEqual(view.items, expectedRows.slice(offset, offset + 2));
rows.push(...view.items);
}
const unknowns = [];
let offset = 0;
do {
const page = result(
await call(
"list_unknowns",
{ domain: unknownDomain, offset, limit: 2 },
`unknowns-${repeat}-${offset}`,
),
"list_unknowns",
);
assert.equal(page.total, expectedUnknowns.length);
assert.equal(page.offset, offset);
assert.deepEqual(
page.items,
expectedUnknowns.slice(offset, offset + 2),
);
assert.equal(
page.next_offset,
offset + 2 < expectedUnknowns.length ? offset + 2 : null,
);
unknowns.push(...page.items);
offset = page.next_offset;
} while (offset !== null);
assert.deepEqual(unknowns, expectedUnknowns);
answer = [rows, unknowns];
}
answers.push(digest(canonicalize(answer)));
}
assert.equal(new Set(answers).size, 1);
report.answer_sha256 = answers[0];
if (values["verify-mixed"])
report.mixed_verification = await verifyMixedRetainedHistory({
call,
original,
sourceId: source.evidence_id,
output,
});
const roundtrip = join(output, "roundtrip.json");
result(
await call("export_evidence_bundle", { path: roundtrip }, "export"),
"export_evidence_bundle",
);
const exported = JSON.parse(await readFile(roundtrip, "utf8"));
const exportedRecords = new Map(
exported.records.map((record) => [record.evidence_id, record]),
);
for (const record of original.records)
assert.deepEqual(exportedRecords.get(record.evidence_id), record);
assert.deepEqual(exported.unknowns, original.unknowns);
report.original_records_preserved = true;
result(await call("close_binary", {}, "close"), "close_binary");
const closed = result(
await call("get_evidence_bundle", { detail: "summary" }, "after-close"),
"get_evidence_bundle",
);
assert.equal(closed.total_retained_records, 0);
report.close_cleared_records = true;
if (values["verify-mixed"])
Object.assign(
report.mixed_verification,
await verifyMixedRetainedClosure(call, source.evidence_id),
);
assert.equal(digest(await readFile(values.bundle)), report.bundle_sha256);
report.status = "passed";
} catch (cause) {
report.status = "failed";
report.failure = { name: cause.name, message: cause.message };
} finally {
const finalized = await finalizeRetainedQueryReceipt({
report,
client,
transport,
account,
serverLog,
serverLogFinished,
output,
});
if (report.status !== "passed" || !finalized) process.exitCode = 1;
}
@@ -0,0 +1,163 @@
import assert from "node:assert/strict";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import {
requireMcpOperationResult as result,
requireMcpToolError,
} from "../../scripts/lib/mcp-verifier-results.mjs";
/** Expected current heads from the original exported revisions, not displayed pages. */
export const retainedUnknownHeads = (unknowns, domain) => {
const heads = new Map();
for (const unknown of unknowns) {
const previous = heads.get(unknown.unknown_id);
if (previous === undefined || previous.revision < unknown.revision)
heads.set(unknown.unknown_id, unknown);
}
return [...heads.values()]
.filter((unknown) => unknown.domain === domain)
.sort((a, b) =>
a.unknown_id < b.unknown_id ? -1 : a.unknown_id > b.unknown_id ? 1 : 0,
);
};
const verifyFollowupPages = async (call, original) => {
const expected = retainedUnknownHeads(
original.unknowns,
"javascript-semantic-followup",
);
assert.ok(
expected.length > 0,
"Supply an authentic mixed history with semantic follow-ups",
);
const revised = expected.find((unknown) => unknown.revision > 1);
assert.ok(revised, "Mixed verification requires a retained updated Unknown");
let offset = 0;
let pages = 0;
const observed = [];
do {
const page = result(
await call(
"list_unknowns",
{
domain: "javascript-semantic-followup",
offset,
limit: 2,
},
`mixed-heads-${offset}`,
),
"list_unknowns",
);
assert.equal(page.total, expected.length);
assert.equal(page.offset, offset);
assert.deepEqual(page.items, expected.slice(offset, offset + 2));
assert.equal(
page.next_offset,
offset + 2 < expected.length ? offset + 2 : null,
);
observed.push(...page.items);
offset = page.next_offset;
pages += 1;
} while (offset !== null);
assert.deepEqual(observed, expected);
return { revised, headsChecked: expected.length, pages };
};
const verifyMutationRefusals = async ({
call,
original,
sourceId,
output,
revised,
}) => {
const before = result(
await call(
"get_evidence_bundle",
{ detail: "summary" },
"mixed-before-refusals",
),
"get_evidence_bundle",
);
const stale = await call(
"update_unknown",
{
unknown_id: revised.unknown_id,
expected_revision: revised.revision - 1,
status: revised.status,
severity: revised.severity,
supporting_evidence_ids: revised.supporting_evidence_ids,
contradicting_evidence_ids: revised.contradicting_evidence_ids,
required_authority: revised.required_authority,
required_confidence: revised.required_confidence,
required_environment: revised.required_environment,
recommended_probes: revised.recommended_probes,
relationships: revised.relationships,
resolution: revised.resolution,
},
"mixed-stale-update",
);
assert.equal(requireMcpToolError(stale).code, "revision_conflict");
const tampered = structuredClone(original);
const target = tampered.records.find(
(record) => record.evidence_id === sourceId,
);
assert.ok(target);
target.normalized_result = { checkpoint_tampered: true };
const path = join(output, "tampered-import.json");
await writeFile(path, JSON.stringify(tampered), { flag: "wx" });
const rejected = await call(
"import_evidence_bundle",
{ path },
"mixed-tampered-import",
);
assert.equal(
requireMcpToolError(rejected).code,
"evidence_integrity_mismatch",
);
const after = result(
await call(
"get_evidence_bundle",
{ detail: "summary" },
"mixed-after-refusals",
),
"get_evidence_bundle",
);
assert.deepEqual(after, before);
};
/** Verify original mixed-history heads, CAS rejection and atomic import failure. */
export const verifyMixedRetainedHistory = async (options) => {
const { revised, headsChecked, pages } = await verifyFollowupPages(
options.call,
options.original,
);
await verifyMutationRefusals({ ...options, revised });
return {
heads_checked: headsChecked,
pages,
revised_unknown_id: revised.unknown_id,
revision_checked: revised.revision,
stale_update_rejected: true,
tampered_import_rejected_atomically: true,
};
};
/** Closing must neither retain old Unknowns nor rehydrate a closed source. */
export const verifyMixedRetainedClosure = async (call, sourceId) => {
const unknowns = result(
await call("list_unknowns", {}, "mixed-after-close-heads"),
"list_unknowns",
);
assert.equal(unknowns.total, 0);
const missing = await call(
"inspect_analysis_view",
{
source: { kind: "retained-evidence", evidence_id: sourceId },
view: { kind: "summary" },
},
"mixed-after-close-reference",
);
const failure = requireMcpToolError(missing);
assert.equal(failure.details?.reason, "missing");
return { unknowns_after_close: 0, old_reference_refused: true };
};
@@ -0,0 +1,46 @@
/** Keep settled and rejected RPCs in the same receipt before returning control. */
export const createRetainedQueryCaller =
(client, record) => async (name, input, phase) => {
const start = performance.now();
let reply;
try {
reply = await client.callTool(
{ name, arguments: input },
{ timeout: 300000 },
);
} catch (cause) {
const failure =
cause instanceof Error
? { name: cause.name, message: cause.message }
: { name: typeof cause, message: String(cause) };
const receipt = {
name,
input,
phase,
elapsed_ms: performance.now() - start,
reply_bytes: null,
is_error: true,
failure,
};
try {
await record(receipt, { name, input, phase, failure });
} catch (recordingFailure) {
throw new AggregateError(
[cause, recordingFailure],
"MCP call and receipt recording both failed",
);
}
throw cause;
}
const receipt = {
name,
input,
phase,
elapsed_ms: performance.now() - start,
reply_bytes: Buffer.byteLength(JSON.stringify(reply)),
is_error: reply.isError === true,
};
// A receipt-write failure is distinct from a rejected MCP call.
await record(receipt, { name, input, phase, reply });
return reply;
};
@@ -0,0 +1,81 @@
import { rename, rm, writeFile } from "node:fs/promises";
import { join } from "node:path";
const attempt = async (failures, phase, action) => {
try {
await action();
return true;
} catch (cause) {
failures.push(`${phase}: ${String(cause)}`);
return false;
}
};
const writeReceipt = (stream, text) =>
new Promise((resolve, reject) => {
const onError = (cause) => reject(cause);
stream.once("error", onError);
try {
stream.write(text, (cause) => {
if (cause !== null && cause !== undefined) {
// A Writable emits its error after notifying the write callback.
reject(cause);
} else {
stream.off("error", onError);
resolve();
}
});
} catch (cause) {
stream.off("error", onError);
reject(cause);
}
});
/** Preserve task costs through independent cleanup and receipt-output failures. */
export const finalizeRetainedQueryReceipt = async ({
report,
client,
transport,
account,
serverLog,
serverLogFinished,
output,
stdout = process.stdout,
}) => {
report.cleanup_failures = [];
await Promise.all([
attempt(report.cleanup_failures, "client", () => client.close()),
attempt(report.cleanup_failures, "transport", () => transport.close()),
]);
await attempt(report.cleanup_failures, "server-log", async () => {
if (!serverLog.writableEnded) serverLog.end();
await serverLogFinished;
});
if (report.cleanup_failures.length === 0)
await attempt(report.cleanup_failures, "workspace", () =>
rm(account, { recursive: true }),
);
if (report.cleanup_failures.length > 0) report.retained_workspace = account;
report.receipt_failures = [];
let publication = 0;
const saveReport = async () => {
// Keep failed publications in the owned output directory for inspection.
// A partial retry must never truncate an already published cost receipt.
const pending = join(output, `.report-${++publication}.json.pending`);
await writeFile(pending, JSON.stringify(report, null, 2) + "\n", {
flag: "wx",
});
await rename(pending, join(output, "report.json"));
};
await attempt(report.receipt_failures, "report-file", saveReport);
const stdoutWritten = await attempt(report.receipt_failures, "stdout", () =>
writeReceipt(stdout, JSON.stringify(report) + "\n"),
);
// Preserve a broken stdout diagnostic in the file that may already exist.
if (!stdoutWritten)
await attempt(report.receipt_failures, "report-file-retry", saveReport);
return (
report.cleanup_failures.length === 0 && report.receipt_failures.length === 0
);
};
@@ -1,88 +0,0 @@
// Generate a complete declared-native baseline; do not infer tools from ordering.
import assert from "node:assert/strict";
import { readFile, writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import { KUNA_OPERATIONS } from "../../dist/kuna/KunaProviderCapabilities.js";
import {
createVerifierRun,
completeVerifierRun,
assertVerifierCleanupComplete,
} from "../../scripts/lib/verifier-run.mjs";
const [output] = process.argv.slice(2);
assert.ok(output, "Usage: node select-kuna-tools.mjs NEW_OUTPUT_JSON");
assert.equal(process.versions.node, (await readFile(".nvmrc", "utf8")).trim());
const desired = new Set([
...KUNA_OPERATIONS,
"open_binary",
"close_binary",
"inspect_analysis_view",
]);
const run = createVerifierRun(),
failures = [];
const client = new Client({
name: "rea-kuna-baseline-catalog",
version: "0.1.0",
});
const transport = new StdioClientTransport({
command: process.execPath,
args: [resolve("scripts/rea.mjs"), "mcp"],
env: {
...process.env,
// This pass needs tool identities, not large result schemas. Keep any
// explicit caller profile; the measured runner already selects off.
REA_MCP_OUTPUT_SCHEMA_PROFILE:
process.env.REA_MCP_OUTPUT_SCHEMA_PROFILE ?? "off",
},
stderr: "pipe",
});
let names;
try {
await client.connect(transport);
names = [];
const cursors = new Set();
let cursor;
do {
assert.ok(!cursors.has(cursor), "Catalog pagination did not advance");
cursors.add(cursor);
const page = await client.listTools(cursor === undefined ? {} : { cursor });
names.push(
...page.tools
.filter((tool) => desired.has(tool.name))
.map((tool) => tool.name),
);
cursor = page.nextCursor;
} while (cursor !== undefined);
assert.equal(
new Set(names).size,
names.length,
"Ambiguous duplicate catalog names",
);
assert.deepEqual(
[...desired].filter((name) => !names.includes(name)),
[],
"Declared native operation lacks a named MCP tool",
);
} catch (error) {
failures.push(error.stack ?? String(error));
} finally {
await client.close();
await transport.close();
}
const lifecycle = await completeVerifierRun(run);
assertVerifierCleanupComplete(lifecycle.process_lineage);
assert.deepEqual(failures, []);
// Caller-selected artifact only; never replace an existing configuration/record.
await writeFile(output, JSON.stringify(names, null, 2) + "\n", { flag: "wx" });
console.log(
JSON.stringify({
provider: "kuna",
selection: "complete declared native operations plus session/views",
names,
lifecycle,
scope:
"Actual registered catalog matched by name to the compiled provider capability owner. No target opened; declared coverage does not prove live provider availability.",
}),
);
@@ -1,46 +0,0 @@
import hashlib
import importlib.util
from pathlib import Path
import tempfile
import unittest
spec = importlib.util.spec_from_file_location('agent_trial', Path(__file__).with_name('agent-trial.py'))
trial = importlib.util.module_from_spec(spec)
spec.loader.exec_module(trial)
class ExperimentalEnginePinTests(unittest.TestCase):
def test_missing_pin_preserves_other_provider_trials(self):
self.assertIsNone(trial.pinned_experimental_engine({}))
self.assertIsNone(trial.experimental_engine_unchanged(None))
def test_feature_build_replacement_and_removal_invalidate_pinned_engine(self):
with tempfile.TemporaryDirectory() as directory:
engine = Path(directory) / 'kuna'
engine.write_bytes(b'embedded-spec-build')
engine.chmod(0o755)
settings = {'REA_KUNA_COMMAND': str(engine),
'REA_ATOMIC_NATIVE_IR_ENGINE_SHA256': hashlib.sha256(engine.read_bytes()).hexdigest()}
receipt = trial.pinned_experimental_engine(settings)
self.assertTrue(trial.experimental_engine_unchanged(receipt))
engine.write_bytes(b'non-embedded-test-build')
with self.assertRaisesRegex(ValueError, 'differs from its pin'):
trial.pinned_experimental_engine(settings)
self.assertFalse(trial.experimental_engine_unchanged(receipt))
engine.unlink()
self.assertFalse(trial.experimental_engine_unchanged(receipt))
with self.assertRaisesRegex(ValueError, 'absolute executable'):
trial.pinned_experimental_engine(settings)
def test_malformed_pin_and_relative_command_are_rejected(self):
for settings in [
{'REA_ATOMIC_NATIVE_IR_ENGINE_SHA256': 'bad'},
{'REA_ATOMIC_NATIVE_IR_ENGINE_SHA256': '0' * 64, 'REA_KUNA_COMMAND': './kuna'},
]:
with self.assertRaises(ValueError):
trial.pinned_experimental_engine(settings)
if __name__ == '__main__':
unittest.main()
@@ -29,16 +29,13 @@ class PayloadObservationTests(unittest.TestCase):
spec = importlib.util.spec_from_file_location('resource_run', Path(__file__).with_name('resource-run.py'))
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
for flags in [['--observe-payload-exit', '--task-ceiling', '1'],
['--early-stop-mib', '0'], ['--early-stop-mib', '3585']]:
with self.subTest(flags=flags), \
patch.object(sys, 'argv', ['resource-run.py', *flags, '--', 'payload']), \
patch.object(sys, 'stderr', io.StringIO()), \
patch.object(module.subprocess, 'Popen') as spawn:
with self.assertRaises(SystemExit) as failure:
module.main()
self.assertEqual(failure.exception.code, 2)
spawn.assert_not_called()
arguments = ['resource-run.py', '--observe-payload-exit', '--task-ceiling', '1', '--', 'payload']
with patch.object(sys, 'argv', arguments), patch.object(sys, 'stderr', io.StringIO()), \
patch.object(module.subprocess, 'Popen') as spawn:
with self.assertRaises(SystemExit) as failure:
module.main()
self.assertEqual(failure.exception.code, 2)
spawn.assert_not_called()
def test_preserves_nonzero_status_kernel_peak_and_nonzero_events(self):
with tempfile.TemporaryDirectory() as directory:
@@ -0,0 +1,166 @@
"""Deterministic RPC receipt failures; not real-provider or model evidence."""
import json
from pathlib import Path
import subprocess
import unittest
class RetainedQueryReceipts(unittest.TestCase):
def run_node(self, body):
module = Path(__file__).with_name('retained-query-calls.mjs').resolve().as_uri()
finalizer = Path(__file__).with_name('retained-query-finalization.mjs').resolve().as_uri()
source = ('import assert from "node:assert/strict";\n'
'const {createRetainedQueryCaller} = await import(' + json.dumps(module) + ');\n'
'const {finalizeRetainedQueryReceipt} = await import(' + json.dumps(finalizer) + ');\n' + body)
result = subprocess.run(['node', '--input-type=module', '-'], input=source,
text=True, capture_output=True, timeout=15)
self.assertEqual(result.returncode, 0, result.stderr)
def run_finalization(self, body):
self.run_node('''
import {mkdtemp,mkdir,readFile,writeFile,rm,stat} from 'node:fs/promises';
import {join} from 'node:path';
import {tmpdir} from 'node:os';
import {Writable} from 'node:stream';
import {finished} from 'node:stream/promises';
const root=await mkdtemp(join(tmpdir(),'rea-receipt-test-'));
const account=join(root,'account');const output=join(root,'output');
await mkdir(account);await mkdir(output);
const chunks=[];
const stdout=new Writable({write(chunk,encoding,done){chunks.push(chunk.toString());done();}});
const serverLog=new Writable({write(chunk,encoding,done){done();}});
const serverLogFinished=finished(serverLog);serverLogFinished.catch(()=>{});
const originalFailure={name:'Error',message:'original request failed'};
const report={status:'failed',failure:originalFailure,calls:[{phase:'page',elapsed_ms:17}]};
const input={report,client:{close:async()=>{}},transport:{close:async()=>{}},
account,output,stdout,serverLog,serverLogFinished};
const saved=async()=>JSON.parse(await readFile(join(output,'report.json'),'utf8'));
try {
''' + body + '''
} finally {
serverLog.destroy();await serverLogFinished.catch(()=>{});stdout.destroy();
await rm(root,{recursive:true,force:true});
}
''')
def test_rejected_call_preserves_request_phase_cost_and_original_failure(self):
self.run_node('''
const failure = new Error('owned server closed');
const input = {offset:0, limit:2}; const rows=[]; const events=[];
const call = createRetainedQueryCaller({callTool:async request=>{
assert.strictEqual(request.arguments,input);throw failure;
}}, async(row,event)=>{rows.push(row);events.push(event);});
await assert.rejects(call('list_unknowns',input,'resume-2'), e=>e===failure);
assert.equal(rows.length,1);assert.equal(events.length,1);
assert.strictEqual(rows[0].input,input);assert.equal(rows[0].name,'list_unknowns');
assert.equal(rows[0].phase,'resume-2');assert.ok(rows[0].elapsed_ms>=0);
assert.equal(rows[0].reply_bytes,null);assert.equal(rows[0].is_error,true);
assert.deepEqual(events[0].failure,{name:'Error',message:'owned server closed'});
''')
def test_protocol_error_is_a_received_reply_with_known_bytes(self):
self.run_node('''
const reply={isError:true,content:[{type:'text',text:'capacity refusal'}]};const rows=[];
const call=createRetainedQueryCaller({callTool:async()=>reply},async row=>rows.push(row));
assert.strictEqual(await call('get_evidence_bundle',{},'complete'),reply);
assert.equal(rows.length,1);assert.equal(rows[0].is_error,true);
assert.equal(rows[0].reply_bytes,Buffer.byteLength(JSON.stringify(reply)));
assert.equal(Object.hasOwn(rows[0],'failure'),false);
''')
def test_receipt_write_error_does_not_reclassify_a_completed_rpc(self):
self.run_node('''
const failure=new Error('receipt disk unavailable');const rows=[];
const call=createRetainedQueryCaller({callTool:async()=>({content:[]})},async row=>{
rows.push(row);throw failure;
});
await assert.rejects(call('list_unknowns',{},'read'),e=>e===failure);
assert.equal(rows.length,1);assert.equal(rows[0].is_error,false);
assert.equal(Object.hasOwn(rows[0],'failure'),false);
''')
def test_failed_recording_preserves_the_prior_rpc_failure(self):
self.run_node('''
const rpc=new Error('request timeout');const disk=new Error('receipt close failed');
const call=createRetainedQueryCaller({callTool:async()=>{throw rpc;}},async()=>{throw disk;});
await assert.rejects(call('inspect_analysis_view',{},'selected'),e=>
e instanceof AggregateError && e.errors[0]===rpc && e.errors[1]===disk);
''')
def test_log_stream_failure_keeps_costs_both_receipts_and_workspace(self):
self.run_finalization('''
const log=new Writable({write(chunk,encoding,done){done(new Error('log disk failed'));}});
const logFinished=finished(log);logFinished.catch(()=>{});log.write('diagnostic');
assert.equal(await finalizeRetainedQueryReceipt({...input,serverLog:log,
serverLogFinished:logFinished}),false);
assert.match(report.cleanup_failures[0],/server-log:.*log disk failed/);
assert.strictEqual(report.failure,originalFailure);
assert.equal(report.calls[0].elapsed_ms,17);assert.equal(report.retained_workspace,account);
assert.equal((await stat(account)).isDirectory(),true);
assert.deepEqual(await saved(),report);assert.deepEqual(JSON.parse(chunks.join('')),report);
''')
def test_workspace_removal_error_still_writes_the_original_failure(self):
self.run_finalization('''
const blocked=join(root,'owned-file');await writeFile(blocked,'owned');
const malformedAccount=join(blocked,'child');
assert.equal(await finalizeRetainedQueryReceipt({...input,account:malformedAccount}),false);
assert.match(report.cleanup_failures[0],/^workspace:/);
assert.equal(report.retained_workspace,malformedAccount);
assert.deepEqual((await saved()).failure,originalFailure);
assert.deepEqual(JSON.parse(chunks.join('')),report);
''')
def test_report_file_refusal_preserves_the_stdout_receipt(self):
self.run_finalization('''
await mkdir(join(output,'report.json'));
assert.equal(await finalizeRetainedQueryReceipt(input),false);
assert.deepEqual(report.cleanup_failures,[]);
assert.match(report.receipt_failures[0],/^report-file:/);
assert.deepEqual(JSON.parse(chunks.join('')),report);
assert.deepEqual(report.failure,originalFailure);
''')
def test_stdout_write_error_is_handled_and_saved_in_the_file(self):
self.run_finalization('''
const failedStdout=new Writable({write(chunk,encoding,done){done(new Error('broken pipe'));}});
assert.equal(await finalizeRetainedQueryReceipt({...input,stdout:failedStdout}),false);
assert.match(report.receipt_failures[0],/stdout:.*broken pipe/);
assert.deepEqual(await saved(),report);assert.deepEqual(report.failure,originalFailure);
''')
def test_partial_retry_after_stdout_failure_preserves_the_prior_receipt(self):
self.run_finalization('''
const fs=await import('node:fs/promises');
const {syncBuiltinESMExports}=await import('node:module');
const originalWrite=fs.default.writeFile;let writes=0;let before;
fs.default.writeFile=async(...args)=>{
if(++writes===2){await originalWrite(args[0],'partial',args[2]);throw new Error('disk quota');}
return originalWrite(...args);
};
syncBuiltinESMExports();
try {
const failedStdout=new Writable({async write(chunk,encoding,done){
before=await readFile(join(output,'report.json'),'utf8');done(new Error('broken pipe'));
}});
assert.equal(await finalizeRetainedQueryReceipt({...input,stdout:failedStdout}),false);
assert.equal(writes,2);assert.equal(report.receipt_failures.length,2);
assert.match(report.receipt_failures[1],/report-file-retry:.*disk quota/);
assert.equal(await readFile(join(output,'report.json'),'utf8'),before);
assert.deepEqual((await saved()).failure,originalFailure);
assert.equal((await saved()).calls[0].elapsed_ms,17);
} finally {fs.default.writeFile=originalWrite;syncBuiltinESMExports();}
''')
def test_failed_client_close_keeps_ownership_and_attempts_peer_cleanup(self):
self.run_finalization('''
const closed=[];
assert.equal(await finalizeRetainedQueryReceipt({...input,
client:{close(){closed.push('client');throw new Error('close failed');}},
transport:{close:async()=>{closed.push('transport');}}}),false);
assert.deepEqual(closed,['client','transport']);
assert.match(report.cleanup_failures[0],/client:.*close failed/);
assert.equal(report.retained_workspace,account);assert.equal(serverLog.writableEnded,true);
assert.equal((await stat(account)).isDirectory(),true);
assert.deepEqual(await saved(),report);assert.deepEqual(JSON.parse(chunks.join('')),report);
''')
-451
View File
@@ -1,451 +0,0 @@
# Atomic RE through Code Mode
This is an **in-progress experiment**, not an integrated provider release. Branch
`experiment/atomic-codemode-20261016` starts at main
`42fc6c53ae188978deb3bedfe88287b6b316ba22` and carries the previous atomic-facts
prototype. Historical measurements in `../atomic-re-tools/` retain their original
baselines. No PR or merge is intended.
The branch was subsequently [refreshed from main `60bf10245`](main-refresh-study.md).
Shared installation/file cleanup and string parsing now follow that main's
owners. Historical model measurements retain their original frozen runtimes;
the refresh has separate real-provider verification and resource receipts.
The goal is a real model completing reverse-engineering questions through
composable facts, with Code Mode as the calling adapter. A configured feature flag,
a scripted verifier or a small response does not prove that goal.
The [capability map](capability-map.md) distinguishes verified task coverage,
experimental exporter requirements and remaining unknowns before interpreting
adapter comparisons.
The [string-span study](string-span-study.md) adds paged incoming occurrence
queries for encoded object spans and independently verifies pooled suffix
references on real SQLite. The same native sparse range index serves Kuna's
existing string aggregates. Equivalent cold occurrence retrieval falls from
48.1 to 1.8 seconds; this is shared analysis reuse, not a Code Mode result.
The subsequent frozen real-model runs all answer the selected task correctly:
traditional takes 315.6 seconds, Direct 102.3 and Code Mode 93.6. Code Mode uses
less cumulative input but more uncached input and peak memory than Direct.
Traditional's full inventory is truncated by the client; one original cited
payload remains only partially auditable. The study preserves that limitation.
The [string-fact precision study](string-facts-study.md) preserves native NUL
termination as true/false/unknown through the shared domain and public output
contract. Real canonical MCP, SDK, Direct, Code Mode and CLI checks retain both
NUL-terminated strings and a nonterminated printable run without length-based
agent inference. The old coarse descriptor remains compatible.
Both fresh real models complete the same frozen task after this repair: Direct
takes 95.2 seconds, Code Mode 90.9. Code Mode lowers cumulative input and peak
memory but increases uncached input and CPU. The results do not isolate the
metadata change's performance effect; all source and usage checks are recorded.
The [large-result study](large-result-study.md) verifies that paging alone does
not bound a large field. String metadata can now be selected without text, while
SDK full reads remain available. Shared pre-allocation JSON checks preserve
context and Evidence on transport refusal, including in-program Code Mode
recovery. The synthetic fixture tests capacity; it does not establish real-app
analysis quality. Real SQLite/SSH regressions are reported separately.
The subsequent real Code Mode model passes the frozen capacity task. Direct
retrieves correct data but labels two 17-byte prefixes as 16, failing the exact
reporting criterion. Both use metadata selection without sending full blobs.
Code Mode uses less input but more wall time; the differing correctness and byte
window choices prevent a matched-quality efficiency ranking. All runs remain.
The [streamed inventory study](streamed-inventory-study.md) then restores real
FFmpeg queries whose complete native source exceeds 8 MiB, using the production
streaming parser and bounded retained files. Real SDK/MCP lanes pass; LLVM and
Node still exceed the existing 64 MiB budget. Those failures remain explicit.
Both real models now complete the FFmpeg task with all cited raw captures
verified. Code Mode uses less cumulative input but more uncached input and time.
The study also retains two evaluator namespace failures and their full costs;
the corrected pair uses actual registered tool discovery.
The [refusal-cache study](capacity-refusal-study.md) then avoids repeated native
work for proven immutable source-budget failures. Real SDK and both MCP adapters
verify reuse and readable partial Evidence; cancellation/cleanup uncertainty
remain uncached. The first Code Mode precondition failure and its cost remain in
the record. Larger-target inventory coverage is still unresolved.
The later [native query study](native-string-query-study.md) makes selected LLVM
and Node string queries answerable without retaining a whole oversized inventory.
Both frozen LLVM model answers pass; Code Mode uses fewer input tokens in that
pair, with only a modest wall-time difference. The [shared byte checkpoint](byte-batch-study.md)
then batches missing byte windows through one native program while retaining
per-window facts and Evidence. A same-engine SDK toggle reduces ten-window cold
retrieval from about 94.3 to 8.5 seconds. Real provider preflight passes; new model
trials for this byte change were not run because the user cleared the goal.
The [AArch64 reference study](aarch64-xref-study.md) finds and fixes missing
ADRP-based string and memory references before the next model comparison.
Real SDK and traditional MCP preflights now agree with independent machine
evidence; the shared bounded producer preserves space/width and uncertainty.
All three real models now complete the behavior-level task. Code Mode takes
151.3 seconds / 388,365 cumulative input tokens, Direct 164.9 / 515,929 and
traditional 345.7 / 681,613. Code has more uncached input than traditional and
more memory than Direct. These are the earlier pinned measurements.
The [return-coverage study](aarch64-return-study.md) subsequently fixes two
independent producer defects: BTI import-entry identity and false no-return
promotion that erased the post-warning path. All three fresh model answers pass
the same selected task. Direct uses 351,157 cumulative input tokens / 139.0
seconds, Code Mode 371,571 / 166.8, and traditional 662,683 / 263.1. Code Mode
reduces MCP requests but adds model responses in this sample; correct primitives
and fewer RPCs do not establish a stable adapter advantage.
The [architecture storage study](storage-study.md) adds exact native register-name
and address-space queries, sharing one bounded immutable capture per lease.
It separates coordinates, widths and native map misses from hardware absence,
SSA equality or alias claims. Both real SSH models complete the extended task;
Code Mode uses 307,888 versus 415,450 cumulative input tokens and 142.2 versus
158.1 seconds, but more local CPU. This single pair does not establish a stable
advantage; the full typecheck gate remains resource-limited.
The [function-boundary study](function-boundary-study.md) adds independent native
prototype entries and return descriptors, separated from raw input varnodes.
Both real SSH models correctly distinguish these inventories and compose the
selected caller/parameter/helper transfer. Direct uses 331,674 cumulative input
tokens / 118.4 seconds; Code Mode uses 359,789 / 125.7, with lower uncached input
but mixed overall costs. Native and real-provider checks are recorded there.
The [path-query study](path-query-study.md) adds a shared, bounded recovered-CFG
witness query with exclusions and paging. Both actual MCP adapters verify the
same four real SQLite witnesses without requiring the model to fetch the entire
graph. This establishes graph-relative facts; predicate feasibility stays unknown.
Both real models now use the query and answer correctly on the same frozen
controller task: direct takes 200.8 seconds / 495,895 cumulative input tokens;
Code Mode takes 203.3 seconds / 554,477. Code Mode has lower uncached input,
but no stable overall advantage is established. All prior pairs stay reported.
The [control-query study](control-query-study.md) verifies every derived control
triple on the real SQLite VM, fixes unknown CFG seeds and reuses a lazy
postdominator index. Its [two-level investigation](controller-oracle.md) is
frozen before model runs and separates alternative path predicates, SSA identity
and finite recovered-edge witnesses from runtime claims. Both real-model answers
now pass: Code Mode reduces cumulative input but increases uncached input, time,
CPU and memory in this pair. Correct facts support both calling strategies;
the query-cache improvement is separate from those mixed whole-task costs.
The [discovery-summary study](discovery-summary-study.md) addresses repeated
metadata from that pair. The complete method index now uses owned intent
summaries; all full contracts and advertised tools remain available. Contracts
and session admission have separate owners, with native loading deferred to open.
Its repeat uses the same frozen control question and retains the earlier results.
That completed repeat again answers correctly in both lanes. The smaller index
does not establish an overall task improvement: actual help use adds a Code Mode
call, and cumulative/uncached tokens, local resources and end-to-end time have
mixed changes. A large observed inter-call gap remains charged and unexplained.
The [exact-value query study](value-query-study.md) adds location-to-value and
value-to-operand-use queries, including inputs/constants without defining operations.
Real stripped OpenSSH checks preserve all 250 SSA versions / 369 occurrences at
one selected policy location while reducing an equivalent core read task from
244 queries to six. A subsequent [real-agent OpenSSH comparison](ssh-warning-study.md)
completes the same machine-supported task through all three interfaces, after
correcting an incomplete traditional evaluator toolset. Atomic direct has the
lowest measured costs in this sample, using machine facts without decompilation;
Code Mode uses the new queries but takes extra analysis steps. General efficiency
claims still require broader evidence.
The reference is [Hex-Rays IDA MCP](https://github.com/HexRaysSA/ida-mcp/blob/df6de7985b534a964c125d5a86e41b26b17b14f6/ida_mcp/mcp.py):
an on-demand `reference` lookup and an execution entrypoint over a richer analysis
API. This experiment uses JavaScript and a QuickJS WASM environment rather than
Python in the host process. It exposes only declared static analysis capabilities.
It does not add target execution, patching or GUI control.
Three boundaries own the implementation:
- `provider.mjs`, `native-ir.mjs`: existing REA native target/process owners and parsed Kuna
string/reference/SSA facts, retained sources, freshness and cleanup.
- `api.mjs`: named, validated fact/relationship contracts and their intent summaries.
`session.mjs` owns shared admission and lease/file cleanup, loading the native
provider only on open. SDK callers, CLI scripts and both MCP adapters use these
same contracts and application owner.
- `executor.mjs`, `server.mjs`, `cli.mjs`: bounded JavaScript composition and
presentation. No analysis is reimplemented in the execution environment.
The complete Code Mode MCP catalog is `open_binary`, `reference`,
`execute_javascript`, `close_binary`. Setting `REA_ATOMIC_ADAPTER=direct` exposes
the same fact API as `facts_*` MCP operations for comparison. This is a distinct
experimental server; the production REA catalog is not filtered or replaced.
Use the pinned Node, an existing REA build and a caller-supplied Kuna 1.833:
```sh
npm ci --prefix experiments/atomic-codemode --ignore-scripts
node --test experiments/atomic-codemode/*.test.mjs
REA_KUNA_COMMAND=/absolute/path/to/kuna node experiments/atomic-codemode/server.mjs
```
The local MCP registration for real model trials is named `rea-codemode`.
`agent-trial.py --mcp-entrypoint /absolute/path/to/server.mjs
--server-name rea-codemode --protocol-profile atomic --profile-parent /tmp` creates an isolated
configuration, home and empty working directory for the model. Shell/file tools,
web search and delegation are disabled. No repository or oracle is placed in that
workspace. The copied authentication file is removed with the isolated profile.
Model output, actual MCP calls, original errors and usage remain in the trial
directory. `REA_ATOMIC_TRACE` and `REA_ATOMIC_EVIDENCE_DIR` retain actual API calls
and complete sources outside the model workspace when explicitly selected by the
evaluator. The ambient environment and credentials are not logged.
Current bounds: 64 MiB guest heap, 32 KiB code and script value/error payloads, 64 host calls per execution,
120 seconds wall deadline and 2 seconds of guest synchronous execution. Native
requests use existing supervision and a 1 GiB function-memory limit. Buffered
formats and diagnostics keep an 8 MiB bound; string inventories stream through
the production reader into the existing 64 MiB per-target source budget, without
an aggregate stdout string. Two resident function indexes each derive from at
most 2 MiB diagnostic or 8 MiB native wire source. Compressed native graphs admit at most 32 MiB decoded
JSON plus independent row/text/relationship bounds. One decoded Evidence text view
up to 32 MiB is also retained per lease; these source bounds are not parsed-heap
size guarantees. Sources are
content-digested and retained until close; explicit evaluator copies survive
close. Capacity failures are explicit, not clipped facts. Leases and snapshot
handles prevent cross-session joins.
The current experimental MCP profile also caps encoded tool-result bodies at
1 MiB, including text escaping and metadata; JSON-RPC/client framing is separate.
`reference.transport_limits` advertises this policy in both modes. The QuickJS
bridge remains 2 MiB. CLI/SDK transports have their own bounds; SDK full selected
string values remain available. Prefer `strings({query,fields:[]})` for metadata.
Invocation context and observed source IDs are additional bounded receipt
metadata; the script payload bound is not a 32 KiB whole-MCP-wire limit. A real
MCP probe found that a 40,000-byte guest exception bypassed that payload policy
and produced a 40,183-byte response. Oversized errors now return explicit
`output_budget` with omission metadata. Escaping expansion is checked too;
ordinary smaller errors remain intact. `verify-executor.mjs` confirms real MCP
delivery and continued access to source Evidence collected before the exception.
It measures response bytes, not model tokens or an analysis speedup. Targeted JS
tests at this stage totaled 42, alongside the separate real-provider and native-writer checks.
The diagnostic SSA format still has incomplete CFG and phi predecessor coverage.
The opt-in [native recovered IR experiment](native-engine.md) adds full recovered
CFG edges, exact value/operand identities, phi incoming-edge bindings, selected
`values`/`blocks` reads and derived control dependence. It requires an explicitly
pinned patched engine; stock Kuna does not gain those capabilities from a wrapper.
Runtime successors, memory aliases and machine-semantic equivalence remain
unknown. Other providers are not yet wired to this experimental service.
The initial [actual model comparison](trials.md) favors the focused traditional
workflow. The seeded value-origin task has lower cumulative input and wall time
through Code Mode, but initially exposes an IR-to-machine-path error. The revised
trial correctly explains that machine path with lower observed task costs;
broader claims still require more than this single seeded task.
The large SQLite VM diagnostic task also completes when its native graph exceeds
capacity. Atomic direct beats Code Mode on cumulative input and wall time in
that sample, and a traditional reused-project run is fastest. The actual CLI
client already exposes JavaScript dispatch in every lane, regardless of requested
feature flags. MCP request counts therefore do not establish fewer model rounds;
the ledger now records actual model responses and client dispatch/wait calls.
`instructions` reads selected machine byte/decode windows through the same
owner. Recovered operations use `origin_address` and blocks `origin_start`;
these locations cannot be substituted for machine branch destinations. The
value-origin trial demonstrates why this boundary matters. The experiment
now has nineteen fact methods, still behind the same four-tool Code Mode
catalog.
`calls` connects recovered call operations to native target specifications and
separates argument SSA values from passing storage. `values(is_input:true)`
selects retained callee inputs for exact storage comparisons. These candidate
links preserve snapshot identities, missing specifications, unknown storage and
runtime-binding limits. The [cross-function task and oracle](call-oracle.md)
are fixed before its real-model trials; the graph wire format is version 3, with independent version-1 call facts.
`references` now selects incoming exact-address references or outgoing
instruction/function references, with native kind filtering, field selection and
paging. Source Evidence plus `source_row` identifies an occurrence. Function
applicability, excluded/unattributed rows, indirect targets and discovery stay
explicit. `fields:[]` requests only the always-retained identity columns across
projection contracts. The [reference question and independent oracle](reference-oracle.md)
cover real SQLite VM aggregates and a machine call omitted from optimized IR.
`bytes` reads explicit virtual-address ranges as native loaded-image hex without
decoding them as instructions. Batched reads preserve short reads and individual
failures, with 64 KiB aggregate selected-byte capacity to bound hex/bridge growth.
Complete hexdumps remain in Evidence. The original-file-offset mapping and live
runtime memory remain unknown. This closes a direct byte-reading contract gap
for data tables; it does not establish arbitrary memory-alias analysis.
`functions` provides selected name/alias/entry reads. Native snapshots report
code and recovered-IR facets separately, preserving readable code when graph
extraction is unavailable. Real capacity and cold/warm MCP checks are documented
in [native-engine.md](native-engine.md). Whole-model costs and unequal-depth
comparisons remain separate in the trial report.
The corrected SQLite comparison reaches the formatter implementation in all
three interfaces. Code Mode uses fewer calls than atomic direct in that sample;
a traditional run reusing its persistent whole-project cache is faster than
Code Mode's fresh lease. Cache state, completed-answer coverage and actual
uncached tokens must therefore accompany any cost comparison.
SDK views share immutable parsed inventories with their owner. A real SDK probe
initially changed a returned string and made the next query disappear under the
same Evidence ID. Freezing at the cache boundary fixes that producing rule,
without copying or parsing the entire inventory for each read. `verify-sdk.mjs`
checks the real provider's string/metadata/function views and complete retained
source digest. The fixed probe passes under the bounded runner (1.328 seconds,
1.144 family CPU seconds, 110.6 MiB kernel family peak, zero OOM kills and verified
payload cleanup); it is a correctness check, not a model-cost measurement.
Encoded size is another real coverage boundary: two SQLite functions initially
lose even their C because pretty JSON exceeds transport capacity. The native
patch now uses bounded compact serialization and a graph-only failure when
needed. Parser's full graph fits; Pragma retains identical C with an explicit
missing graph. The 8 MiB bound remains. See the exact sizes, rebuilt engine digest
and verification scope in [native-engine.md](native-engine.md).
Completion requires actual model Code Mode use, independently checked task
answers, shared atomic/direct/Code Mode semantics, needed relation coverage,
failure/cancellation/identity tests, and equivalent completed-task measurements
including discovery/retries, actual model usage, cold/warm analysis, CPU and
process-family peak memory. Negative cases such as the small SQLite function
must remain in the comparison.
The outgoing-reference real-model pair now completes with identical required
facts and explicit coverage limits. In its single sample, Code Mode uses 264,680
cumulative input / 93.837 seconds versus direct's 285,086 / 106.183. The shared
CLI/API also verifies the VM aggregates on unpatched stock Kuna 1.833. These are
scoped positive results alongside the earlier mixed adapter comparisons, not
proof of general superiority. Details and retained failed/partial attempts are
in [trials.md](trials.md).
Recovered calls and their boundary values now survive full-graph capacity
failure. The real VM capture preserves 416 call operations and 1,294 boundary
values while its graph remains unavailable. Values clearly state their partial
scope; definition IDs do not imply readable defining operations. See the
[boundary question and oracle](boundary-oracle.md) and its completed real-model
pair in [trials.md](trials.md). Both answers pass, using one VM capture each.
Code Mode's single-sample latency is lower, with mixed context costs; broader
efficiency remains unproven. The focused JS suite at that stage passes 49 tests.
Available snapshot call facets now include `by_opcode` known/unknown-target
counts and their own coverage. The owner derives them once from the same
validated immutable calls used by selected reads, including dead operations;
target knowledge is independent of opcode. Empty available facets report zeros,
while unavailable facets omit counts. This small aggregate addresses an observed
cost in the real boundary pair: paging the entire call set just to count it.
Both subsequent real-model answers satisfy the unchanged question/oracle without
that paging. In the new sample direct is faster and lower on cumulative/uncached
input than Code Mode, reversing the preceding latency ordering. Whole-task
effects remain mixed; see [the complete results](trials.md). This aggregate is a
shared fact-layer improvement, available to either adapter.
The shared owner also checks the native cleanup `Result` before releasing its
lease or clearing retained state. A tagged cleanup failure now stays retryable;
MCP errors retain the lease context and reported resources. The real SDK
failure-injection verifier first reproduces the old false success, then verifies
both close and target replacement retain the staged file/owner until a successful
retry. Both public MCP adapters preserve that error and retry successfully.
These use an injected tagged failure, not an observed engine cleanup incident;
native reads and subsequent cleanup use the real provider. See the recorded
scope and resource receipts in [native-engine.md](native-engine.md).
A [subsequent diagnostic probe](projection-experiment.md) measures the VM's full
17 MB recovered graph and much smaller selected definition neighborhoods. It
supports trying a bounded operation/value facet, while preserving unresolved
definitions and unavailable CFG. The following implementation now makes that
facet callable; the original diagnostic remains separate from public results.
`snapshot.facets.operations` distinguishes a complete recovered graph from a
bounded call-rooted definition projection. `operations`, `values`, selected
definition/use `relations` and `slice` share the same parsed operation owner in
either case. Projection coverage preserves unexpanded definition counts and
selected slice frontier reasons; CFG/controller reads remain unavailable.
Native operation reads retain `is_dead` and literal operand/value identities.
Coverage returns compact counts and bounded issue text, with complete native
details retained in Evidence. [The new question/oracle](projection-oracle.md)
are fixed before real-model trials of the PHI format alternatives.
Both first PHI-format model answers pass the full oracle using one VM analysis
and a six-operation selected trace, with the global graph/use limits intact.
The trace reveals two format sources at each shared call, verified against byte
and machine evidence. [Costs and source review](trials.md) also record a direct
documentation-lookup miss; named discovery needs fixing before rerunning the
same task. No general adapter speedup follows from that first pair.
Named reference lookup now accepts canonical IDs or exact displayed names,
including space/comma-separated lists. One presentation map supplies direct
registration and documentation names; unmatched terms remain explicit. Selected
schemas come from named contracts, use input semantics (defaulted fields stay
optional), and are cached immutably by Zod schema identity for the process.
Validation stays in the API registry; documentation has its own module. Both
actual MCP catalogs and all fourteen reference schemas validate. The unchanged
PHI question/oracle were rerun: both answers pass again, but direct has a native
timeout followed by a successful retry. Complete costs and the unknown timeout
cause remain in [trials.md](trials.md); this does not isolate an adapter speedup.
The next observed atom boundary is a wide PHI. One real VM operation has 156
inputs; its old default single-node slice is about 44 KB and exceeds the guest's
32 KiB result budget. Native operation/slice defaults now return opcode, output
and exact input/definition/constant counts. Explicit detailed fields still work.
`relations({kind:"operands",seeds:[id],input_indices:[0,105,155]})` reads selected
slots; omitting the selector pages all slots. Each slot retains value/definition
and phi predecessor/edge identity, including null values and definition-free
constants/inputs. Counts concern recovered facts, not source function arity.
Full and projected native operations use the same owner. Relationship paging
counts existing groups before materializing only the requested page; identity
reads deduplicate requested IDs in caller order. Diagnostic SSA explicitly lacks
native operand relations. The discriminated relation schema advertises the same
seed types and selector applicability enforced at runtime. The fourteen-method
API and both adapters remain shared; no new engine or output-budget increase is
needed. The [seeded wide-operand task/oracle](operands-oracle.md) is separate from
the earlier PHI-format question and is pinned before model trials.
Both actual wide-operand model answers now pass that fixed oracle, including
distinct edges sharing a value and absent-slot versus unretained-seed semantics.
Each performs one native analysis and reads only selected slots, distinct values
and their immediate definitions. Code Mode takes 95.699 seconds versus direct's
91.817, with nearly equal cumulative input and lower uncached input. Its four
discovery lookups prevent fewer MCP requests from becoming fewer model responses.
These [mixed costs](trials.md#selected-wide-phi-input-relationships) validate the
fact boundary while leaving broad efficiency unproven. The current shared JS
suite passes 57 tests; the Python cost-ledger suite passes three.
Discovery now also offers `reference({view:"index"})`: the complete fourteen
method names and descriptions, without schemas or return contracts. Follow with
`view:"contracts"` and exact names for only the needed inputs. The default
contract view and named/topic lookup stay compatible. Both views use the same
registry and presentation map; index access never constructs unrequested schemas.
The index describes declared methods, while `snapshot` remains the live coverage
authority. This addresses observed blind discovery without inventing aliases or
changing analysis facts; its whole-task effect must be measured on the unchanged
wide-operand question.
The identical question now completes correctly through both indexed adapters.
Code Mode uses the intended index plus one named lookup; discovery drops from
four calls to two, without changing the seven fact reads. The new pair takes
about 98.8 seconds each; cumulative input favors direct, uncached input favors
Code Mode. All four wide-operand answers pass, with no retry or OOM. Costs remain
mixed. A selected-slot read still incurs whole-function native decompilation on
a fresh lease; phase profiling is the next computation question, separate from
the now finer fact/query boundary.
The [native phase study](native-compute-study.md) now measures the VM drive at
about 34 seconds, C rendering at 0.22 seconds and projection at 0.03 seconds.
Repeated new native processes do not gain the API owner's warm result reuse.
Its subsequent [bounded codec implementation](native-graph-transport-study.md)
now returns the complete 21,349-operation VM graph in about 3.79 MB, inside the
unchanged 8 MiB wire budget. Selected definitions/CFG reads and decoded Evidence
work through both real MCP adapters; all graph fields and ordinary C/calls match
the prior complete golden. Same-lease reuse is about 67 ms after a 39.7-second
fresh capture, with resource limits and no OOM. The [next question/oracle](savepoint-control-oracle.md)
start from names/error messages and exercise the new condition/CFG coverage.
Two [real-model pairs](savepoint-control-study.md), including a discovery-guided
repeat, answer both local guards correctly without a whole-report fetch. Code
Mode uses fewer MCP requests, but whole-task costs are mixed and a large capture
time variation remains unexplained. Both clients already provide JavaScript
orchestration. Source fidelity is not machine equivalence, provider parity or a
general speedup. The [native switch experiment](switch-study.md) now exports and independently checks
182 labels over those 149 targets, exposes selected case-to-edge relations and
keeps them readable when a 2 MiB native output budget omits the full graph.
Both real models now answer the selected-case/default question correctly using
one retained capture and focused case/byte reads. Code Mode uses fewer tokens
in this pair, but unequal native capture time and extra client polling confound
the comparison. Whole-task costs and limits are in the same study; a general
efficiency advantage remains unproved. A common
[long-wait repeat](client-wait-study.md) reduces polling to one wait per lane;
both answers remain correct, but direct wins cumulative input and wall time
while Code Mode uses less uncached input. Runtime correctness, discovery,
composition choices and waiting all matter to the completed task.
@@ -1,251 +0,0 @@
# AArch64 import entries and return coverage
Two independent producer defects are corrected: BTI import-entry identity and
false no-return promotion that erased a post-warning path. A fresh three-way
model run passes the selected task oracle with all interfaces. Direct atomic
reads use less cumulative and uncached input and finish sooner than Code Mode
in this sample, despite more MCP requests. Correct primitive facts are useful;
the extra Code Mode layer does not automatically improve a completed task.
This continues the [three-way warning investigation](aarch64-xref-study.md),
where all three interfaces encountered the same dropped post-warning path.
## PLT entry checkpoint
The actual Debian arm64 SSH fixture remains SHA-256
`de352e4ace7028d9816fd0ee9d22936bc1b5622c400d5b0b7df660df3426b068`,
1,051,744 bytes, extracted and never executed. The independent
[machine verifier](verify-aarch64-machine.py) checks the warning epilogue's
restored LR/SP, tail branch `0x25858 → 0xbad0`, BTI at that entry, ADRP at
`0xbad4`, loaded GOT slot `0x10f390`, and its `free@GLIBC_2.17` JUMP_SLOT
relocation. GNU objdump's neighbouring synthetic PLT label is not authoritative
symbol identity. Actual runtime binding, pointer authentication and path
feasibility remain unknown.
The old loader recognizes an ADRP/LDR pair and names the ADRP address. The
resulting inventory splits `sub_bad0` (4 bytes) from `free` at `0xbad4` (20).
The corrected owner recognizes the complete standard veneer, optional immediate
BTI c prefix and optional AUTIA1716. It uses the ADRP's own PC and exact
relocation slot, without assuming a PLT stride. Complete load/add/branch
agreement is required before consuming a relocation. Truncated/corrupt sequences,
ordinary preceding instructions, missing slots, misalignment and overflowing
instruction ranges cannot manufacture an entry.
The AArch64 decoder and its tests move into `loader/elf_plt/aarch64.rs`;
section and PT_DYNAMIC paths call that single owner. The parent still owns GOT
name correlation and deduplication. These supported sequences follow Arm's
[System V ABI examples](https://github.com/ARM-software/abi-aa/blob/main/sysvabi64/sysvabi64.rst#sample-plt-sequences).
Other veneer forms stay unrecognized. This experiment does not establish full
Ghidra loader/analyzer parity.
REA refreshed main through `d5be402fb3dbfc56ac9854c27b5538df20cc2437`
(merge `d3443521d`); native upstream stays
`fe01d6294eb0d1053ce343c8943646df88e143fc`. The PLT-only overlay hash is
`ec660ee463d46e95bc76a9c80e0889ee65443748f1196ad61c4464352dfc8c19`.
Copied immutable embed-specs/opt1 engine SHA-256:
`646c49341f9f55147ce9363d8f3e33b69860a830dbd1b88beea339db88ff2fe9`.
The previous engine is `e43185ff11e74c18753e8755c7757ef6ede415c87a1dac9f04bb39856de87f43`.
Six new test groups first ran against the old decoder: five failed, one passed.
All 13 PLT decoder tests then passed, including seven AArch64 groups and the
other architectures' retained cases. The real public SDK inventory now places
`free` at `0xbad0` and `_exit` at `0xbdd0`; their former ADRP-body entries disappear.
The warning's recovered tail call names `free`. The real native CLI
[loader verifier](verify-aarch64-plt.py) checks both the original ELF section
path and PT_DYNAMIC fallback using a separately hashed derived copy with only
ELF section-header coordinates zeroed. Both produce the corrected entries.
Neither input is executed. Both patch application directions pass.
The original and sectionless inventories contain 1713 and 518 entries; this
check compares selected imports, not whole-inventory completeness. PAC coverage
uses synthetic byte fixtures; the real SSH checks exercise the BTI form.
| Executed check | Family wall s | Family CPU s | Kernel family peak MiB |
| ------------------------------------------------------------------------- | ------------- | ------------ | ---------------------- |
| Refreshed REA runtime build | 34.141 | 32.976667 | 3039.0 |
| Six new groups against old decoder, expected failure | 123.335 | 122.063494 | 1031.2 |
| All 13 PLT tests after correction, including compile | 68.475 | 68.217534 | 887.9 |
| Corrected native CLI build | 102.486 | 102.098492 | 625.3 |
| Old-engine SDK inventory/references/two captures/full source verification | 14.314 | 14.060418 | 389.6 |
| PLT-only engine, equivalent SDK workflow | 14.312 | 14.080485 | 388.5 |
| Real CLI, both loader paths | 4.045 | 3.744119 | 101.9 |
All listed scopes verify payload cleanup, observed OOM 0, one CPU and the existing
4 GiB hard/3 GiB early-stop memory guard. Peaks include charged file cache and
are not RSS; verified payload-exit counters are not final whole-scope counters.
SDK sessions use fresh retained-evidence stores; OS cache state is uncontrolled.
The single equivalent SDK pair does not establish a performance improvement.
No new model/token measurement or broad repository typecheck is claimed here.
The PLT-only correction **does not** restore the caller's strict diagnostic:
its recovered call facet still omits `0x2854c`, and C still marks the warning
call at `0x2841c` no-return. This controlled result separates the import-entry
defect from the no-return defect. The discovered-no-return pass has a weaker
terminal-call promotion than the existing propagation walk: it observes a
terminal call somewhere and absence of RET, without rejecting an escaping tail
transfer to possibly returning code. Causality and the structural correction
require their own checks; the entry fix alone is not claimed to solve it.
## No-return ownership checkpoint
With the PLT-only engine unchanged, disabling only `noreturn_disc` restores the
caller call at `0x2854c` and removes the false no-return annotation from the
warning call at `0x2841c`. That native CLI counterfactual takes 5.052 s wall,
4.813974 s local family CPU, 175.6 MiB kernel family peak, with verified cleanup
and observed OOM 0. It isolates the discovered pass; it is not the final fix or
the configuration supplied to model evaluators.
The discovered pass's duplicate promotion scanned a whole function span for
any terminal call and no RET. An alternative tail transfer to a returning
import therefore failed to protect the caller's continuation. The correction
removes that interpretation and shares the propagation pass's conservative
reachable-path walk. Known terminal transfers stop a path; returning tails,
missing successors, unresolved indirect jumps and escaping branches cannot
prove the whole function no-return. A dead, unreachable RET no longer prevents
legitimate promotion. Existing call-site threshold and strict-successor options
remain, but an absent local successor contributes no new vote: it is compatible
with a returning tail call. The inspected
[Ghidra analyzer](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/FindNoReturnFunctionsAnalyzer.java)
also skips calls without fall-through when looking for new indicators; this is
source comparison, not a real-Ghidra runtime verification.
The shared entry first checks for any terminal-transfer candidate before
allocating a body map or visiting its CFG. That necessary-condition check also
applies to the existing propagation consumer. Terminal sets still grow during
the bounded fixpoint, so false results are not cached across changing sets.
There is no added long-lived graph cache or duplicate adapter interpretation.
Five new semantic test groups cover the fatal/returning-tail alternative,
four different unknown exits, genuine terminal paths with a dead RET, a
transitive wrapper fixpoint, and missing versus positively identified
successors. Against the old rule, four groups fail and the wrapper group passes
(the two pre-existing smoke tests also pass). After the correction, all 39
no-return-related tests pass, including those groups. Expected-failure run:
68.371 s wall / 68.147478 s CPU / 889.2 MiB peak. Passing run including compile:
73.808 s / 72.914925 s / 892.6 MiB. Both have verified cleanup and observed OOM 0.
An earlier syntax-error attempt is not counted as a semantic regression run.
The final overlay SHA-256 is
`597b5236c42b214b88da39afe0f2b2b1cd7c5ff82e512e91d6a3249bfef565f1`;
the immutable engine SHA-256 is
`0969be0c9c3ace9357acce1f802f12e8595bc57445da32937933de543ca77672`.
Forward-index and reverse-worktree application checks pass. The public
[SDK verifier](verify-aarch64-returns.mjs) now finds the strict call at
`0x2854c`, removes the false warning-call annotation, retains the genuine fatal
call annotation, verifies canonical import ownership and byte identity, hashes
all retained sources, and checks complete C/source fidelity and warm reuse.
Warm captures retain identical handles/facts: warning 0.770 ms / 0.000797 CPU s;
caller 0.702 ms / 0.000761 CPU s. Cold captures take 2033.6 / 5857.3 ms and
2.023671 / 5.835244 CPU s respectively. These are lease cache observations, not
OS-cold or model-task measurements.
| Executed check after no-return correction | Family wall s | Family CPU s | Kernel family peak MiB |
| --------------------------------------------------------------------- | ------------- | ------------ | ---------------------- |
| Native CLI build | 212.756 | 166.409933 | 629.8 |
| New SDK return/source verifier | 13.606 | 13.381336 | 421.9 |
| Equivalent earlier SDK inventory/references/two captures/full sources | 15.632 | 15.370816 | 415.7 |
| Existing AArch64 xrefs/GOT reads/source regression | 13.309 | 13.018756 | 206.9 |
| Complete old x86 function/prototype fidelity through MCP | 9.080 | 8.790274 | 308.5 |
| All 87 experimental JS tests | 5.355 | 5.055786 | 83.8 |
| Both actual catalogs and converted schemas | 1.936 | 1.712823 | 136.3 |
| Both real native ELF loader paths | 4.047 | 3.799690 | 101.1 |
All these successful scopes verify cleanup and observed OOM 0 under the same
resource bounds. Wall/CPU divergence occurred during compilation; attribution
between host contention and changed compilation is unmeasured. The equivalent
SDK task is slower than the PLT-only 14.312 s / 14.080485 CPU s / 388.5 MiB
sample, while retaining the previously missing path. This single sequential
pair does not establish a general performance delta. Changed-file JS lint,
format and Python compilation checks pass. Broad repository type checking
retains the previously disclosed resource-limited gap.
## Fresh real-model comparison after both corrections
All three trials freeze REA runtime
`bf9d3a6e47de1e16a7eefb58bf385dfbe093fdb9`, the final engine above, the same
target and the unchanged [question](aarch64-warning-question.txt). Trial prefixes
are `arm-return-{direct,codemode,traditional}-v1` under the ignored local cache.
Execution order is Direct, Code Mode, traditional. Each uses a fresh isolated
Codex profile; traditional gets a new project-cache directory and the atomic
modes get new evidence stores. Each requests `gpt-6.1-sol` with high
reasoning through Codex 0.161.0, and receives its actual advertised tools:
22 Direct, 4 Code Mode, or all 16 Kuna-supported traditional tools. Discovery
and SDK-converted schema verification precede these runs. No runtime or engine
mutation occurs during the three trials.
| Whole-task observation | Traditional | Code Mode | Direct atomic |
| -------------------------------------------- | ----------: | --------: | ------------: |
| Cumulative input tokens | 662,683 | 371,571 | 351,157 |
| Cached input, included above | 570,368 | 323,968 | 310,912 |
| Uncached input | 92,315 | 47,603 | 40,245 |
| Output tokens | 5,304 | 6,069 | 5,402 |
| Reasoning tokens, included in output | 1,181 | 1,586 | 1,379 |
| Model responses | 20 | 14 | 12 |
| Client executor calls / waits | 15 / 4 | 13 / 0 | 11 / 0 |
| MCP attempts | 20 | 13 | 25 |
| Rejected MCP attempts | 2 | 0 | 0 |
| Reference-document requests, included in MCP | — | 3 | 1 |
| Shared fact API calls | — | 23 | 22 |
| Model wall seconds | 263.085 | 166.756 | 139.033 |
| Family wall seconds | 263.580 | 167.258 | 139.587 |
| Local family CPU seconds | 166.299552 | 41.040445 | 34.362879 |
| Kernel family peak MiB | 1279.4 | 617.0 | 625.2 |
The unique per-response usage sums match each runner total. Cache writes are
zero. All three runs preserve runtime/engine/target fingerprints, close the
target, remove their isolated profiles, verify payload cleanup and observe OOM 0. Whole-scope final counters remain unavailable; family CPU/memory use verified
payload-exit observations. Memory includes charged file cache, not just RSS.
Remote compute, resolved service model build, OS cache state and host contention
are unmeasured. Fresh local profiles do not imply cold OS or remote model caches.
Code Mode executes its 23 fact calls inside eight `execute_javascript` requests;
Direct issues 22 `facts_*` requests. Each mode retains the same two complete
native function documents, verified equal, including restored strict call
`0x2854c`, the selected pointer bindings, and the warning's named `free` tail.
Code Mode requests three snapshots but captures only two distinct sources; a
repeat uses the existing lease cache. Different queries/field selections and
model response counts are part of the measured workflows, not equal instruction
traces. Both modes, and traditional, also have the same client-side JavaScript
executor available. This compares MCP/API surfaces, not JavaScript versus its
absence.
The traditional run first passes xref instruction addresses `0x25750` and
`0x2853c` to an exact-entry analysis operation; both are correctly rejected. It
recovers with `list_procedures`. Traditional `xrefs` normalizes these results to
address strings; the atomic response also supplies native owning-function
facts. Those navigation differences and retries are counted. Its two successful
function dossiers share the same ready project-export key
`dbfd828b95d9c1a2981707728a9e31b4c38688162e851a904c3808fd911c79eb`.
Higher CPU is not evidence of a broken project cache. Traditional project export
and per-function atomic export remain different native analysis profiles; the
comparison does not isolate transport or schema cost from analysis scope.
All complete answers were read and passed agent review against the frozen
question, independent file/GNU oracle, selected additional GNU checks and their
actual delivered Evidence. Each identifies both functions, proves the selected
pointer transfer and first helper target, verifies format formation/passing,
the four-byte test and actual zero/nonzero successors, conditional cleanup
return, and the necessary runtime/logging/alias limitations. This is selected
task correctness, not human readiness or general analysis completeness.
Every cited source is verified: 11 traditional, 14 Code Mode and 14 Direct IDs.
Traditional projected views correctly have their own provider and null engine
profile; their explicit parent-Evidence links trace to the pinned engine. An
initial audit incorrectly required a native engine profile on each projection;
the corrected audit follows that provenance chain and passes. Atomic retained
source byte counts/digests, target/engine contexts, selected native call/value
bindings, restored strict call and complete selected-function equality pass.
Answer SHA-256 values are:
- Traditional: `655877f07ce8819e7f086c584b49fb6d63dd2a7319c792deb09a721092eb7c5b`
- Code Mode: `35d96912940a3a51704093d08ab228aea3e40fbdc80085d8137385f0d9199f61`
- Direct: `24b1f3954397c3c30686a199189d0a37b61bc6ce74dfc49cfc061e79fe5c7fa9`
The local `return-model-costs.json`, `return-answer-checks.json` and
`return-answer-review.json` retain the detailed receipts/review; raw model and
native captures remain ignored. The earlier Code Mode advantage does not repeat:
this sample uses 5.8% more cumulative input, 18.3% more uncached input and 19.9%
more model wall time than Direct. Its memory peak is slightly lower. One
sequential sample with different model choices cannot establish a stable winner
or attribute the change solely to the fixes. It supplies a concrete counterexample
to treating fewer RPCs as proof of fewer tokens or faster completed analysis.
Broader complex-software effectiveness remains unproved.
@@ -1,92 +0,0 @@
# AArch64 OpenSSH warning oracle
Freeze the question, oracle, source runtime, immutable engine and complete
catalogs before real models. This is a behavior/machine question, without
native-only SSA or prototype-count requirements. The traditional native
Kuna workflow is a valid comparison when its complete tools and evidence
can answer the same question. No question addresses or answers are supplied
to the isolated model workspaces.
Target: extracted Debian `openssh-client_10.0p1-7+deb13u4_arm64.deb`, never
installed or executed. ELF size 1,051,744, SHA-256
`de352e4ace7028d9816fd0ee9d22936bc1b5622c400d5b0b7df660df3426b068`.
Package/provenance and signature-verification limits are in [the storage study](storage-study.md).
All lanes use immutable embed-specs/opt1 engine SHA-256
`e43185ff11e74c18753e8755c7757ef6ede415c87a1dac9f04bb39856de87f43`.
The backend xref correction benefits every lane; old engines with missing
AArch64 facts are not used as a scored traditional baseline.
Independent GNU AArch64 disassembly and FDEs identify banner function
`0x256c0..0x25888`, selected caller `0x27848..0x297d4`. The public
[file/machine verifier](verify-aarch64-machine.py) checks selected ELF words,
ADRP/ADD math, direct/conditional branch targets, the GOT slot/relocation and
GNU unwind ranges without consuming Kuna output. Native SDK/source fidelity
is checked separately. GNU nearest-export labels are not original function names.
Required facts and interpretations:
- Banner format is `0xb0468`: `ADRP X6,0xb0000` at `0x2574c`, then
`ADD X6,X6,0x468` at `0x25750`, then `BL 0x5ae04` at `0x25754`.
The incoming data-reference site is the completing ADD, owned by `0x256c0`.
X6 holds the format pointer at the call. No banner-format stack slot or
original source argument ordinal should be invented from the x86 study.
- Strict format is `0xb1330`: `ADRP X6,0xb1000` at `0x28534`, unrelated
`MOV X5,0` at `0x28538`, completing `ADD X6,X6,0x330` at `0x2853c`,
and `BL 0x5ae04` at `0x2854c`. Reference owner is `0x27848`.
- Banner function has selected incoming calls `0x2841c` from `0x27848` and
`0x29ccc` from `0x297e0`. Select the caller by the strict diagnostic and
corroboration, not by address/name ordering or an original source-name guess.
- Selected pointer setup is `MOV X0,X27` at `0x28414`, then
`BL 0x256c0` at `0x2841c`. In the callee `MOV X23,X0` at `0x256e8`
preserves the incoming pointer; X0 is not rewritten before the first helper
`BL 0x3d108` at `0x256f0`. Matching native passing/input tuples, if used,
remain snapshot-scoped correlations and not global SSA/alias equality.
- Local decision loads **four bytes**: `LDR W0,[X25,0x88]` at `0x2851c`.
`CBZ W0,0x28554` at `0x28524` takes the zero successor `0x28554`;
nonzero falls through to `0x28528`, which prepares the strict diagnostic.
The normalized static model names the tested global `dat_1104f8`.
- The address recovery is corroborated by `ADRP X25,0x10f000` at `0x27904`
and `LDR X25,[X25,0xf20]` at `0x27908`: slot `0x10ff20`, initial/model
bytes `7004110000000000` = `0x110470`, plus field offset `0x88` gives
static image coordinate `0x1104f8`. Independent ELF relocation is
`R_AARCH64_RELATIVE` with addend `0x110470`. An ABI-conforming initial
relocation uses load bias plus addend; this is not a captured live pointer
or a read of the tested runtime value. Across calls, interpreting X25 as
preserved relies on the ordinary callee-save model, not a proved runtime path.
See [Arm ELF relocation semantics](https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#dynamic-relocations)
and [AAPCS64 registers](https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#general-purpose-registers).
- After the strict logging call, `B 0x281c0` at `0x28550` enters cleanup.
Its selected returning route sets `W0=0xffffffff` at `0x281f4` and reaches
`RET X30` at `0x28264`; intervening calls, the stack-check branch at
`0x28214` and pointer authentication can prevent runtime return. Report low
32 bits `0xffffffff` (signed 32-bit -1), without inventing the original return type.
- The banner call precedes this policy test. It alone is not proof of rejection.
Zero enters more checks at `0x28554`, not proof of acceptance/login. The
static initial global/pointer is not a runtime value, alias or binding proof.
Score complete final answers against owner/caller, both address formations,
selected pointer/helper transfer, tested storage/width and zero/nonzero machine
successors, cleanup/low return bits, Evidence/target identities, necessary
unknowns and close. Accept native C/model recovery corroborated by machine
addressing for the static global, or selected loaded-image bytes plus instruction
arithmetic; do not require an unavailable native-only representation. Explicitly
label weaker/missing coverage rather than treating missing facts as completion.
Preflight confirms both strings/xrefs, both selected C/assembly dossiers and
the correct artifact through the real traditional MCP. It resolves the same
static `dat_1104f8`. Its 95.291-second first dossier waits for whole-program
export; later reads reuse that cache. This preflight is not a model trial.
Both atomic catalogs are complete (twenty-two direct / four Code tools), and
the baseline includes all thirteen declared Kuna native operations plus
open/close/retained views (sixteen tools), generated from the capability owner
and actual catalog. Use the same question, requested gpt-6.1-sol/high, fresh
isolated profiles/private caches, common envelope/discovery/stopping/wait
guidance and one-CPU / 4 GiB hard / 3 GiB early-stop bounds. Planned order is
traditional → Code Mode → direct, pinned before launch. Charge every attempt,
whole-task cumulative/cached/uncached input, output/reasoning, responses,
calls/retries/waits, elapsed/CPU and kernel family peak memory. Existing client
JavaScript dispatch is present in every lane. Native profiles differ: selected
atomic windows/functions versus traditional whole-program export. This is a
workflow comparison, not an isolated dispatch-only or same-native-work ablation.
Remote build/compute, OS/model caches and host contention remain unknown.
@@ -1,30 +0,0 @@
Analyze {{artifact_path}} statically, starting from these observed formats:
- REMOTE HOST IDENTIFICATION HAS CHANGED
- Host key for %.200s has changed and you have requested strict checking.
Find the function that supplies the banner format to a formatting/logging call,
and the caller that owns the second diagnostic. Establish both from references
and corroborating function facts; do not guess original source names. Show the
selected direct call from that caller into the warning function. Trace its
passed pointer into the warning function's first helper-call use, including
machine passing locations and call targets. If using SSA, keep the snapshots'
value identities separate; matching storage is not a general alias proof.
Show how the banner format pointer is formed and passed to its formatting/
logging call. Verify the essential address formation, register or stack passing
location and transfer against selected machine instructions. Recovered origins
or operand slots alone do not establish machine addresses or source ordinals.
In the selected caller, after the warning call returns, identify the local test
that chooses the strict-checking diagnostic versus continuation. Report the
tested storage and width, both actual machine successors with zero/nonzero
behavior, and the selected failure-cleanup path's low 32-bit return value.
Distinguish machine addressing from any static model's global-address recovery;
do not present an initial/model pointer as observed live memory. Does selecting
the banner alone prove rejection? Does zero prove a connection will be accepted?
Give a focused answer with function/instruction addresses, real Evidence IDs,
target digest and necessary coverage. Prefer selected facts/windows; do not
return full reports or inventories to model context. Preserve unknown runtime
values, relocation/binding state, aliases, logging behavior, other paths and
runtime feasibility. Do not execute the target. Close the target lease.
@@ -1,230 +0,0 @@
# Composable AArch64 address references
The AArch64 OpenSSH check exposed a real completeness gap before another model
comparison: both warning strings were present, but Kuna returned zero incoming
references for either. Native observations had unknown discovery coverage;
zero was not proof that the strings were unused. Independent GNU decoding
showed ADRP plus ADD at `0x2574c/0x25750` and `0x28534/0x2853c`.
The query scanner read one instruction's p-code at a time. The existing ARM
pool-displacement tracker supplied the relevant bounded value-flow owner, but
did not carry AArch64 page bases. The experiment extends that owner rather than
introducing another interpreter or postprocessing disassembly text. SLEIGH's
mnemonic licenses ADRP, and its exact constant COPY supplies the coordinate;
COPY/ADD/SUB then propagate the value. Machine operand text and hardcoded
register-offset tables are not reparsed. Possible page copies alone, such as
ordinary MOV-immediate instructions, do not establish PC provenance.
The same calculation produces Data for materialized register addresses, or
Read/Write for a LOAD/STORE through a composed default-data-space byte address.
The accessed cell is identified; its mutable/GOT contents are not propagated
as a live value. This also covers the selected GOT slot, which an intermediate
address-only fix still missed. Space-selector constants and stored values are
not mistaken for access pointers.
The directly related refactor renames the former private pool-only module to
`kuna_pc_relative`, moves its tests out of the implementation and retains one
value lookup for arithmetic and memory accesses. Keys preserve native space
identity, offset and width. Partial overwrites invalidate overlaps; copies can
carry a known value into a different register. Calls/jumps/returns stop carry,
instruction-local predicates do not execute both arms sequentially, a pool
load overwritten later in the same instruction cannot seed a stale value,
unsupported widths remain unknown and interval checks include the final u64
byte without overflow. Empty/failed assembly rendering cannot license ADRP.
State remains function-local, follows fall-through addresses and keeps the
existing eight-hop/eight-value bounds. It is not a complete fixed-point,
cross-call, alias, runtime-value or feasible-path analysis. Unknown discovery
and indirect-target coverage remain explicit through the shared parser and
SDK/CLI/MCP views. Both experimental adapters and the traditional Kuna provider
consume the corrected native producer; no special advantage is injected into
one evaluator lane. Stock Kuna is not silently upgraded.
## Pins and real artifacts
REA refreshed main through `0d2247428` before this work. The native upstream is
`fe01d6294eb0d1053ce343c8943646df88e143fc`, overlay SHA-256
`62cb9d9386d110ca1301d4f7d541d0d1ee676f17ca888163cf7d69d8a9d07c53`.
The copied immutable embed-specs/opt1 engine SHA-256 is
`e43185ff11e74c18753e8755c7757ef6ede415c87a1dac9f04bb39856de87f43`.
Default forward-index and reverse-worktree patch checks pass. New analysis
patch sections use Git-supported unprefixed empty context lines, preserving
line counts/source bytes without whitespace-only lines in the patch artifact.
The target is extracted Debian arm64 OpenSSH, SHA-256
`de352e4ace7028d9816fd0ee9d22936bc1b5622c400d5b0b7df660df3426b068`.
The [storage study](storage-study.md) records its package URL, digest and
unverified package-signature scope. It was neither installed nor executed.
The [independent machine oracle](verify-aarch64-machine.py) reads checked
file-backed ELF ranges, validates selected instruction/branch math and GNU FDEs,
and confirms the selected RELATIVE relocation. It does not read Kuna output.
The oracle refuses optimized Python rather than silently disabling assertions.
The real SDK verifier returns one reference for `0xb0468`, from `0x25750`,
owned by `0x256c0`; and one for `0xb1330`, from `0x2853c`, owned by `0x27848`.
It also verifies both direct caller sites and 77 reads of GOT slot `0x10ff20`,
including `0x256d0`, `0x27908`, `0x27dcc` and `0x28eb8`. The slot's selected
loaded-image bytes agree with the independent file read, while runtime memory
remains not-observed. Full retained source digests are verified. A warm repeat
uses the same Evidence IDs and identical facts.
## Executed checks and costs before model trials
| Check | Family wall s | Family CPU s | Kernel family peak MiB |
| ------------------------------------------------------------- | ------------- | ------------ | ---------------------- |
| Refreshed REA runtime build | 36.660 | 35.931222 | 2989.1 |
| 17 final PC-relative tests, including compile | 69.090 | 68.844945 | 885.1 |
| All 125 Listing tests, including those 17 | 0.524 | 0.349058 | 59.2 |
| Final native CLI build | 104.525 | 104.240617 | 630.2 |
| Real AArch64 SDK/source verifier | 13.109 | 12.857963 | 203.1 |
| Old x86 complete-function/prototype fidelity through real MCP | 8.779 | 8.516305 | 302.0 |
| Both actual atomic catalogs and converted schemas | 1.932 | 1.689159 | 139.3 |
| All 87 experimental JS tests | 5.060 | 4.890171 | 78.8 |
| Complete traditional capability/catalog selection | 4.148 | 3.761593 | 443.2 |
| Actual traditional MCP target/C/assembly preflight | 103.002 | 102.596202 | 872.3 |
The independent machine verifier, changed-file lint/format checks and patch
application checks also pass; their CPU/memory costs were not separately measured.
All measured successful runs have observed OOM 0 and verified payload cleanup.
Resource scopes use one CPU, 4 GiB hard/3 GiB early-stop memory, TasksMax192 and
swap disabled. Peaks include charged file cache and are not RSS. Final
whole-scope counters are unavailable; table values use verified payload-exit
observations. Broad repository type checking retains the previously reported
resource-limited gap; no passing full typecheck/native corpus gate is claimed.
The 17 PC-relative tests include the retained pool-displacement cases and new
page/copy/space/width/clobber/predicate/access cases; they are included in the
125 Listing tests, not additional independent executions. An intermediate run
passed 16/17: its obsolete assertion expected no reference when a composed
temporary was dereferenced. The intended extension now identifies that actual
cell Read while retaining the negative assertion against a register address-taken
claim. The test was updated to require exactly that stronger typed outcome.
All failed/intermediate receipts remain local; they are not model attempts.
The AArch64 two-address reference batch takes 3,548.3 ms wall / 3.535213 CPU s
on a fresh lease, versus 1.54 ms / 0.001539 s for the same-lease repeat. This
shows retained-source reuse, not faster native discovery. Old engine c48ad957
returned incorrect zero results; its costs are not an equivalent completed-task
performance baseline for those new facts.
A separate equivalent x86 task requests the same three exact-address reference
sets before/after. Every normalized fact and coverage field agrees (counts
1/1/2), using fresh leases/private caches. Its old/new cold phase is
4,028.3/4,082.2 ms wall and 3.993216/4.031850 CPU s; warm is 3.30/2.38 ms.
Whole-run wall is 4.852/4.852 s, CPU 4.554857/4.580338 s, peak 155.3/157.4 MiB.
This single lookup repeat shows no material observed regression for that case;
it is not a model-token measurement or a general speed guarantee. OS/cache and
host variation remain uncontrolled.
## Frozen model task
The [question](aarch64-warning-question.txt) and [oracle](aarch64-warning-oracle.md)
ask the same behavior-level warning/pointer/guard/cleanup question through
three complete interfaces. Native SSA identities are optional. Traditional
preflight supplies the same strings, actual references, both C/assembly dossiers,
and recovered static `dat_1104f8`, with target/engine digests verified. Its first
dossier costs 95.291 s waiting for whole-program export; later assembly/dossier
reads reuse that cache. Atomic selected-native profiles differ, so the planned
comparison is a full workflow comparison, not a dispatch-only ablation.
The runtime/question/oracle are frozen at
`5eede35c978c76ff9215443ed0a0d5980bfbdfe1`. Execution order is traditional →
Code Mode → direct. All request gpt-6.1-sol/high via Codex 0.161.0, with fresh
isolated profiles/private caches and the same task. Both atomic catalogs are
complete (22/4 tools); the traditional set contains every declared Kuna native
operation and session/views (16 tools). Each client actually has JavaScript
dispatch. This compares MCP workflows inside that common client surface.
All three complete answers pass agent review against the frozen oracle. They
identify both owners, the X27→X0 pointer/helper transfer, banner ADRP/ADD into
X6, four-byte field/CBZ successors, static versus live pointer knowledge,
cleanup/low return bits, Evidence/target identities, unknowns and close. The
traditional answer uses native C recovery plus machine addressing for the static
global; both atomic answers also read the selected loaded-image pointer bytes.
No native-only representation is required to pass.
Separate scripted checks verify all seven traditional, fifteen Code and fourteen
Direct cited sources against delivered responses/traces and target/engine
identities. Atomic retained source hashes/lengths agree; complete selected native
function documents are identical between the two atomic lanes. Selected native
argument/value/passing tuples and the PHI/input distinction match the delivered
graphs/call facets. The independent ELF/GNU oracle checks the machine facts.
Supplementary GNU checks corroborate the traditional answer's added logging
wrapper call at `0x5ae6c → 0x5abb0`, with X6 unchanged. Source/fidelity checks
are separate from agent review of the entire natural-language answers; neither
constitutes human readiness or global machine-equivalence verification.
| Whole completed task | Traditional | Code Mode | Direct atomic |
| ----------------------------------------------------- | ----------- | ----------------------------- | --------------- |
| Required answer | pass | pass | pass |
| Cumulative input tokens | 681,613 | 388,365 | 515,929 |
| Cached input, included above | 639,360 | 336,000 | 436,224 |
| Uncached input | 42,253 | 52,365 | 79,705 |
| Output tokens | 5,423 | 5,755 | 6,529 |
| Reasoning, included in output | 1,324 | 1,137 | 1,934 |
| Unique model responses | 23 | 13 | 15 |
| Client executor / wait calls | 16 / 6 | 12 / 0 | 14 / 0 |
| MCP attempts, including failures/discovery/open/close | 13 | 12 | 31 |
| Rejected MCP attempts | 2 | 0 | 0 |
| Atomic fact reads | n/a | 25 inner reads | 25 direct reads |
| Native function dossiers / snapshot requests | 4 dossiers | 3 requests, 2 unique captures | 2 captures |
| Model wall seconds | 345.676 | 151.264 | 164.942 |
| Family wall seconds | 346.217 | 151.834 | 165.421 |
| Local family CPU seconds | 186.786767 | 41.152525 | 43.116751 |
| Kernel family peak MiB | 973.1 | 695.7 | 600.4 |
Both traditional rejections are instruction-interior addresses passed to exact
procedure lookup. The inventory was available, the model used it and completed;
this is not the earlier under-equipped baseline. All four traditional dossiers
report the same ready project-export key, so the observation does not establish
a broken project cache. Its extra logging-wrapper investigations and native
profile add work beyond the two selected atomic captures. All attempts remain
charged; failed/intermediate development checks are separate from model trials.
Code uses 24.7% less cumulative input and less wall/CPU time than Direct in
this pair, but more peak memory. Compared with traditional it uses 43.0% less
cumulative input and less wall/CPU/memory, but **23.9% more uncached input** and
more output. There are only two fewer model responses than Direct, despite
nineteen fewer MCP requests. Same fact-read counts do not mean identical native
work. This is one new architecture/version sample with uncontrolled OS/model
caches, host contention, service build and remote compute, not a stable Code
Mode advantage, a price claim or broad complex-software superiority.
Unique per-response usage sums match the task totals. All target, engine and
runtime fingerprints remain unchanged. All three profiles are removed; verified
payload-exit observations show OOM 0 and descendant cleanup. The same resource
bounds and kernel-memory interpretation as above apply.
Raw model records are `arm-warning-{traditional,codemode,direct}-v1/` with sibling
resource logs/configs; atomic traces and explicitly retained sources have matching
prefixes. Derived records are `arm-model-costs.json`, `arm-answer-checks.json`,
`arm-answer-review.json` and `arm-traditional-delivered-evidence.json`. Reviewed
answer SHA-256 values are:
- Traditional: `5312aa0757b35b8a28b8d1c60af652760e445b0463117eb41def1e2eeb5031eb`
- Code: `e331df37f53e58a85bea61f37b5e3b7c6a6848af78a0225383df0d9a481121a7`
- Direct: `792b613d25e9c5dfec4e4dd03c13d265f24937e0eafc817931bd5a563e496408`
## Remaining native identity/control-flow question
All answers detect the recovered caller's no-return treatment of the warning
call and use machine instructions for the requested conditional post-call path.
The recovered call facet omits the strict call. Complete recovered-graph coverage
therefore does not establish a complete machine graph or a correct no-return
inference. This is a concrete remaining backend/identity investigation.
Supplementary static observations identify a suspicious boundary: the warning
epilogue restores LR/SP and branches at `0x25858` to `0xbad0`. That address
starts with BTI, followed by ADRP at `0xbad4` and a slot load at `0xbad8` from
`0x10f390`. ELF `R_AARCH64_JUMP_SLOT` names that slot `free@GLIBC_2.17`.
The native inventory instead exposes `sub_bad0` with size bound 4 and `free`
at `0xbad4` with bound 20. GNU's synthetic PLT label at `0xbad0` says closedir,
which the actual slot relocation contradicts; it must not be used as symbol
identity. Whether the native BTI/veneer split causes the no-return propagation
still needs a producing-boundary investigation and regression proof. No such
fix or rerun is attributed to the frozen comparison above.
Raw receipts live under `.cache/atomic-codemode/` as `arm-*`: initial missing
xrefs, intermediate/final native test/build logs, SDK/source records, x86 fidelity
and equivalent-query costs, actual catalogs and traditional preflight. Binaries,
native projects and raw captures remain uncommitted.
@@ -1,24 +0,0 @@
// Shared named contract and selection vocabulary; no engine or adapter code.
import { z } from "zod";
export const hex = z.string().regex(/^0x(?:0|[1-9a-f][0-9a-f]{0,15})$/u);
export const valueLocation = z.strictObject({
space: z.string(),
offset: hex,
size_bytes: z.number().int().positive(),
});
export const page = {
offset: z.number().int().nonnegative().default(0),
limit: z.number().int().min(1).max(128).default(20),
};
export const definition = (
{ summary, description },
input,
method,
example,
) => ({
summary,
description,
input: z.strictObject(input),
method,
example,
});
-424
View File
@@ -1,424 +0,0 @@
// One named contract registry shared by SDK, CLI, direct MCP and Code Mode.
import { z } from "zod";
import { MAX_BYTE_BATCH_BYTES, MAX_BYTE_WINDOWS } from "./limits.mjs";
import { MAX_GRAPH_BLOCKS } from "./graph-limits.mjs";
import { createReference } from "./reference.mjs";
import { definition, hex, page, valueLocation } from "./api-contracts.mjs";
import { storageMethods } from "./storage-contracts.mjs";
import { referencesMethod } from "./reference-contracts.mjs";
const snapshot = z.string().startsWith("snap_");
const byteWindow = z.strictObject({
address: hex,
length: z.number().int().min(1).max(MAX_BYTE_BATCH_BYTES).default(256),
});
const kinds = z.enum([
"value",
"load",
"store",
"phi",
"call",
"branch",
"switch",
"return",
]);
const fields = z
.array(
z.enum([
"kind",
"statement",
"definitions",
"constants",
"opcode",
"inputs",
"output",
"is_dead",
"input_count",
"definition_count",
"constant_count",
]),
)
.optional();
const identitySeeds = z.array(z.string()).min(1).max(128);
const relationInput = z.discriminatedUnion("kind", [
z.strictObject({
snapshot,
kind: z.literal("cases"),
seeds: identitySeeds,
case_values: z.array(hex).max(128).optional(),
case_indices: z.array(z.number().int().nonnegative()).max(128).optional(),
...page,
}),
z.strictObject({
snapshot,
kind: z.literal("operands"),
seeds: identitySeeds,
input_indices: z.array(z.number().int().nonnegative()).max(128).optional(),
...page,
}),
z.strictObject({
snapshot,
kind: z.enum(["definitions", "uses", "value_uses"]),
seeds: identitySeeds,
...page,
}),
z.strictObject({
snapshot,
kind: z.enum(["incoming", "outgoing", "controllers"]),
seeds: z.array(z.number().int().nonnegative()).min(1).max(128),
...page,
}),
]);
export const methods = {
...storageMethods,
switches: definition(
{
summary:
"Select recovered switches/table metadata; fetch cases separately. Native defaults may differ from machine guards.",
description:
"Inspect recovered indirect branches and their independent native jump-table metadata, without returning all case rows. Selector is the current recovered BRANCHIND input, which may be normalized rather than the machine jump address. Native consumed mask and signed rendering hint are not complete runtime/signedness proofs. Null tables/defaults stay unknown. The native model default out-edge is separate from any machine out-of-range guard destination. Use relations kind:cases for selected raw table rows, labels and their native mapping to recovered edges; row/edge ordinals are not case values. Available even when the full graph is unavailable if this independent facet was captured.",
},
{
snapshot,
ids: z.array(z.string()).max(128).optional(),
origin_addresses: z.array(hex).max(128).optional(),
fields: z.array(z.enum(["selector", "table"])).optional(),
...page,
},
"switches",
'await rea.switches({snapshot:s,origin_addresses:["0x1000"]})',
),
functions: definition(
{
summary:
"Select callable entries and aliases, preserving ambiguous names; reported sizes are bounds, not assured extents.",
description:
"Search retained native callable entries by literal name/alias, exact name, or entry addresses. Names can match several entries, including PLT/import stubs and implementations; preserve all matches and select by address. A name does not establish runtime symbol binding.",
},
{
query: z.string().default(""),
exact: z.boolean().default(false),
case_sensitive: z.boolean().default(true),
addresses: z.array(hex).max(128).optional(),
fields: z.array(z.enum(["name", "aliases", "size"])).optional(),
...page,
},
"functions",
'await rea.functions({query:"format_error",exact:true})',
),
strings: definition(
{
summary:
"Search native string candidates by literal text; discovery and reference attribution remain unknown.",
description:
"Search native string candidates by literal text (JavaScript UTF16 includes semantics, no regex). Address and encoding identify an object within the artifact; fields:[] omits display text. Select value, provider_value or decoding only when needed. Encoded byte lengths and provider-reported NUL termination are preserved when known; omitted NUL status is unknown. A false NUL status makes no claim about bytes outside that span. Coverage.source_scope distinguishes a retained whole inventory from a selected query report; source IDs need not be shared between queries/pages/detail views. source_row, when present, is the canonical candidate ordinal under the declared native scan settings. Paging and native selection completeness do not establish artifact discovery completeness. Complete captured source remains readable through evidence.",
},
{
query: z.string(),
fields: z
.array(z.enum(["value", "provider_value", "decoding"]))
.optional(),
...page,
},
"strings",
'await rea.strings({query:"incorrect header check",fields:[]})',
),
references: referencesMethod,
snapshot: definition(
{
summary:
"Capture one function's analysis; return a snapshot, retained Evidence, facet availability and scoped counts.",
description:
"Analyze an explicit function entry once; return a retained capture handle, facets and coverage. Reuses the source within this target lease. Code, recovered calls and values remain independently available when full recovered IR exceeds capacity. A bounded call-rooted operation/definition projection may also be available; inspect facets.operations and coverage before reads. CFG queries still require the complete recovered graph. Available calls include compact by_opcode counts of known/unknown targets over the whole retained call facet; no paging is needed for these counts. Selected calls and complete Evidence remain readable.",
},
{ entry: hex },
"snapshot",
'await rea.snapshot({entry:"0x1000"})',
),
bytes: definition(
{
summary:
"Read batched static loaded-image byte ranges with source identity and per-window partial outcomes.",
description:
"Read selected native loaded-image bytes without instruction decoding. Batch up to 16 exact virtual-address windows and 64 KiB total selected bytes; hex uses twice that space before provenance. Short reads remain partial. A shared source can contain several windows; source_row, when present, identifies its zero-based native window row. Repeated exact ranges can reuse that source. These are not live process memory or an original-file-offset mapping. Global code discovery is not performed.",
},
{
windows: z.array(byteWindow).min(1).max(MAX_BYTE_WINDOWS),
},
"bytes",
'await rea.bytes({windows:[{address:"0x2000",length:32}]})',
),
instructions: definition(
{
summary:
"Decode selected static machine-byte windows, distinct from optimized IR edges and runtime execution.",
description:
"Batch selected machine instruction windows. Read exact bytes and native disassembly to verify actual control transfers; optimized recovered CFG edges can bypass machine blocks. Address+size with the artifact context identifies the byte range. A caller-selected decode start does not prove execution/alignment.",
},
{
windows: z
.array(
z.strictObject({
address: hex,
count: z.number().int().min(1).max(4096).default(16),
}),
)
.min(1)
.max(16),
fields: z
.array(z.enum(["bytes", "text", "mnemonic", "operands"]))
.optional(),
},
"instructions",
'await rea.instructions({windows:[{address:"0x1000",count:8}],fields:["bytes","text"]})',
),
operations: definition(
{
summary:
"Select snapshot-local IR operations by identity, origin, constant or kind, with native/projection scope.",
description:
"Select SSA operations by IDs, source instruction origins, block IDs, constant literal or kind. Native default rows are compact summaries: opcode/kind/output and input/definition/constant counts; request detailed fields explicitly or page input slots via relations kind:operands. Filters intersect; identities and native is_dead are retained. Availability may be a complete recovered graph or a bounded call-rooted projection; inspect coverage before inferring absence. A literal match is not object identity. origin_addresses selects optimized recovered IR origins; use instructions for actual machine control transfers.",
},
{
snapshot,
ids: z.array(z.string()).max(128).optional(),
origin_addresses: z.array(hex).max(128).optional(),
block_ids: z.array(z.number().int().nonnegative()).max(128).optional(),
constant: hex.optional(),
kind: kinds.optional(),
fields,
...page,
},
"operations",
'await rea.operations({snapshot:s,constant:"0x2000",fields:["statement"]})',
),
relations: {
summary:
"Read typed SSA operands/def-use, CFG/controllers or switch cases by identities; preserve unknown/partial scope.",
description:
"Read native operand occurrences, operation definitions/uses, value_uses or case rows. value_uses takes value-ID seeds and returns exact operation/input-slot occurrences, including function inputs and constants without defining operations; null definition stays explicit, not a missing use. Uses cover retained operations, not runtime or memory aliases. Other data-flow/case seeds are operation IDs; incoming/outgoing CFG edges or derived controllers for block IDs. Native CFG/controller reads deduplicate seeds and report unretained_seeds; an unknown block is not a retained block with no relations. Incoming/outgoing rows keep caller seed then native edge order; controllers keep native controller/edge then postdominator order. cases pages one relation per case/out-edge, with a stable case_id; an unmapped case has one explicit unknown-edge row. total counts relations, not table rows. cases filters optional case_values (native labels tagged value) and case_indices (original row ordinals); both filters intersect and paging spans deduplicated seeds in caller order. Rows preserve missing/no-label status, original recovered target, and separate recovered edges. Partial/unavailable tables and unmapped rows are explicit; no runtime feasibility claim. operands pages every selected input slot, including constants, function inputs and null slots; input_indices optionally selects slots in caller order. Identity is snapshot + operation + input_index; value_id/definition and exact phi predecessor/edge bindings remain separate. Out-of-range slots of retained operations are absent; unretained_seeds remain unknown. A bounded call-rooted projection supports operands/definitions/uses but no CFG; uses cover retained selected operations only. Diagnostic SSA lacks native operands and has partial CFG/printed occurrences. controllers requires a complete recovered graph and concerns finite paths to recovered exits, not runtime feasibility.",
input: relationInput,
method: "relations",
example:
'await rea.relations({snapshot:s,kind:"operands",seeds:[op.id],input_indices:[0,2]})',
},
values: definition(
{
summary:
"Select SSA values by ID or exact space/offset/width; keep versions, inputs and constants distinct, without alias inference.",
description:
"Read native SSA values by IDs or exact locations [{space,offset,size_bytes}], with width required. Locations match retained metadata, including const/unique spaces, not pointee contents, aliases or live memory. Filters intersect; IDs retain caller order, otherwise locations retain caller order and values retain native order per location. Empty IDs/locations select none. Null-space values cannot resolve a location and stay explicit in location_coverage; unretained_locations means no known retained coordinate match, not absent machine storage. Scope may be a full graph, bounded call-rooted definition projection, or call-boundary values only; is_input filters the raw native input flag, which can also mark globals or stack values; it is not formal-parameter membership. Use parameters for the separate native recovered prototype, which also does not prove an original source signature. Offset is an address-space offset, not a computed arbitrary-width value. Width, constants, function inputs, annotation status and defining operation are separate facts. Requires the pinned native exporter.",
},
{
snapshot,
ids: z.array(z.string()).max(128).optional(),
is_input: z.boolean().optional(),
locations: z.array(valueLocation).max(128).optional(),
fields: z
.array(
z.enum([
"space",
"offset",
"size_bytes",
"is_constant",
"is_input",
"is_annotation",
"definition",
"type_name",
]),
)
.optional(),
...page,
},
"values",
"await rea.values({snapshot:s,ids:op.inputs.map(i=>i.value_id).filter(Boolean)})",
),
calls: definition(
{
summary:
"Read recovered calls, target knowledge, arguments and passing storage; signatures and runtime binding remain uncertain.",
description:
"Select structured recovered call sites and argument bindings. Target comes from native call specifications, never the fspec annotation offset or display text. Each argument separates its SSA value from its passing storage. Calls and their boundary values survive full graph capacity failure. target_value_id retains input zero independently of target resolution; it may be an fspec annotation or an unresolved indirect target value. A null output describes this recovered operation, not proof of a void source signature. Input slots are not original source parameter ordinals; missing storage and indirect/runtime targets remain unknown. To investigate across functions, snapshot the selected callee and select values with is_input:true, comparing exact space/offset/width. Requires the pinned native exporter.",
},
{
snapshot,
ids: z.array(z.string()).max(128).optional(),
origin_addresses: z.array(hex).max(128).optional(),
fields: z
.array(
z.enum([
"target",
"target_name",
"arguments",
"output",
"prototype",
"stack_offset",
"target_value_id",
"is_dead",
]),
)
.optional(),
...page,
},
"calls",
'await rea.calls({snapshot:s,origin_addresses:["0x1100"]})',
),
blocks: definition(
{
summary:
"Select recovered CFG blocks and edges; origin addresses are provenance, not machine block extents.",
description:
"Read native recovered blocks by stable snapshot-local ID, with ordered predecessors, successor edges and member operation IDs. origin_start describes optimized IR provenance, not a machine block extent. Requires an available native recovered IR graph. Runtime successors remain unknown.",
},
{
snapshot,
ids: z.array(z.number().int().nonnegative()).max(128).optional(),
fields: z
.array(
z.enum(["origin_start", "operations", "predecessors", "successors"]),
)
.optional(),
...page,
},
"blocks",
"await rea.blocks({snapshot:s,ids:[op.block]})",
),
parameters: definition(
{
summary:
"Select native recovered formal parameter and return storage, convention and recovery flags; raw input varnodes are not formals.",
description:
"Read the captured native function prototype: paged parameter entries, return descriptor, native convention label, locks, variadic and recovery-error flags. IDs/indices belong to this snapshot's recovered prototype, not proven source parameter ordinals or original signature. Native is_input also marks stack/global input varnodes; it is not formal membership. Select indices in caller order and optional fields; defaults omit display names/type strings. Output uses the same field selection. Null storage/type stays unknown; explicit is_void is independent of storage absence. Storage matches across snapshots require exact artifact/callee identity and ABI reasoning; stack rebasing, aliases, split/join storage, runtime binding and source signatures remain unproved. Requires a captured parameters facet, independently of full CFG/calls. Older experimental captures explicitly report not-captured; no synthetic empty signature.",
},
{
snapshot,
indices: z.array(z.number().int().nonnegative()).max(128).optional(),
fields: z
.array(
z.enum([
"name",
"type_name",
"size_bytes",
"is_void",
"storage",
"type_locked",
"name_locked",
"size_locked",
"this_pointer",
"indirect_storage",
"hidden_return",
]),
)
.optional(),
...page,
},
"parameters",
'await rea.parameters({snapshot:s,indices:[0],fields:["storage","size_bytes","is_void","type_name"]})',
),
path: definition(
{
summary:
"Find one shortest recovered CFG path to a block or exit, with exclusions and paged native edges; feasibility stays unknown.",
description:
"Find one shortest edge-count witness in the complete recovered CFG from a numeric block ID to a block or any zero-successor recovered exit, excluding avoid IDs. Ties follow native successor order. Return paged native edges with a separate step_index; index remains the original successor ordinal. A found zero-edge path is distinct from not-found. Unknown start/target/avoid identities produce status unknown and unretained_blocks, never absence. Not-found applies only to this recovered graph under the requested exclusions; exits, termination, machine flow and branch-predicate feasibility remain unproved. Requires the full recovered_ir facet, not a call-rooted projection. Search state is bounded by the admitted graph; one last-query cache per resident immutable graph expires with eviction/lease close. The avoid selection is bounded by the maximum admitted graph block count.",
},
{
snapshot,
from: z.number().int().nonnegative(),
target: z.discriminatedUnion("kind", [
z.strictObject({
kind: z.literal("block"),
id: z.number().int().nonnegative(),
}),
z.strictObject({ kind: z.literal("exit") }),
]),
avoid: z
.array(z.number().int().nonnegative())
.max(MAX_GRAPH_BLOCKS)
.default([]),
...page,
},
"path",
'await rea.path({snapshot:s,from:block,target:{kind:"exit"},avoid:[join]})',
),
slice: definition(
{
summary:
"Trace bounded backward definitions with explicit LOAD/PHI/frontier cutoffs; memory aliases remain unknown.",
description:
"Compose a bounded backward definition traversal from explicit operation IDs. Native default operation rows are compact summaries; request detailed fields or use paged operand relations for wide nodes. Available over a complete recovered graph or bounded call-rooted projection. Missing defining bodies retain frontier reasons; complete use sets and CFG are unavailable for a projection. Default load/phi cutoffs keep boundaries visible; choose stop_kinds:[] to traverse beyond them. Complete reachability and memory aliases remain unknown.",
},
{
snapshot,
seeds: z.array(z.string()).min(1).max(64),
max_operations: z.number().int().min(1).max(256).default(48),
stop_at: z.array(z.string()).max(128).default([]),
stop_kinds: z.array(kinds).default(["phi", "load"]),
fields,
},
"slice",
'await rea.slice({snapshot:s,seeds:callIds,stop_kinds:["load"],fields:["opcode","inputs","output","constants"]})',
),
code: definition(
{
summary:
"Read selected lines of retained reconstructed code, including when graph capture is unavailable.",
description:
"Read reconstructed code from the same retained function capture, even when its graph facet is unavailable. offset is zero-based. A large limit reads the complete code inside Code Mode for local filtering. The bridge byte budget bounds the result. No additional decompilation.",
},
{
snapshot,
offset: page.offset,
limit: z.number().int().positive().default(64),
},
"code",
"await rea.code({snapshot:s,offset:100,limit:64})",
),
evidence: definition(
{
summary:
"Page complete retained source or decoded graph Evidence with source/view identities and freshness checks.",
description:
"Read complete retained native source in UTF-16-code-unit pages by evidence_id; no reanalysis. component:source preserves exact original wire JSON. component:recovered_ir reads the decoded graph source, including lossless compressed graphs; source hash remains the original capture and view has its own hash/byte count. This is source inspection, not a claim that malformed graph facts are valid. Available until close_binary.",
},
{
evidence_id: z.string().startsWith("ev_"),
component: z.enum(["source", "recovered_ir"]).default("source"),
offset: page.offset,
limit: z.number().int().min(1).max(16384).default(4096),
},
"evidence",
"await rea.evidence({evidence_id:id,offset:0,limit:4096})",
),
};
methods.bytes.input = methods.bytes.input.superRefine((value, context) => {
// Pattern failures need not prevent object refinements from running in Zod.
// Only the named window contract may admit values to exact u64 arithmetic.
const windows = value.windows.flatMap((window) => {
const parsed = byteWindow.safeParse(window);
return parsed.success ? [parsed.data] : [];
});
if (
windows.reduce((sum, window) => sum + window.length, 0) >
MAX_BYTE_BATCH_BYTES
)
context.addIssue({
code: "custom",
path: ["windows"],
message:
"Select at most 64 KiB of bytes per batch; use additional windows/pages in later calls",
});
if (
windows.some(
(window) =>
BigInt(window.address) + BigInt(window.length) > 0xffffffffffffffffn,
)
)
context.addIssue({
code: "custom",
path: ["windows"],
message: "Byte range end exceeds the native u64 address format",
});
});
export const reference = createReference(methods);
-231
View File
@@ -1,231 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import Ajv2020 from "ajv/dist/2020.js";
import { methods, reference } from "./api.mjs";
import { AtomicSession } from "./session.mjs";
const factory = () => {
let sequence = 0;
const calls = [];
const create = async (path) => ({
context: { lease: `lease-${++sequence}`, selected_path: path },
close: async () => {
calls.push("close");
},
cancel: () => {
calls.push("cancel");
},
strings: async (input) => {
calls.push(input);
return { items: [], source: { evidence_id: "ev_real-owner" } };
},
});
return { create, calls };
};
test("path selectors agree in runtime and JSON Schema, without inferred target or string identities", () => {
const validate = new Ajv2020({ strict: false }).compile(
reference("path").methods[0].input_schema,
);
for (const [request, valid] of [
[{ from: 0, target: { kind: "exit" } }, true],
[
{
from: 0,
target: { kind: "block", id: 1 },
avoid: [2, 2],
offset: 1,
limit: 1,
},
true,
],
[{ from: "0", target: { kind: "exit" } }, false],
[{ from: 0, target: { kind: "block" } }, false],
[{ from: 0, target: { kind: "exit", id: 1 } }, false],
[{ from: 0, target: { kind: "exit" }, avoid: [-1] }, false],
[{ from: 0, target: { kind: "exit" }, limit: 129 }, false],
]) {
const input = { snapshot: "snap_test", ...request };
assert.equal(methods.path.input.safeParse(input).success, valid);
assert.equal(validate(input), valid, JSON.stringify(validate.errors));
}
});
test("relation identity and operand-only selectors agree in runtime and advertised schemas", () => {
const validate = new Ajv2020({ strict: false }).compile(
reference("relations").methods[0].input_schema,
);
for (const [request, valid] of [
[{ kind: "operands", seeds: ["0x1:0"], input_indices: [0, 155] }, true],
[{ kind: "operands", seeds: ["0x1:0"], input_indices: [] }, true],
[{ kind: "uses", seeds: ["0x1:0"] }, true],
[
{
kind: "cases",
seeds: ["0x1:0"],
case_values: ["0xffffffffffffffff"],
case_indices: [0, 155],
},
true,
],
[{ kind: "cases", seeds: [0] }, false],
[{ kind: "cases", seeds: ["0x1:0"], case_values: ["0X1"] }, false],
[{ kind: "incoming", seeds: [0] }, true],
[{ kind: "incoming", seeds: ["0"] }, false],
[{ kind: "operands", seeds: [0] }, false],
[{ kind: "uses", seeds: ["0x1:0"], input_indices: [0] }, false],
[{ kind: "operands", seeds: ["0x1:0"], input_indices: [-1] }, false],
]) {
const input = { snapshot: "snap_test", ...request };
assert.equal(methods.relations.input.safeParse(input).success, valid);
assert.equal(validate(input), valid, JSON.stringify(validate.errors));
}
});
test("named contracts reject extra keys and stale leases before provider admission", async () => {
const provider = factory();
const session = new AtomicSession(provider.create);
await session.open("first");
const lease = session.context.lease;
const invalid = await session.call("strings", { query: "x", guessed: true });
assert.equal(invalid.error.code, "invalid_input");
const wrongIdentity = await session.call("relations", {
snapshot: "snap_test",
kind: "incoming",
seeds: ["0"],
});
assert.equal(wrongIdentity.error.code, "invalid_input");
assert.equal(provider.calls.length, 0);
await session.open("second");
const stale = await session.call("strings", { query: "x" }, undefined, lease);
assert.equal(stale.error.code, "stale_context");
assert.deepEqual(provider.calls, ["close"]);
await session.close();
});
test("cancellation after a completed read retains observations under a cancelled outcome", async () => {
const controller = new AbortController();
const session = new AtomicSession(async () => ({
context: { lease: "late-cancel" },
close: async () => {},
strings: async () => {
controller.abort();
return {
source: { evidence_id: "ev_observed" },
items: [{ value: "retained" }],
};
},
}));
await session.open("target");
const result = await session.call(
"strings",
{ query: "x" },
controller.signal,
);
assert.equal(result.ok, false);
assert.equal(result.error.code, "cancelled");
assert.equal(
result.error.details.partial_observation.items[0].value,
"retained",
);
assert.equal(result.context.lease, "late-cancel");
await session.close();
});
test("close drains admitted reads and a failed cleanup retains ownership for retry", async () => {
let release;
let reads = 0;
let closes = 0;
const session = new AtomicSession(async () => ({
context: { lease: "owned" },
strings: () => {
reads++;
return new Promise((resolve) => {
release = resolve;
});
},
close: () => {
if (++closes === 1) throw new Error("cleanup failed");
},
cancel() {},
}));
await session.open("target");
const read = session.call("strings", { query: "x" });
await new Promise((resolve) => setImmediate(resolve));
const close = session.close();
assert.equal(closes, 0);
assert.equal(reads, 1);
release({ items: [] });
assert.equal((await read).ok, true);
await assert.rejects(close, /cleanup failed/u);
assert.equal(session.context.lease, "owned");
await session.close();
assert.equal(session.context, null);
});
for (const action of ["close", "replace"])
test(`failed open retains session file owners through ${action} and cleanup retry`, async () => {
let acquisitions = 0,
cleanupAttempts = 0,
releasable = false;
const primary = new Error(
"Engine inspection failed after acquiring a file",
);
const session = new AtomicSession(async (path, { fileResources }) => {
acquisitions++;
if (acquisitions === 1)
return fileResources.run(async () => {
fileResources.retain({
kind: "lease",
resource: "/selected/engine",
lease: {
release: async () => {
cleanupAttempts++;
if (!releasable) throw new Error("Descriptor remains open");
},
},
});
throw primary;
});
return {
context: { lease: "recovered", selected_path: path },
close: async () => {},
};
});
await assert.rejects(session.open("first"), (error) => error === primary);
assert.equal(session.context, null);
assert.equal(
(await session.call("strings", { query: "x" })).error.code,
"no_target",
);
const retry = () =>
action === "close" ? session.close() : session.open("second");
await assert.rejects(
retry(),
(error) =>
error.code === "cleanup_incomplete" &&
error.details.resources.length === 1 &&
error.details.resources[0] === "/selected/engine",
);
assert.equal(acquisitions, 1, "Unresolved owners block replacement");
assert.equal(cleanupAttempts, 1);
releasable = true;
assert.equal((await retry()).ok, true);
assert.equal(cleanupAttempts, 2);
if (action === "close") {
assert.equal(session.context, null);
assert.equal((await session.open("second")).ok, true);
}
assert.equal(acquisitions, 2);
assert.equal(session.context.lease, "recovered");
await session.close();
assert.equal(cleanupAttempts, 2, "Released owners are not retried");
});
test("cancellation before admission makes no provider query; advertised reference schemas compile", async () => {
const provider = factory();
const session = new AtomicSession(provider.create);
await session.open("target");
const stop = new AbortController();
stop.abort();
const cancelled = await session.call("strings", { query: "x" }, stop.signal);
assert.equal(cancelled.error.code, "cancelled");
assert.deepEqual(provider.calls, []);
const ajv = new Ajv2020({ strict: false });
for (const method of reference().methods) ajv.compile(method.input_schema);
await session.close();
});
@@ -1,53 +0,0 @@
# Calls and values surviving full-graph capacity
The question is `sqlite-boundary-question.txt`. Fix it and this acceptance oracle
before either real-model run. Both lanes use the same complete fourteen-method
API, preserved engine, model/effort request, common guidance and resource limits.
This task requires VM decompilation once per fresh lease; it is different work
from the earlier shallow-reference question. Do not compare their task times as
an adapter speedup. Actual client JavaScript dispatch is available in both lanes.
Artifact: Debian `libsqlite3-0:amd64` version `3.40.1-2+deb12u2`,
`libsqlite3.so.0.8.6`, SHA-256
`2e6eef9a727f081f0d453b4e5e6cbd8b9ef8b6f86cbf7681cbad444d3b0b55c8`.
The selected VM implementation entry is `0xea6d0`, not its same-name PLT entry.
Pre-model public MCP capture with the new exporter establishes:
- Code is available. Full graph is unavailable with `atomic operation capacity
exceeded`. Calls remain available: 416 retained block-member operations,
consisting of 395 CALL and 21 CALLIND. The 395 direct targets are known, all
21 indirect targets remain unknown. Call-boundary values are available (1,294),
covering targets, arguments and outputs only, with 21,349 operations scanned
over 1,229 recovered blocks. These do not supply a complete definition/use graph.
- At `0xf115c`, recovered call ID `0xf115c:6a84` targets `ram:0x296c0`.
Input zero is `v1000118d6`, `fspec:0x102f4`, annotation true, width 8.
Three recovered inputs use passing storage `register:0x38/8`, `0x30/8`,
`0x10/8` (RDI, RSI, RDX in this verified x86-64 lane).
- At `0xf238b`, call ID `0xf238b:7130` has the same resolved target.
Input zero is `v100012a80`, `fspec:0x1030c`, annotation true, width 8.
Two recovered inputs use passing storage `register:0x38/8`, `0x30/8`.
- Both first arguments are the same snapshot-local SSA value `v30000004b`,
`register:0x38/8`, `is_input:true`, definition null. Other retained argument
values have defining operation IDs outside this boundary view. Exact SSA
identity is supported; source parameter ordinals and general aliases are not.
Independent GNU objdump decoding from the exported VM entry verifies the two
machine CALL targets and register setup. The earlier complete direct-call pair
oracle contains both. Of the 396 physical direct immediate calls, the only one
absent from the recovered 395 is `0xf2493 -> 0x29370` (stack check failure).
The question does not require rediscovering this extra call; the recovered-call
count must not be claimed as complete machine/runtime coverage.
Required final facts: correct selected entry and facet availability/scope; both
call-count groups and target-unknown distinction; both resolved targets separated
from annotation offsets; argument slots/locations; shared first-input identity;
selected machine checks; explicit unreadable definition/use and alias/runtime
limits; real Evidence and subject digest. Do not require the model to report
every additional native metadata counter. Check that its API source arguments
show only one VM analysis and all relevant reads reuse its snapshot/Evidence.
Raw public verification is retained as `facets-v3-mcp.json` and its Evidence
directory under `.cache/atomic-codemode/`. The ordinary VM record (C, mappings,
variables and other ordinary metadata) equals the prior captured engine output.
The independent oracle and precomputed answer are absent from the model workspace.
@@ -1,26 +0,0 @@
# Frozen shared-byte model task
Use the unchanged `native-string-query-question.txt` and all exact target/string/
byte facts in `native-string-query-oracle.md`. The target digest and 4+1 string
objects are unchanged. This phase's pinned engine is `bce4dc97fda99a028aca6b2b40a0a593c87b5224ac9e03221a69313faba2d3e8`,
with both `REA_ATOMIC_NATIVE_STRING_QUERY=1` and `REA_ATOMIC_NATIVE_BYTE_BATCH=1`.
The earlier oracle's engine digest describes its earlier frozen runtime only.
Both query reports remain distinct and each covers 602,544 candidates. A native
byte report may now contain several requested windows with one shared source ID;
source_row identifies a native window row, not the caller's ordinal after reuse.
Repeated or reordered ranges may refer to the same original row. Fewer distinct
byte Evidence IDs are valid when the cited source actually covers every claimed
window. Counts/hex and provenance must remain exact. Focused covering reads are
still allowed. Do not require ten commands or unique source IDs per window.
Grade complete original answers, all cited source hashes/contexts, raw byte
payloads and actual source-window reads. Keep failed calls and all costs, with no
answer repair or winning retry. Direct and Code Mode use the same 19 methods,
question, model/reasoning, static authority and resource controls; actual Code
Mode MCP execution must be observed. Report cumulative tokens, cached/uncached
input, output/reasoning, schemas/help/calls/retries, wall, local CPU and kernel
family peak. Actual clients have common JavaScript dispatch. Remote costs and
resolved model builds are unmeasured. One run per lane does not establish broad
RE superiority; historical model results use a different pinned runtime, while
the SDK acquisition-toggle comparison uses the same current engine and code.
@@ -1,99 +0,0 @@
# Shared native byte reads: checkpoint
The user cleared the active goal after implementation and real preflight.
Work stopped before new model trials. No PR or merge into main is requested.
Main was refreshed to `5112fe07a` in `2dc3820b6`. LeanToken returned not_indexed
for this experimental path; scoped native reads were used instead.
Opt in with `REA_ATOMIC_NATIVE_BYTE_BATCH=1` and an exact experimental native
engine pin. Unset/0 preserves single-window acquisition. The 19 shared methods,
22 Direct tools and four Code Mode tools are unchanged. The byte batch reads
only selected static loaded-image ranges; no target execution or modification.
`disassemble/kuna_batch.rs` shares one existing ConsoleProgram load, range
resolution, mapped-end clipping and data renderer across at most 16 windows /
64 KiB selected bytes. It rejects ignored options and bounds encoded output
against the existing 8 MiB capture ceiling. Each native row retains its exact
request, ordinal and success or window_unavailable error. Global load or report
encoding failure fails explicitly. The old read path can initialize again when
a bounded anonymous region lacks a name; this is source-derived reasoning, not
a measured count of internal translator initialization.
`NativeByteBatchReads` caches validated exact address/length facts for this target
lease, deduplicates missing ranges, batches only missing work and preserves caller
order. Source + source_row identify a window in retained raw Evidence; duplicates
or reordered calls can share that row. Partial reads remain partial. Successful
siblings survive bad per-row data; global failures preserve cached facts. Transient
capture failures are not cached here. Close clears the cache. Its retained entries
are bounded by source admission (128 sources times at most 16 windows); no global
cache or live-memory freshness claim is added.
Old and new byte reports use one normalization owner. Exact JSON numeric tokens
preserve u64 aliases and reject rounded fractional counters, with shared KunaJson
support; alias disagreements fail instead of publishing contradictory facts.
Original-file mapping and runtime memory remain unknown/not-observed.
## Executed evidence
- Native disassemble tests: 15 passed, including the two new protocol/budget tests.
- Runtime build passed; final experimental JS tests: 128 passed.
- Kuna reference files/ranges boundary tests: 27 passed.
- Changed-file lint/format, module boundaries, affected-source typecheck and
converted actual MCP schema/catalog checks passed.
- Real SDK, Direct and Code Mode LLVM checks passed all prior five literal-query
goldens, paging, projection, exact ten independent byte windows and 13 complete
retained source hashes per lane.
- Both actual MCP adapters passed SQLite mixed success/error, short reads,
repeated exact windows and the full 64 KiB request.
- Same-engine SDK comparison passed reordered/duplicate reuse, mixed cached/new
windows, all raw hashes and stale Evidence rejection after reopen.
- Actual producer cancellation preserved cached facts in partial_observation,
allowed a fresh retry and completed owned cleanup. Target bytes were unchanged.
The existing full repository typecheck memory refusal is not a pass. No full
check:fast/check:pr, full native workspace gate, new architecture/provider parity,
or new real-model result is claimed for this phase. Earlier model outcomes retain
their own immutable revisions. The prepared byte-batch oracle is unexecuted by models.
## Same-engine acquisition comparison
Both runs use engine `bce4dc97fda99a028aca6b2b40a0a593c87b5224ac9e03221a69313faba2d3e8`, the same LLVM artifact and independent
file oracle. Only acquisition is toggled between 0 and 1. Cold means a new lease,
not dropped OS caches. These are single scripted observations with no model tokens.
| Phase | Single-window ms / CPU s | Batched ms / CPU s |
| --------------------------- | -----------------------: | ------------------: |
| cold_ten_windows | 94269.834 / 94.110456 | 8505.789 / 8.488729 |
| warm_reordered_duplicates | 2.598 / 0.002657 | 10.494 / 0.010407 |
| mixed_cached_and_new_window | 6385.777 / 6.374731 | 6446.780 / 6.438594 |
Cold ten-window retrieval drops from about 94.3 to 8.5 seconds. The warm sample
is slower in the batch run; it is retained without claiming a warm speedup.
New unseen windows still incur program initialization. The old workflow retains
11 native sources for the completed task; batching retains two.
| Whole task | Wall s | Local family CPU s | Kernel family peak MiB |
| ------------ | ------: | -----------------: | ---------------------: |
| before | 102.304 | 101.898599 | 861.9 |
| after | 16.533 | 16.327818 | 858.1 |
| cancellation | 15.324 | 15.107833 | 862.8 |
Counters are verified at payload exit while the observer lives, not final whole-
scope counters. Memory includes charged file cache. Heavy work was serial, one
CPU, hard 4 GiB/no swap, with early stopping at 3 GiB (3.25 GiB for builds).
The first compiled native version was replaced before real provider verification
to distinguish request_address_hex from numeric native address aliases; original
builds/logs remain. No failed run was relabeled as passing.
## Reproduction anchors
The canonical native patch targets Kuna `fe01d6294eb0d1053ce343c8943646df88e143fc`.
Binaries, captures and explicit provider settings remain ignored. Source patch
SHA-256: `56d2cd197bfcab9566c055c32ee0aece4805c7708f0a0117a8fa06a768969055`.
- `native-byte-batch-before-v1.json`: `ec7c9ab21ef91ff6f965d8e6efc9da97c4a6593d19fde660ba5cb2b1c4459dcb`.
- `native-byte-batch-after-v1.json`: `9737291a03ad7c12700bf124134c4c06d4ef5beb8c31dda102eaa5ae0752aa47`.
- `native-byte-batch-cancellation-v1.json`: `6dd58baed164df0747573b143c31f01d12d5d697ca7c3ff4813b545c355d0d18`.
- `native-byte-batch-llvm-sdk-v1.json`: `04d2ee586f376c41d86d1e9c4508c6b84fcb04d71b7ce2aab6b2580169367a1e`.
- `native-byte-batch-llvm-direct-v1.json`: `53be8d5e5ce0f70d015be98d7ac0b500702fb414bd7a0b41be023a660717eff0`.
- `native-byte-batch-llvm-codemode-v1.json`: `d94e171953fcc86a09b38e730564fae0d42068e1d2ac59b5547bd3c4837d5d42`.
-141
View File
@@ -1,141 +0,0 @@
// Native loaded-image data is not instruction decoding or original-file mapping.
import { z } from "zod";
import { FactFailure } from "./fact-error.mjs";
import { MAX_BYTE_BATCH_BYTES, NATIVE_OUTPUT_BYTES } from "./limits.mjs";
import { parseKunaJson } from "../../dist/kuna/KunaJson.js";
const hex = z.string().regex(/^0x(?:0|[1-9a-f][0-9a-f]{0,15})$/u);
const payload = z.string().regex(/^(?:[0-9a-f]{2})*$/u);
const header = z.object({
binary: z.string(),
kind: z.literal("data"),
start_hex: hex,
end_hex: hex,
start: hex.optional(),
end: hex.optional(),
target: z.object({ address: hex, address_hex: hex }).optional(),
count: z
.number()
.int()
.nonnegative()
.max(MAX_BYTE_BATCH_BYTES / 16),
bytes: z.number().int().nonnegative().max(MAX_BYTE_BATCH_BYTES),
hex: payload,
truncated: z.boolean(),
notes: z.array(z.string()),
});
const row = z.object({
address: hex.optional(),
address_hex: hex,
size: z.number().int().min(1).max(16),
bytes: payload,
});
const requireFact = (valid, message) => {
if (!valid) throw new FactFailure("invalid_provider_output", message);
};
export function parseByteFacts(text, inputPath, request) {
try {
requireFact(
Buffer.byteLength(text) <= NATIVE_OUTPUT_BYTES,
"Byte source exceeds capture capacity",
);
return normalizeByteFacts(parseByteSourceJson(text), inputPath, request);
} catch (error) {
throw byteFailure(error);
}
}
export function parseByteSourceJson(text, integerKeys = []) {
return parseKunaJson(
text,
NATIVE_OUTPUT_BYTES,
new Set(["start", "end", "address"]),
new Set(["count", "bytes", "size", ...integerKeys]),
);
}
export function normalizeByteFacts(raw, inputPath, request) {
try {
requireFact(
Array.isArray(raw?.rows) && raw.rows.length <= MAX_BYTE_BATCH_BYTES / 16,
"Byte rows exceed capacity or have invalid shape",
);
const doc = header.parse(raw);
requireFact(
(doc.start === undefined || doc.start === doc.start_hex) &&
(doc.end === undefined || doc.end === doc.end_hex) &&
(doc.target === undefined ||
(doc.target.address === doc.start_hex &&
doc.target.address_hex === doc.start_hex)),
"Byte address aliases disagree",
);
requireFact(
doc.binary === inputPath && doc.start_hex === request.address,
"Byte source names a different target/window",
);
requireFact(
doc.bytes <= request.length && doc.count === raw.rows.length,
"Byte source exceeds the request or disagrees with row count",
);
let end = BigInt(request.address);
const pieces = raw.rows.map((value, index) => {
const item = row.parse(value);
requireFact(
item.address === undefined || item.address === item.address_hex,
"Byte row address aliases disagree",
);
requireFact(
BigInt(item.address_hex) === end && item.bytes.length === item.size * 2,
"Byte row address/length is inconsistent",
);
requireFact(
index === raw.rows.length - 1 || item.size === 16,
"Nonfinal byte row is not the declared native width",
);
end += BigInt(item.size);
return item.bytes;
});
requireFact(
end === BigInt(doc.end_hex) &&
end - BigInt(request.address) === BigInt(doc.bytes) &&
pieces.join("") === doc.hex &&
doc.hex.length === doc.bytes * 2,
"Byte rows, payload and extent disagree",
);
return {
hex: doc.hex,
returned_bytes: doc.bytes,
end_address: doc.end_hex,
coverage: {
authority: "native loaded-image bytes",
requested_bytes: request.length,
status:
doc.bytes === request.length
? "complete-for-requested-range"
: "partial",
provider_truncated: doc.truncated,
notes: doc.notes,
original_file_mapping: "unknown",
runtime_memory: "not-observed",
},
};
} catch (error) {
throw byteFailure(error);
}
}
function byteFailure(error) {
return error instanceof FactFailure
? error
: new FactFailure(
"invalid_provider_output",
"Native byte window does not match the declared format",
{
reason:
error instanceof z.ZodError
? error.issues[0]?.message.slice(0, 256)
: String(error.message).slice(0, 256),
},
);
}
@@ -1,128 +0,0 @@
import test from "node:test";
import assert from "node:assert/strict";
import { parseByteFacts } from "./byte-facts.mjs";
import { AtomicSession } from "./session.mjs";
const make = () => ({
binary: "/input",
kind: "data",
start_hex: "0x20000000000001",
end_hex: "0x20000000000005",
count: 1,
bytes: 4,
hex: "00417fff",
truncated: false,
notes: [],
rows: [
{
address_hex: "0x20000000000001",
size: 4,
bytes: "00417fff",
},
],
});
const request = { address: "0x20000000000001", length: 4 };
test("byte facts keep exact u64 extents, null/nontext bytes and loaded-image authority", () => {
const facts = parseByteFacts(JSON.stringify(make()), "/input", request);
assert.equal(facts.hex, "00417fff");
assert.equal(facts.end_address, "0x20000000000005");
assert.equal(facts.coverage.status, "complete-for-requested-range");
assert.equal(facts.coverage.original_file_mapping, "unknown");
assert.equal(facts.coverage.runtime_memory, "not-observed");
const clipped = parseByteFacts(JSON.stringify(make()), "/input", {
...request,
length: 5,
});
assert.equal(clipped.coverage.status, "partial");
const flagged = make();
flagged.truncated = true;
assert.equal(
parseByteFacts(JSON.stringify(flagged), "/input", request).coverage.status,
"complete-for-requested-range",
);
});
test("wrong byte subject, contradictory duplicated payload, gaps and counts fail before publishing facts", () => {
for (const mutate of [
(d) => (d.binary = "/other"),
(d) => (d.kind = "code"),
(d) => (d.hex = "00417f00"),
(d) => (d.rows[0].address_hex = "0x20000000000000"),
(d) => (d.rows[0].size = 3),
(d) => (d.end_hex = "0x20000000000006"),
(d) => (d.count = 2),
(d) => (d.rows = Array(4097).fill(null)),
]) {
const document = make();
mutate(document);
assert.throws(
() => parseByteFacts(JSON.stringify(document), "/input", request),
{ code: "invalid_provider_output" },
);
}
const empty = make();
Object.assign(empty, {
hex: "",
rows: [],
count: 0,
bytes: 0,
end_hex: request.address,
});
assert.equal(
parseByteFacts(JSON.stringify(empty), "/input", request).coverage.status,
"partial",
);
});
test("byte input capacity, malformed addresses and u64 end overflow reject before native admission", async () => {
let reads = 0;
const session = new AtomicSession(async () => ({
context: { lease: "bytes" },
bytes: () => {
reads += 1;
},
close: () => {},
}));
await session.open("/input");
try {
for (const windows of [
[{ address: "invalid", length: 1 }],
[{ address: "0xffffffffffffffff", length: 1 }],
[
{ address: "0x1000", length: 65536 },
{ address: "0x2000", length: 1 },
],
[{ address: "0x1000", length: 0 }],
]) {
const result = await session.call("bytes", { windows });
assert.equal(result.error.code, "invalid_input", JSON.stringify(result));
}
assert.equal(reads, 0);
} finally {
await session.close();
}
});
test("byte aliases and kept counters are validated from exact numeric source tokens", () => {
const raw = JSON.stringify({
...make(),
start: "9007199254740993",
end: "9007199254740997",
target: { address: "9007199254740993", address_hex: request.address },
rows: [{ ...make().rows[0], address: "9007199254740993" }],
})
.replaceAll('"9007199254740993"', "9007199254740993")
.replaceAll('"9007199254740997"', "9007199254740997");
assert.equal(parseByteFacts(raw, "/input", request).returned_bytes, 4);
for (const invalid of [
raw.replace('"count":1', '"count":1.0000000000000000001'),
raw.replace('"bytes":4', '"bytes":4e0'),
raw.replace('"size":4', '"size":4.0000000000000000001'),
raw.replace('"start":9007199254740993', '"start":9007199254740992'),
raw.replace('"end":9007199254740997', '"end":9007199254740996'),
raw.replace('"address":9007199254740993', '"address":9007199254740992'),
])
assert.throws(() => parseByteFacts(invalid, "/input", request), {
code: "invalid_provider_output",
});
});
@@ -1,64 +0,0 @@
# Cross-function context experiment: pinned question and oracle
This is an experiment acceptance oracle, unavailable to the isolated model.
The question is `sqlite-call-question.txt`. Fix this question and the required
facts before launching either model lane. Both adapters expose the same complete
fourteen-method fact API; Code Mode has four MCP tools, direct has seventeen.
Use the same pinned engine, artifact, model request, reasoning effort, common
envelope guidance, fresh target leases and resource limits. Do not change runtime
sources or HEAD during the model batch. One sample per lane cannot establish a
general advantage, and the client itself already offers JavaScript dispatch in
both lanes. This comparison isolates the server calling adapter, not all forms of
composition or a traditional provider workflow.
The artifact is the local Debian ELF `libsqlite3.so.0.8.6`, SHA-256
`2e6eef9a727f081f0d453b4e5e6cbd8b9ef8b6f86cbf7681cbad444d3b0b55c8`.
Independent GNU objdump decoding from the function entries covers `0x64060`
through `0x65400`; existing earlier captures independently pin the same flow.
No target execution or source-code answer is used.
Required facts for an equal completed answer:
- Wrapper entry `0x65180`; direct machine CALL `0x65211` targets internal helper
`0x64060`. The recovered call operation has an fspec annotation as input zero;
that annotation's offset is not the target address.
- Caller LEA `0x65201` passes post-prologue `RSP+0x20` in RDI. Structured passing
storage is `register:0x38`, width 8. The SSA argument and the callee's retained
input are separate snapshot-local identities; matching their storage supplies a
candidate connection. The direct machine transfer and pointer setup support
this particular connection. Do not globally infer source parameter ordinal,
alias completeness or runtime binding from a slot number or a name.
- The helper preserves the input context pointer in RBP. Its 32-bit field at
context offset `0x30` is incremented at `0x64693`/`0x64696`/`0x64699` for an
opening parenthesis and decremented at `0x64c92` for a closing parenthesis.
The parser's token/branch context must support the parenthesis interpretation;
an ADD/SUB instruction alone does not identify the meaning of a field.
- In the wrapper this is `[RSP+0x50]`, initialized to zero with the other context
tail fields. After helper return zero, LOAD `0x65268` and TEST/JZ
`0x65270`/`0x65272` check it. Zero skips the malformed block; nonzero frees the
expression at `0x65274`, clears its output pointer at `0x65279`, then reaches
the malformed diagnostic at `0x65281` through formatter call `0x65290`.
- Return-code-one errors can also reach the malformed block, via
`0x65239`/`0x6523c`; return code 18 selects a separate depth-limit diagnostic
at `0x65330`. No demonstrated runtime-feasibility or full memory-alias claim.
The producer verifier additionally checks two formatter call targets:
`0x5f031 -> 0x2adc0` (free PLT) and `0x5f062 -> 0x27e50` (vmprintf PLT), whereas
their input-zero fspec offsets are `0x10000`/`0x10001`. Resolving these PLT entries
to runtime implementations is outside this task.
Native producer fidelity is checked against previously retained captures of all
three functions: C, ordinary metadata/line mappings, blocks, operations, values
and coverage are identical. Only schema version and structured call records are
added. Older sources used pretty JSON; their smaller/newer encoded sizes must
not be attributed to the call exporter. The earlier compact-writer change is a
separate experiment. Unsupported old schema graphs remain unavailable with valid
C retained, rather than acquiring guessed call records.
The first paired question runs at `01e5c5955` both explain the primary state flow
correctly but omit the oracle's separate return-1/return-18 distinctions. Because
the initial question did not explicitly enumerate those codes, the next round
clarifies that requirement in `sqlite-call-question.txt` before either lane
starts. The required facts and independent oracle stay unchanged. Earlier
questions and costs remain pinned to their original commits; neither incomplete
sample is counted as a full-oracle success.
@@ -1,141 +0,0 @@
# Capability and comparison scope
The experiment has nineteen fact methods behind a shared SDK/CLI owner, exposed
as twenty-two direct MCP tools or four Code Mode tools. The structured IR/call/
projection/switch facts require the explicitly pinned experimental Kuna patch;
they are not capabilities added to stock Kuna or integrated REA by registration
alone. Other providers are not wired to this experimental service.
A fair completed-task comparison first needs sufficient facts on both paths,
with a common correctness oracle. A complete universal RE interface is not
established here. The selected-case question requires native row/edge identities,
so it compares the two atomic adapters; no traditional-provider result for that
question is invented. Earlier traditional comparisons retain their own questions,
engine profiles and limitations in [the trial record](trials.md).
| Analyst question | Composable facts/relations | Executed evidence and limits |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Which implementation owns an observed message? | Callable entries/aliases, encoded strings, exact-address xrefs with occurrence identity and function attribution | Both recent SQLite tasks select the owner before capture. Name equality alone is insufficient; discovery/unattributed coverage remains explicit. |
| Which local condition controls a selected value/call? | Snapshot-local operations, SSA values, indexed operands, definitions/uses with PHI predecessor edges, recovered CFG edges | [Four real control-task runs](savepoint-control-study.md) verify the selected guards and machine instructions. [Full graph transport checks](native-graph-transport-study.md) establish producer fidelity, not global machine equivalence. |
| What crosses a call boundary? | Native call specifications, argument values and separate passing storage; selected callee inputs and bounded definition projections | Earlier pinned [call/boundary trials](trials.md) exercise these relations. Storage matches are candidates, not proof of runtime binding or complete ABI/memory effects; a new exporter hash alone is not a repeated cross-function model trial. |
| Which cases map to a recovered edge? | Original case identity/label/address, independent native default, flattened case/out-edge relations | [All 182 SQLite original targets](switch-study.md) match independent ELF table bytes. Four real models answer selected cases and distinguish the native default from the machine range guard. No complete case inventory is needed in model context. |
| What machine bytes support the interpretation? | Batched loaded-image bytes and selected linear instruction windows, each with source/coverage | The case models independently derive signed relative targets. These windows do not establish runtime execution/alignment, a complete machine CFG, live memory or arbitrary file-offset mappings. |
| Can the answer be audited without returning the report? | Snapshot/source identity, selected fields, batch reads, paging and retained raw/decoded Evidence | Real CLI/MCP checks verify source access and capacity fallbacks. Scope/partial/unknown survive composition; a guest-derived answer keeps its own authority. |
The [string-span experiment](string-span-study.md) extends exact xrefs with
batched incoming target-coordinate spans. It preserves all eleven selected
SQLite data occurrences, including nine pooled suffix pointers, with individual
endpoints/owners and raw source rows. Kuna already had aggregate string-span
counts; the new occurrence query shares its sparse index. Range membership alone
does not establish whole-string use, access overlap or runtime behavior.
Three real models complete the pooled-string task. The traditional original
inventory has a partial source audit after client truncation; atomic source
captures are fully checked. Code Mode's cumulative input/time improve in this
sample, while uncached input and memory exceed Direct. This remains task evidence,
not provider parity or a stable adapter advantage.
The useful grain so far is an identified object plus a relation with its exact
qualifiers: an operand needs its slot and PHI binding; a case/out-edge pair needs
both identities; an address needs its artifact/address space; an optimized
operation needs its snapshot and representation. One small JSON row is not
automatically one independently meaningful fact. Machine instructions and
normalized operations also cannot substitute for each other.
An identified object may still contain a huge field. The [capacity study](large-result-study.md)
adds string metadata selection and pre-allocation transport accounting with
recoverable source handles. Real SDK/MCP checks cover both escaping layers and
in-program recovery. In the frozen model pair, Code Mode passes; Direct reports
17-byte prefixes as 16 despite correct provider data. Preserve that failure;
the pair cannot rank efficiency at matched correctness. Native capture still
reads the complete bounded inventory, so small replies alone do not establish
scalable producer work. The [streamed inventory experiment](streamed-inventory-study.md)
restores FFmpeg queries over a 16.8 MB source with bounded files and the production
parser. Both corrected real-model answers pass with all sources checked; setup
failures remain in the ledger. Costs are mixed, and LLVM/Node still exceed the
unchanged 64 MiB retained-source ceiling.
Selection, projection, batching, paging and bounded traversal compose those
facts. The analysis owner derives/validates relations; Code Mode selects and
combines them. A query can be fine-grained even when its fresh native capture
still computes a whole function. Same-lease reuse is measured separately from
that work and does not establish a cross-session cache or native acceleration.
The [control-query study](control-query-study.md) independently verifies all
2,845 control-dependence triples in the real SQLite VM through both MCP adapters.
Two real models also complete a two-level controller/SSA/path-witness task and
distinguish alternative predicates from conjunction. Unknown CFG seeds are
explicit, and the snapshot owner reuses a bounded lazy postdominator index.
Code Mode has lower cumulative input but higher uncached input and runtime costs
in that pair; precise derived facts do not imply a preferred calling adapter.
The [OpenSSH value-query study](value-query-study.md) adds exact location lookup
and inverse operand occurrences for value identities, including inputs/constants
without definitions. It checks every retained selected version/use against the
complete source graph; this is separate from machine-byte evidence and does not
turn SSA occurrences into a memory-alias proof.
The [stripped OpenSSH model comparison](ssh-warning-study.md) also verifies a
common warning/caller/stack/guard question through the two atomic adapters and
the traditional Kuna workflow. Exact machine facts suffice for the direct
answer; extra SSA capture is not required by every RE question. The corrected
traditional baseline has its complete declared native toolset. This expands
the completed-task evidence while retaining the local scope and cost confounds.
Memory alias dependencies, full machine-flow recovery, indirect runtime binding,
feasible paths and nontermination remain unknown. The current evidence does
not establish provider parity, broad complex-software superiority or a stable
Code Mode cost advantage. The [wait repeat](client-wait-study.md) shows why fewer
MCP requests or polls cannot replace correct answers and whole-task costs.
The [path query](path-query-study.md) composes selected recovered edges into one
paged witness under explicit exclusions, with zero-edge/not-found/unknown
outcomes. Both real SQLite MCP lanes preserve every original edge field; complete
native function fidelity is checked. This removes an observed graph-reading
burden without establishing feasible runtime paths or an adapter cost advantage.
The completed path-query pair answers the unchanged two-level task correctly in
both actual models; each uses four path reads and three selected block reads,
without a complete graph inventory in model context. Direct and Code Mode have
similar wall time with mixed token/resource costs. Stock 1.833 explicitly rejects
the unsupported path query while preserving readable Evidence/code in a real SDK
check. These are scoped observations, not stock-provider parity or complete
runtime reachability coverage.
The [function-boundary study](function-boundary-study.md) adds independent native
prototype entries/return descriptors. On real stripped SSH, prototype counts
4/10 differ from raw input counts 3/44; both actual models preserve that distinction,
all exact matches/missing tuples and the selected caller-to-callee/helper transfer.
Call-passing storage is separate from the caller value's own coordinate. Native
model labels and recovered entries do not prove original source arity/ABI.
Complete old function fidelity is preserved except for the new facet. Actual
old-native/stock checks return explicit unavailability with readable Evidence.
The two completed model tasks have mixed token/time/resource costs; no stable
Code Mode advantage or provider parity follows.
The [storage study](storage-study.md) exposes native address-space descriptors
and exact varnode_xref names without function decompilation. Width-qualified
coordinates compose with prototype/value/passing-storage facts. Real x86-64
and AArch64 OpenSSH catalog checks do not establish big-endian, alias, runtime
or full provider parity coverage.
Both real models complete the extended native storage/prototype/call task.
Code Mode reduces cumulative/uncached input and wall time in that pair but uses
more local CPU and more inner fact reads. The shared metadata capability is
verified separately from this adapter observation; earlier mixed pairs remain.
The [AArch64 reference study](aarch64-xref-study.md) corrects an observed native
ADRP+ADD/LOAD/STORE gap through the shared PC-relative value owner. Real arm64
SSH checks verify both warning owners, callers, selected machine words and
77 GOT-slot reads. Coverage stays bounded and does not propagate live GOT
contents. Traditional C/assembly preflight can answer the same new behavior-level
question, avoiding a baseline missing necessary facts. All three real models
complete it, while token/time/resource tradeoffs remain mixed. That pinned run
preserves the recovered no-return disagreement and uses machine facts for the
post-call path.
The [return-coverage study](aarch64-return-study.md) fixes the BTI entry split
and a separate false no-return promotion through the native owners. The fresh
three-way task passes with the strict call restored in both atomic captures;
their complete selected function documents agree. Direct has lower input,
time and CPU than Code Mode in this sample. Memory, analysis-profile differences,
the common client executor and n=1 sampling prevent a universal adapter claim.
@@ -1,132 +0,0 @@
# Reuse proven native source refusals
After the streamed-inventory model pair, main was fetched again and remained
`150e996a8`. Baseline runtime is `b88c75df8`. Native engine remains
`2e398e7229e30b6d2387a802db8a0050764119a6b457020d334855e36e69d6c5`.
This is an experimental follow-up, with no PR or integration into main.
## Observed redundant work
Two identical real LLVM string queries in one target lease first hit the 64 MiB
source ceiling after 8.363 seconds. The second still runs native analysis for
3.024 seconds / 3.021736 CPU seconds, retaining another partial prefix and
reporting cleanup uncertainty. The provider discarded every failed work entry,
even a proven output-size refusal for the identical immutable native capture.
The source budget cannot grow within that lease. Neither query produces valid
string facts; absence must remain unknown.
The same two-request probe after the change takes 7.603 seconds for the first
refusal and 1.528 ms / 0.001567 CPU seconds for reuse. Only one partial source is
captured, with the same readable Evidence handle on both errors. The added
`cached_observation:{kind:"source_budget_refusal",scope:"target_lease"}` labels
the original observation being reused; it does not report a fresh native run or
current process status. Cold-time variation is not a causal speed claim.
| Same two-request diagnostic probe | Wall s | Local family CPU s | Kernel family peak MiB |
| --------------------------------- | -----: | -----------------: | ---------------------: |
| Before | 12.406 | 12.192070 | 1,745.6 |
| After | 8.579 | 8.364375 | 1,492.5 |
This compares the same diagnostic intent, not successful LLVM analysis. The
second original attempt adds a cleanup-uncertainty failure, whereas reuse keeps
the original proven resource refusal without starting another process. Different
cold costs and transient ownership observations prevent a pure latency ratio or
general memory/speedup claim. The decisive signal is avoided native work.
## Cache ownership and invalidation
`NativeCaptureCache` owns pending/completed native work in one provider lease.
It replaces the old map wrapper. It retains a refusal only for the understood
`FactFailure` resource code, native-source scope, positive safe byte limit and
observed lower bound above that limit, with a retained partial source ID and
only the six understood refusal fields. Secondary file-cleanup uncertainty and
unexamined metadata also prevent reuse. Classification copies own data properties without
invoking getters; unknown/primitive failures retain their original identity.
Cancellation, I/O, cleanup uncertainty, other resources and unproven constraints
remain uncached. The cache never turns an unknown primary cleanup outcome into
resource success. Error views are separate from the immutable retained refusal,
so editing an SDK error cannot alter later Evidence IDs or limits. At most the
existing 128-source policy's number of work entries is memoized. When that table
is full, new producer results still return without adding retention; the shared
application owner continues to bound native admission. This also bounds any future source/key aliases. No additional source budget is introduced.
Keys keep the existing native request inputs, with target/engine/profile fixed
by the owner instance. Catalog selectors do not change native capture arguments.
Cache validity follows the immutable artifact capture and nonincreasing source
budget, not live state. Successful captures retain the previous reuse semantics;
close clears the cache after confirmed resource cleanup. A new lease gets a new
owner. No cross-session negative cache is claimed.
## Actual adapters, failures and verification scope
Real LLVM SDK and Direct MCP checks pass refusal reuse, unchanged target/lease,
identical refusal details except the explicit reuse label, one raw source,
readable partial Evidence and exact full raw digest. SDK warm latency is 2.282 ms
/ 0.001675 CPU seconds; Direct is 6.412 ms / 0.005566 CPU seconds. Their fresh
first calls take 7.350 / 7.756 seconds respectively.
The first scripted Code Mode check fails its cache-hit precondition because the
first call reports `cleanup_incomplete`. It correctly does not reuse that
uncertain failure, and the second native attempt takes about 2.905 seconds.
Both partial raw captures independently validate target/engine/hash/length. The
original verifier recorded phases/stack but placed the complete API observation
after its assertions, so the failed API payload is not fully auditable. Preserve
that limitation and the original failed receipt; do not relabel it a pass.
The verifier now records replies before assertions and stops if cleanup is
uncertain. One fresh scripted coverage repeat then reaches the proven-refusal
path. In one actual MCP execution, the guest calls strings twice and Evidence
once: the second call is 3 ms by guest `Date.now` (millisecond precision, separate
warm CPU unmeasured), with the same handle and exactly one raw source. The full
8.126-second program uses 8.119767 local CPU seconds. The two error results remain
errors; successful composition does not establish successful LLVM analysis.
This is a scripted coverage repeat after a verifier correction, not another
model answer or a replacement for the failed observation.
| Whole verifier | Wall s | Local family CPU s | Kernel family peak MiB | Result |
| ---------------------------------------- | -----: | -----------------: | ---------------------: | ---------------------------------- |
| SDK refusal + reuse + Evidence | 9.092 | 8.908659 | 1,516.8 | pass |
| Direct MCP same task | 9.886 | 9.666791 | 1,635.9 | pass |
| First Code Mode attempt | 12.909 | 12.680445 | 1,939.9 | cache-hit precondition unavailable |
| Corrected Code Mode coverage repeat | 10.088 | 9.885309 | 1,698.8 | pass |
| Capacity + partial source + cancellation | 9.885 | 9.632806 | 1,487.4 | pass |
Both Code Mode attempts cost 22.997 family-wall seconds / 22.565754 CPU seconds;
peak across them is 1,939.9 MiB, not the sum of peaks. These receipts are not a
matched adapter performance ranking: verifier work and failure paths differ.
All are one-CPU, 3 GiB early-stop / 4 GiB hard-limit, no-swap runs; payload-exit
observers verify cleanup and OOM=0, including the failed attempt. Final exited-
cgroup counters are unavailable. Kernel family memory includes file cache.
All 116 experimental JS tests pass, including in-flight reuse, invalidation,
mutable caller views, zero/false/null/unknown errors, noncacheable cleanup,
accessor avoidance and bounded memo admission. Real FFmpeg selected facts,
Evidence, bytes and stale-handle checks pass in SDK/Direct/Code Mode after the
cache change. Cancellation/owned cleanup checks pass. Changed-file lint and
format checks pass. After tightening the sealed-source/secondary-cleanup eligibility guard, the full
116-test suite passes again, and captured SDK/Direct/Code Mode refusal DTOs all
pass through that sealed contract in replay. That replay is a production-boundary
check, not another live-provider or model run. Existing full-suite/resource-gate
limitations from the
[streaming study](streamed-inventory-study.md) remain. No new model trial was
performed for this cache change; the earlier fixed-runtime model costs remain
attached to that earlier runtime. Scripted probes consume no model tokens.
LLVM and Node inventories still exceed the source budget. This optimization
makes known refusal cheap; producer-side selective computation remains the next
coverage/computation question. It does not improve provider parity or prove
complex reverse-engineering superiority.
Local artifact SHA-256 (raw documents remain uncommitted):
- `capacity-cache-before.json`: `68fbd4444c81b4a4435a8d300f8b1ea7365f140078ab3cc322bde140be74db24`
- `capacity-cache-after.json`: `66491d37d85c3748578022e0f7e0f8013c2bf19ecec6d0c73db33d2246c7485e`
- `capacity-cache-before.log`: `d57684ede8f9d01bf9750b78f400b4bb529e2d7a23b84195d79d6d729cba6190`
- `capacity-cache-after.log`: `30039f832930680a8cc128c8a372c0018be08c88ac84e4db03d2cc15e4623b38`
- `capacity-cache-final-sdk.json`: `95326d584a88ca5130e79e116b5c0a14bdbaa0a6016342d58010515e8a6c22f9`
- `capacity-cache-final-direct.json`: `ead7e2c5976e13876d1d34cd336e88f62a2e9bba4b3812bc012efbc64d272473`
- `capacity-cache-final-codemode.json`: `8bb64217d52bdbd1771968b9274d6ae04a6ea3b0ae1e5a09d0510bf180320e7b`
- `capacity-cache-final2-codemode.json`: `4ccf81f282a2f62db00638b6a94feaf80992aacc8096ea15d3fc419f0d2789a3`
- `capacity-cache-js-precommit.log`: `d22b3e948baf2a36ae262786d470af0fc3d631ddd79d88a879ac9f2103352792`
- `capacity-cache-js-sealed.log`: `004ffeac2994612f1608fd5904eff15c41ea059d4ad91644abce8532669a5ea0`
-123
View File
@@ -1,123 +0,0 @@
import { freezeFacts as freeze } from "./fact-reads.mjs";
import { nativePage } from "./native-reads.mjs";
function search(outgoing, from, target, avoid) {
const blocked = new Set(avoid);
if (blocked.has(from) || (target.kind === "block" && blocked.has(target.id)))
return {
status: "not-found",
end: null,
items: [],
examined_blocks: 0,
examined_edges: 0,
search: "excluded-endpoint",
};
const queue = [from],
predecessor = new Map([[from, null]]);
let examined_blocks = 0,
examined_edges = 0;
for (let cursor = 0; cursor < queue.length; cursor++) {
const current = queue[cursor],
edges = outgoing.get(current) ?? [];
examined_blocks++;
if (target.kind === "block" ? current === target.id : edges.length === 0) {
const path = [];
for (let at = current; predecessor.get(at) !== null;) {
const edge = predecessor.get(at);
path.push(edge);
at = edge.from;
}
path.reverse();
return {
status: "found",
end: current,
items: path.map((edge, step_index) => freeze({ ...edge, step_index })),
examined_blocks,
examined_edges,
search: "shortest-witness",
};
}
for (const edge of edges) {
examined_edges++;
if (!blocked.has(edge.to) && !predecessor.has(edge.to)) {
predecessor.set(edge.to, edge);
queue.push(edge.to);
}
}
}
return {
status: "not-found",
end: null,
items: [],
examined_blocks,
examined_edges,
search: "reachable-subgraph-exhausted",
};
}
// Consume validated identities/edges, never provider text or machine predicates.
// A resident immutable graph owns at most one cached query and O(V) search state.
export function createGraphPathReader(blocks, outgoing) {
let last;
return (input) => {
const avoid = [...new Set(input.avoid ?? [])];
const selected = [
input.from,
...(input.target.kind === "block" ? [input.target.id] : []),
...avoid,
];
const unretained_blocks = [...new Set(selected)].filter(
(id) => !blocks.has(id),
);
let result;
if (unretained_blocks.length) {
result = {
status: "unknown",
end: null,
items: [],
examined_blocks: 0,
examined_edges: 0,
search: "unretained-selection",
};
} else {
const key = JSON.stringify([
input.from,
input.target.kind,
input.target.kind === "block" ? input.target.id : null,
[...avoid].sort((a, b) => a - b),
]);
if (last?.key !== key)
last = {
key,
result: freeze(search(outgoing, input.from, input.target, avoid)),
};
result = last.result;
}
const {
items,
examined_blocks,
examined_edges,
search: scope,
...outcome
} = result;
return {
...outcome,
from: input.from,
target: { ...input.target },
avoid,
...nativePage(items, input),
total: outcome.status === "unknown" ? null : items.length,
unretained_blocks,
path_coverage: {
scope:
"recovered CFG under requested exclusions; one shortest edge-count witness in native edge order",
search: scope,
examined_blocks,
examined_edges,
branch_predicate_feasibility: "unknown",
machine_semantic_equivalence: "unknown",
runtime_reachability: "unknown",
},
};
};
}
@@ -1,190 +0,0 @@
import assert from "node:assert/strict";
import test from "node:test";
import { createGraphPathReader } from "./cfg-path.mjs";
import { MAX_GRAPH_BLOCKS } from "./graph-limits.mjs";
const graph = (successors) => {
const blocks = new Map(successors.map((_, id) => [id, { id }]));
const outgoing = new Map(
successors.map((targets, from) => [
from,
targets.map((to, index) =>
Object.freeze({
id: `${from}:${index}`,
from,
to,
target: to,
index,
operation: `op${from}`,
polarity: null,
condition_value: null,
condition_test: null,
}),
),
]),
);
return { blocks, outgoing, read: createGraphPathReader(blocks, outgoing) };
};
function floydDistances(successors, allowed) {
const distances = Array.from({ length: 3 }, (_, from) =>
Array.from({ length: 3 }, (_, to) =>
!allowed(from) || !allowed(to)
? Infinity
: from === to
? 0
: successors[from].includes(to)
? 1
: Infinity,
),
);
for (let k = 0; k < 3; k++)
for (let i = 0; i < 3; i++)
for (let j = 0; j < 3; j++)
distances[i][j] = Math.min(
distances[i][j],
distances[i][k] + distances[k][j],
);
return distances;
}
function assertWitness(result, { distance, ends, from, outgoing, allowed }) {
assert.equal(result.status, distance === Infinity ? "not-found" : "found");
assert.equal(result.total, distance === Infinity ? 0 : distance);
if (result.status !== "found") return;
assert.ok(ends.includes(result.end));
let at = from;
for (const [step, edge] of result.items.entries()) {
assert.equal(edge.step_index, step);
assert.equal(edge.from, at);
assert.equal(outgoing.get(at)[edge.index].id, edge.id);
assert.equal(outgoing.get(at)[edge.index].to, edge.to);
assert.ok(allowed(edge.to));
at = edge.to;
}
assert.equal(at, result.end);
}
test("all three-node digraphs and exclusions agree with independent Floyd-Warshall distances", () => {
for (let mask = 0; mask < 512; mask++) {
const successors = Array.from({ length: 3 }, (_, from) =>
[0, 1, 2].filter((to) => mask & (1 << (from * 3 + to))),
);
const { read, outgoing } = graph(successors);
for (let exclusions = 0; exclusions < 8; exclusions++) {
const avoid = [0, 1, 2].filter((id) => exclusions & (1 << id));
const allowed = (id) => !avoid.includes(id);
const distances = floydDistances(successors, allowed);
const queries = [0, 1, 2].flatMap((from) =>
[
{ kind: "exit" },
...[0, 1, 2].map((id) => ({ kind: "block", id })),
].map((target) => ({ from, target })),
);
for (const { from, target } of queries) {
const ends =
target.kind === "block"
? [target.id]
: [0, 1, 2].filter((id) => successors[id].length === 0);
const distance = Math.min(...ends.map((to) => distances[from][to]));
assertWitness(read({ from, target, avoid }), {
distance,
ends,
from,
outgoing,
allowed,
});
}
}
}
});
test("paging retains original edge ordinal, source fields and full-path outcome", () => {
const { read } = graph([[0, 1, 1], [2], []]);
const request = { from: 0, target: { kind: "exit" } };
const first = read({ ...request, limit: 1 });
assert.equal(first.status, "found");
assert.equal(first.total, 2);
assert.equal(first.end, 2);
assert.equal(first.next_offset, 1);
assert.equal(first.items[0].id, "0:1");
assert.equal(first.items[0].index, 1);
assert.equal(first.items[0].step_index, 0);
assert.equal(first.items[0].operation, "op0");
assert.throws(() => {
first.items[0].to = 999;
}, TypeError);
const second = read({ ...request, offset: 1, limit: 1 });
assert.equal(second.items[0].step_index, 1);
assert.equal(second.next_offset, null);
const beyond = read({ ...request, offset: 9 });
assert.equal(beyond.status, "found");
assert.equal(beyond.total, 2);
assert.equal(beyond.end, 2);
assert.deepEqual(beyond.items, []);
});
test("unknown selections, duplicates and excluded endpoints stay explicit", () => {
const { read } = graph([[1], []]);
for (const input of [
{ from: 9, target: { kind: "exit" } },
{ from: 0, target: { kind: "block", id: 9 } },
{ from: 0, target: { kind: "exit" }, avoid: [9, 9] },
]) {
const result = read(input);
assert.equal(result.status, "unknown");
assert.equal(result.total, null);
assert.equal(result.end, null);
assert.deepEqual(result.unretained_blocks, [9]);
}
assert.equal(
read({ from: 0, target: { kind: "block", id: 0 }, avoid: [0] }).status,
"not-found",
);
const zero = read({ from: 1, target: { kind: "exit" } });
assert.equal(zero.status, "found");
assert.equal(zero.total, 0);
assert.equal(zero.end, 1);
assert.equal(zero.path_coverage.runtime_reachability, "unknown");
});
test("one graph-owned cache covers paging and normalized exclusions, replaces on input change", () => {
const { blocks, outgoing } = graph([[1], [2], [], []]);
let reads = 0;
const observed = {
get(id) {
reads++;
return outgoing.get(id);
},
};
const read = createGraphPathReader(blocks, observed);
const request = { from: 0, target: { kind: "exit" }, avoid: [3, 3] };
read(request);
const initial = reads;
read({ ...request, avoid: [3], offset: 1, limit: 1 });
assert.equal(reads, initial);
read({ ...request, avoid: [99] });
read(request);
assert.equal(reads, initial);
read({ from: 0, target: { kind: "block", id: 1 }, avoid: [3] });
assert.ok(reads > initial);
const changed = reads;
read(request);
assert.ok(reads > changed);
const other = createGraphPathReader(blocks, observed);
const before = reads;
other(request);
assert.ok(reads > before, "fresh owner must not share the cache");
});
test("maximum admitted chain is iterative, paged and does not expand caller output", () => {
const { read } = graph(
Array.from({ length: MAX_GRAPH_BLOCKS }, (_, i) =>
i + 1 < MAX_GRAPH_BLOCKS ? [i + 1] : [],
),
);
const result = read({ from: 0, target: { kind: "exit" }, limit: 1 });
assert.equal(result.total, MAX_GRAPH_BLOCKS - 1);
assert.equal(result.items.length, 1);
assert.equal(result.end, MAX_GRAPH_BLOCKS - 1);
assert.equal(result.path_coverage.examined_blocks, MAX_GRAPH_BLOCKS);
});
-20
View File
@@ -1,20 +0,0 @@
import { readFile } from "node:fs/promises";
import { AtomicSession } from "./session.mjs";
import { executeJavaScript } from "./executor.mjs";
const [binary, script] = process.argv.slice(2);
if (!binary || !script)
throw new Error("Usage: node cli.mjs BINARY JAVASCRIPT_FILE");
const session = new AtomicSession();
try {
await session.open(binary);
const result = await executeJavaScript(
session,
await readFile(script, "utf8"),
);
console.log(JSON.stringify(result));
process.exitCode = result.ok ? 0 : 1;
} finally {
session.abort();
await session.close();
}
@@ -1,135 +0,0 @@
# Client waiting and whole-task cost
The [selected-case pair](switch-study.md) exposes one-second client polls after
the snapshot execution yields. Direct makes six waits (three one-second then
three ten-second requests); Code Mode makes three one-second requests. Five
direct and two Code Mode wait responses still report a running cell. Initial
execution yields after about 31 seconds in both lanes. This is observed client
behavior, separate from MCP attempts and native source-capture time.
Native latency remains variable, including in sequential scripted MCP runs
without models. The [overlap canary](overlap-study.md) did not establish a cause.
No analysis acceleration or cache invalidation change is proposed here.
## Frozen diagnostic
The opt-in runner flag `--guide-long-waits` appends exactly the same client wait
policy in both lanes: resume an already-running cell with a 30,000 ms wait,
respect the advertised schema, and do not sleep or duplicate analysis merely
to check progress. It changes neither the initial execution yield policy nor
the provider/Code Mode deadlines. It supplies no analysis facts. The policy,
flag and instruction digest are recorded in each trial's settings. Older runs
without this flag remain a separate stratum.
Run Code Mode first, then direct, with the unchanged
[question](sqlite-switch-question.txt) and [oracle](switch-oracle.md), final
`a9ca8a8a...` engine, complete four/eighteen-tool catalogs and the same exact
discovery/envelope guidance as the first pair. Use fresh leases and isolated
model workspaces, requested `gpt-6.1-sol/high`, Codex 0.161.0 and the same one-CPU,
4 GiB hard / 3 GiB early-stop resource policy. No runtime edits during the pair.
Local records use `sqlite-switch-{codemode,direct}-v2*`.
Review complete answers against the frozen independent machine oracle and
retained source, including selector widths, all requested cases, signed target
arithmetic, case/edge identities, native default versus machine out-of-range
guard, provenance and unknown runtime behavior. Require one VM capture and
focused reads; a lower token count without a correct answer is not a win.
Record actual wait arguments and running/completed responses, model responses,
all input/cached/uncached/output/reasoning tokens, MCP/API attempts, wall time,
family CPU, kernel family peak, native source-capture time, identity/freshness
and cleanup/OOM status. Count discovery, guidance and unsuccessful waits in
whole-task usage. Fewer polls would establish adherence in this client, not
causally lower tokens or native latency. A before/after pair remains subject to
model choices, prompt caches, host contention and run order; do not subtract
native or polling intervals to manufacture an adapter speedup.
The [official Codex CLI reference](https://learn.chatgpt.com/docs/cli/reference)
documents client configuration but does not establish the `wait` contract used
here. The actual captured client calls and subsequent run establish behavior;
no configuration feature flag is treated as proof of the available surface.
The native/API contracts are unchanged.
## Executed repeat
Both runs pin `790cdfdef`, with Code Mode first and direct second. Their shared
frozen runtime is preserved by tag
[`experiment/atomic-codemode-wait-runtime-20261016`](https://github.com/morluto/rea/tree/experiment/atomic-codemode-wait-runtime-20261016),
which retains the original revision before commit-attribution metadata cleanup.
Both complete answers again pass the frozen oracle: format ownership before capture, selector
widths, all five selected case identities/edges/targets, signed table arithmetic,
the absent explicit `0xb6` case and distinct native-default/machine-guard
destinations. Direct cites eleven observed source IDs; Code Mode cites ten.
Each has one VM source, equal to the full prior graph/ordinary-field golden,
and no complete case/C/graph fetch. Both close the lease and retain the stated
static/alias/runtime limits. Source fidelity does not prove global equivalence.
| Whole-task measure | Direct atomic | Code Mode |
| ------------------------------ | ------------: | --------: |
| Cumulative input tokens | 280,035 | 372,288 |
| Included cached input | 221,312 | 343,168 |
| Uncached input | 58,723 | 29,120 |
| Output tokens | 4,648 | 5,384 |
| Included reasoning output | 1,122 | 862 |
| Observed model responses | 12 | 16 |
| Client execution / wait calls | 10 / 1 | 14 / 1 |
| MCP attempts, including reject | 17 | 15 |
| Successful atomic fact reads | 14 | 19 |
| Model wall seconds | 175.908 | 196.640 |
| Family wall seconds | 176.382 | 197.767 |
| Family CPU seconds | 66.735 | 56.081 |
| Kernel process-family peak MiB | 786.6 | 870.3 |
| VM source-capture wall seconds | 47.010 | 39.828 |
Both request `yield_time_ms:30000` once, resuming their pending snapshot cell;
the waits return completed results after 16.5 seconds direct and 6.5 Code Mode.
Neither adds an unsuccessful running-cell poll. This establishes adherence,
and reduces waits from six/three to one/one in these samples. It does not
establish a causal token/latency reduction: native capture times and subsequent
investigation choices differ, and the Code Mode repeat makes more fact reads.
Code Mode's attempts include a schema-rejected `timeout_ms:200000` (maximum
120,000), then a valid retry. Later a script returns complete input arrays from
operations at a PHI-heavy origin and exceeds the 32 KiB result budget. Its three
host reads succeed and source Evidence survives; the next script returns a
smaller projection successfully. Both costs stay in the ledger. Direct has no
failed attempts. The timeout mistake also occurred in the earlier control task:
the next interface check should make the default/maximum explicit in discovery,
using the execution owner's policy rather than another copied constant.
Within this repeat, Code Mode uses 32.9% more cumulative input, 15.8% more output
and 11.8% more model wall time, while using 50.4% less uncached input and less
family CPU. Relative to the first pair, direct cumulative input falls but its
uncached input rises; Code Mode cumulative and uncached input both rise despite
fewer waits. There is no stable whole-task winner across these strata.
Per-response usage matches the ledger; guidance is included in token usage.
Runtime, engine and target fingerprints remain unchanged. OOM is zero and
payload/profile cleanup is verified. Resource/model settings and the cold-lease,
uncontrolled-cache/host and unmeasured-remote-compute limitations remain as above.
Kernel peaks include charged file cache, not RSS. Both clients already provide
JavaScript composition. Full records use the declared `-v2` local paths; the
unchanged summarizer reconstructs actual usage but does not grade correctness.
## Discovery follow-up
The execution owner, MCP admission schema and Code Mode help now use one frozen
policy in `limits.mjs`. Both the execution description and detailed reference
state that omitting `timeout_ms` uses the 120,000 ms default/maximum; the separate
2,000 ms guest CPU budget remains explicit. Heap, stack, host-call, source and
result budgets are unchanged. The direct adapter omits Code Mode execution
limits/notes. Snapshot documentation also names the optional independent switch
facet, avoiding a stale return description after the new exporter.
All 73 shared JS tests pass (4.349 family wall / 4.114 CPU seconds, 79.6 MiB
kernel peak). The actual SDK catalogs and named references validate in both
lanes. The Code Mode MCP check rejects the observed 200,000 ms parameter, then
successfully executes a defaulted request with zero host calls (final catalog
check: 5.086 family wall / 4.111 CPU seconds, 142.2 MiB kernel peak).
A real zlib MCP check also verifies bounded
ordinary/oversized guest errors and retained source access after failure
(1.530 wall / 1.338 CPU seconds, 136.6 MiB). All have OOM 0 and verified cleanup;
focused lint has no warnings and formatting passes. No native rebuild or full
repository gate ran for this discovery change. No new model pair has measured
whether it reduces mistakes or whole-task cost; earlier results retain their
original runtime pins.
@@ -1,92 +0,0 @@
// Stream a complete legacy native inventory; retain only small expected query pages.
import assert from "node:assert/strict";
import { createReadStream } from "node:fs";
import { readFile, writeFile } from "node:fs/promises";
import { createHash } from "node:crypto";
import { createGunzip } from "node:zlib";
import { Transform } from "node:stream";
import chain from "stream-chain";
import { parser } from "stream-json";
import { pick } from "stream-json/filters/pick.js";
import { streamArray } from "stream-json/streamers/stream-array.js";
import { join } from "node:path";
const [directory, output] = process.argv.slice(2);
assert(directory && output);
const manifest = JSON.parse(
await readFile(join(directory, "manifest.json"), "utf8"),
);
const queries = [
"undefined symbol",
"Invalid bitcode signature",
"",
"\ud800",
"a.b+",
].map((query) => ({ query, total: 0, sample: [] }));
const rawHash = createHash("sha256");
let bytes = 0,
total = 0,
group = [],
previous = -1;
const emit = () => {
group.sort((a, b) => a.encoding.localeCompare(b.encoding, "en"));
for (const row of group) {
for (const selection of queries)
if (row.text.includes(selection.query)) {
selection.total++;
if (selection.sample.length < 16)
selection.sample.push({ ...row, source_row: total });
}
total++;
}
group = [];
};
const stream = chain([
createReadStream(join(directory, "inventory.json.gz")),
createGunzip(),
new Transform({
transform(chunk, _encoding, done) {
rawHash.update(chunk);
bytes += chunk.length;
done(null, chunk);
},
}),
parser(),
pick({ filter: "strings" }),
streamArray(),
]);
for await (const { value } of stream) {
assert(Number.isSafeInteger(value.address) && typeof value.text === "string");
assert.equal(value.address_hex, "0x" + value.address.toString(16));
assert(value.address >= previous);
if (value.address !== previous) {
emit();
previous = value.address;
}
group.push(value);
}
emit();
assert.equal(rawHash.digest("hex"), manifest.raw_sha256);
assert.equal(bytes, manifest.raw_bytes);
await writeFile(
output,
JSON.stringify(
{
manifest,
total,
queries,
scope:
"Complete legacy producer comparison; query matches use JavaScript UTF16 includes, only first 16 per query retained. Not an independent proof of all string recognition.",
},
null,
2,
),
{ flag: "wx" },
);
console.log(
JSON.stringify({
total,
bytes,
queries: queries.map(({ query, total }) => ({ query, total })),
}),
);
@@ -1,144 +0,0 @@
// Immediate postdominators on the reversed recovered CFG, using linear retained
// state. Control dependence is derived for finite paths to recovered exits.
import { FactFailure } from "./fact-error.mjs";
import { freezeFacts } from "./fact-reads.mjs";
const workBudget = (limit) => {
let work = 0;
return () => {
if (++work > limit)
throw new FactFailure(
"capacity",
"Control-dependence work budget exceeded",
);
};
};
// Retain one linear-size index per resident graph. Selected rows are generated
// per read, so paging does not retain a potentially quadratic relation set.
export function createControlDependenceIndex(
blocks,
{ workLimit = 2_000_000 } = {},
) {
const exit = Symbol("recovered-exit");
const successors = new Map(
blocks.map((block) => [
block.id,
block.successors.map((edge) => edge.target),
]),
);
const reverse = new Map([
[exit, []],
...blocks.map((block) => [block.id, []]),
]);
const tick = workBudget(workLimit);
for (const [from, targets] of successors) {
if (!targets.length) targets.push(exit);
for (const to of targets) reverse.get(to).push(from);
}
const { parent, visited } = postdominatorParents(
exit,
successors,
reverse,
tick,
);
const coverage = freezeFacts({
scope:
"derived control dependence in the recovered graph; zero-successor blocks treated as exits; finite paths only",
status:
visited.size === blocks.length + 1
? "complete-for-recovered-finite-exit-paths"
: "partial",
exit_unreachable_blocks: blocks
.filter((block) => !visited.has(block.id))
.map((block) => block.id),
nontermination: "unknown",
runtime_reachability: "unknown",
});
function* relations(dependents) {
const tick = workBudget(workLimit);
for (const block of blocks) {
if (!parent.has(block.id)) continue;
for (const edge of block.successors) {
let runner = edge.target;
while (
parent.has(runner) &&
runner !== parent.get(block.id) &&
runner !== exit
) {
tick();
if (!dependents || dependents.has(runner))
yield { controller: block.id, dependent: runner, edge };
runner = parent.get(runner);
}
}
}
}
return Object.freeze({
relations,
coverage,
read: ({ seeds, offset = 0, limit = 20 }) => {
const selected = new Set(seeds),
items = [];
let total = 0;
// Exhaust for a truthful total, retaining only the requested page.
for (const row of relations(selected)) {
if (total >= offset && items.length < limit) items.push(row);
total++;
}
return {
items,
total,
next_offset: offset + limit < total ? offset + limit : null,
relation_coverage: coverage,
};
},
});
}
function postdominatorParents(exit, successors, reverse, tick) {
const visited = new Set([exit]);
const stack = [[exit, 0]],
postorder = [];
while (stack.length) {
tick();
const frame = stack.at(-1),
children = reverse.get(frame[0]);
if (frame[1] < children.length) {
const child = children[frame[1]++];
if (!visited.has(child)) {
visited.add(child);
stack.push([child, 0]);
}
} else {
postorder.push(frame[0]);
stack.pop();
}
}
const order = postorder.reverse();
const position = new Map(order.map((id, i) => [id, i]));
const parent = new Map([[exit, exit]]);
const intersect = (a, b) => {
while (a !== b) {
tick();
if (position.get(a) > position.get(b)) a = parent.get(a);
else b = parent.get(b);
}
return a;
};
let changed = true;
while (changed) {
changed = false;
for (const node of order.slice(1)) {
tick();
const known = successors.get(node).filter((id) => parent.has(id));
if (!known.length) continue;
const next = known.slice(1).reduce(intersect, known[0]);
if (parent.get(node) !== next) {
parent.set(node, next);
changed = true;
}
}
}
return { parent, visited };
}
@@ -1,43 +0,0 @@
// Test/evaluator oracle only. Removing a node and searching for exits is
// independent of the runtime's immediate-postdominator algorithm.
export function finiteExitControlOracle(blocks) {
const reverse = new Map(blocks.map((block) => [block.id, []]));
for (const block of blocks)
for (const edge of block.successors)
reverse.get(edge.target).push(block.id);
const exits = blocks
.filter((block) => !block.successors.length)
.map((b) => b.id);
const reachesExitWithout = (forbidden) => {
const seen = new Set(exits.filter((id) => id !== forbidden));
const queue = [...seen];
for (let i = 0; i < queue.length; i++)
for (const previous of reverse.get(queue[i]))
if (previous !== forbidden && !seen.has(previous)) {
seen.add(previous);
queue.push(previous);
}
return seen;
};
const active = reachesExitWithout(undefined),
relations = [];
for (const dependent of active) {
const avoiding = reachesExitWithout(dependent);
const postdominates = (node) => active.has(node) && !avoiding.has(node);
for (const block of blocks) {
if (!active.has(block.id)) continue;
// Strict postdominance excludes the node itself, preserving loop
// self-dependence when a recovered edge leads back to its controller.
if (block.id !== dependent && postdominates(block.id)) continue;
for (const edge of block.successors)
if (postdominates(edge.target))
relations.push({ controller: block.id, dependent, edge_id: edge.id });
}
}
return {
relations,
exit_unreachable_blocks: blocks
.filter((b) => !active.has(b.id))
.map((b) => b.id),
};
}
@@ -1,152 +0,0 @@
# Correct and reusable control queries
Retained-source inspection exposed a correctness gap: a nonexistent CFG seed
returned an empty set without saying that the block was unretained. Source-wide
control coverage could be mistaken for proof that the requested block had no
controllers. Incoming/outgoing queries shared this selection boundary. They now
deduplicate seeds and return `unretained_seeds`, distinguishing a retained block
with no relations. Incoming/outgoing order follows caller seeds then native
edges; controller order stays native controller/edge then postdominator ancestor.
`createControlDependenceIndex` replaces the one-shot implementation. The native
graph owner constructs it lazily and retains it only with that resident snapshot.
It holds linear-size postdominator/coverage state, without query keys or a
potentially quadratic complete relation set. Page reads generate relations,
count the entire selected set and retain only the requested page. Construction
and each relation walk have separate two-million-step budgets; capacity failure
is explicit. Coverage/edges are immutable; fresh reply row containers cannot
change subsequent reads. The index follows the existing two-resident-model
lifetime. CLI, SDK and both adapters use this owner; no native rebuild or new
public method is required.
Semantics remain finite paths to recovered zero-successor exits. Loop
self-dependence is possible; exit-unreachable blocks are explicit. Runtime
feasibility, memory aliases and nontermination remain unknown.
## Independent verification
The test/evaluator-only `control-path-oracle.mjs` removes each candidate node
and searches backward from exits. It independently verifies all 512 three-node
directed graphs, including cycles, alongside the existing 64 four-node DAGs,
multiple exits, unreachable regions and work-capacity checks. Single-row paging,
unknown/duplicate seeds and immutable coverage/edges pass. The related suite
passes 82 tests; the final added edge-mutation assertion also passes its focused
ten-test suite. Experiment lint has no warnings; formatting passes.
The real Debian SQLite VM has 1,229 blocks, 2,061 edges and 2,845 derived control
triples. Both actual MCP adapters page every triple and match the independent
oracle, including exact native edge metadata. Each executes 52 MCP requests.
Full graph, ordinary function/call records and Evidence views equal the earlier
golden; former projection frontiers remain readable. All three CFG relation
kinds correctly report unknown-only and mixed/duplicate seeds. Target and
preserved `a9ca8a8a...` engine match the [switch study](switch-study.md). No target
execution or modification occurs.
## Executed costs
| Scope | Family wall s | Family CPU s | Kernel peak MiB |
| --------------------------- | ------------: | -----------: | --------------: |
| Related 82 tests | 20.342 | 13.857 | 93.5 |
| Real Code Mode MCP | 103.417 | 78.642 | 713.2 |
| Real direct MCP | 42.702 | 42.301 | 725.4 |
| Equivalent-query diagnostic | 2.636 | 2.482 | 309.0 |
One CPU, 4 GiB hard / 3 GiB early-stop bounds apply. All have OOM/kill 0 and
verified payload cleanup. Kernel family peak includes charged file cache, not
RSS. Code Mode's fresh native capture takes 95.068 wall / 72.758 CPU seconds;
direct's takes 39.432 / 39.408. This native/host variation is not a dispatch
measurement. The first selected eight-row query takes 61.2 ms / 0.0616 CPU
seconds Code Mode, 15.0 ms / 0.0157 direct. The identical same-lease warm query
takes 3.2 ms / 0.00384 and 1.8 ms / 0.00242. Paging all triples takes 274.9/224.2
ms. Cumulative peaks only upper-bound warm memory. Private native caches are
fresh; OS caches and host contention are uncontrolled. Receipts remain local
as `controls-{code,direct}-v1*`.
`profile-controls.mjs` compares baseline
`d7d95c7dcc824cc90f63de7a8e2efa2237c53d8f` with the current owner on the same
validated retained graph. The complete task returns eight relations for blocks
1154/1159 in four two-row pages. Both return identical facts:
| Core task | Reads | Elapsed ms | Process CPU s |
| ----------------------------- | ----: | ---------: | ------------: |
| Previous implementation | 4 | 75.33 | 0.0751 |
| First indexed task | 4 | 23.33 | 0.0233 |
| Identical complete task, warm | 4 | 1.27 | 0.0013 |
| Previous, 50 complete tasks | 200 | 420.03 | 0.4174 |
| Indexed, 50 complete tasks | 200 | 60.27 | 0.0603 |
Parsing/validation separately takes 1,013.4 ms / 1.0127 CPU seconds. Order,
JIT and caches are uncontrolled within the shared process. This diagnostic
excludes fresh native work, MCP discovery/serialization and model tokens;
it does not establish a whole-agent speedup or fewer reads/tokens. Source/module
hashes and facts are retained in `controls-profile-v1.json`.
## Real-agent two-level investigation
The [question and oracle](controller-oracle.md) and runtime were frozen at
`8d13c67e7` before either model launch, Code Mode first and direct second.
Both complete answers pass the frozen oracle/source review: format ownership,
PHI/call binding, both complete controller levels, all four Boolean guards and
operand widths/LOADs, exact shared/distinct SSA identities, alternative predicates,
valid recovered witnesses, machine corroboration and explicit limits. Both close
the lease. The relation list is correctly distinguished from a conjunction.
Direct chooses longer bypass witnesses than the oracle examples. Every reported
edge is valid; both paths end at zero-successor block 1207 and avoid block 1159.
Including the initial controller edge, direct uses nine/twelve edges, Code Mode
six/six; shortest paths were not required. Both full native function records equal
the earlier golden. All thirteen Code Mode and ten direct cited source IDs exist
with matching artifact/engine identities. Code Mode's extra pointer/spill facts
also match the retained IR and selected GNU decoding. The cost summarizer does
not automatically grade natural language.
| Whole-task measure | Direct atomic | Code Mode |
| ------------------------------ | ------------: | --------: |
| Cumulative input tokens | 935,185 | 503,113 |
| Included cached input | 878,592 | 436,736 |
| Uncached input | 56,593 | 66,377 |
| Output tokens | 7,320 | 7,450 |
| Included reasoning output | 757 | 835 |
| Observed model responses | 24 | 17 |
| Client executions / waits | 22 / 1 | 15 / 1 |
| MCP attempts | 36 | 15 |
| Rejected MCP / inner API reads | 0 / 0 | 0 / 0 |
| Successful atomic fact reads | 32 | 33 |
| Model wall seconds | 230.280 | 246.479 |
| Family wall seconds | 230.755 | 248.500 |
| Family CPU seconds | 52.458 | 72.837 |
| Kernel process-family peak MiB | 876.5 | 944.3 |
| Native source-capture wall s | 37.852 | 52.471 |
Both request `gpt-6.1-sol/high` via Codex 0.161.0, with complete 18/4-tool catalogs
and common exact-name/envelope/stopping/long-wait guidance. Actual client calls
use JavaScript `exec`/`wait` in both lanes despite false client Code Mode flags.
This compares server Code Mode with direct atomic MCP on that host, not
composition against its absence. Resolved service build and remote compute are
unknown. Per-response usage sums match the ledger; cached input is included in
input, reasoning in output. Discovery, schemas, waits and all calls are charged.
Runtime, target and engine remain unchanged; both profiles/payloads have verified
cleanup, OOM/kill 0 and no resource abort under the same one-CPU / 4 GiB / 3 GiB
bounds. No new warm real-agent task was run.
Both actually query `controllers` at both levels. Neither uses the C tool or
fetches the complete raw IR report. Code Mode reads the complete block-successor
inventory internally for path search and does extra pointer/spill analysis:
fourteen block, six operation and three instruction API reads. Direct uses ten
block, five operation, two instruction reads, two bounded slices and more selected
CFG reads. Different strategies and native capture times remain confounds;
source-capture time is not an isolated native-drive interval and must not be
subtracted to manufacture a dispatch-only effect.
In this single pair, Code Mode reduces cumulative input by about 46% and uses
fewer model rounds, but increases uncached input, output, elapsed time, CPU and
peak memory. The index's core-query improvement does not establish a causal
whole-agent benefit. Correct composable facts support both strategies; there is
still no stable overall Code Mode advantage or broad complex-software superiority
claim. No traditional-provider cell is invented for this native-identity question.
Local records: `sqlite-controller-{direct,codemode}-v1*`,
`controller-matrix-costs.json` and `controller-answer-checks.json` under
`.cache/atomic-codemode/`. `summarize-trials.py` reconstructs costs. Fresh leases
and private native caches do not control OS/model-service caches; kernel peaks
include charged file cache, not RSS. Scripted warm/core results stay separate.
@@ -1,108 +0,0 @@
# Two-level recovered controller oracle
Freeze this oracle and [question](sqlite-controller-question.txt) before model
launches. Both lanes get the same question without addresses, native IDs or
precomputed paths; this oracle stays outside their isolated workspace. Complete
catalogs are eighteen direct tools or four Code Mode tools over the same API.
The question requires native identities/derived relations absent from the
traditional catalog, so there is no traditional-provider cell or parity claim.
Both clients already expose JavaScript dispatch.
Target: Debian SQLite `3.40.1-2+deb12u2` amd64
`/usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6`, SHA-256
`2e6eef9a727f081f0d453b4e5e6cbd8b9ef8b6f86cbf7681cbad444d3b0b55c8`.
Engine SHA-256:
`a9ca8a8ac224936afb08a9d4be9c1225feb69473ad9f35764e8d1c4f04875b5b`.
REA was refreshed from main `4838f444939677107902549c59b73439e14d3ae9`
before this work. Freeze runtime/HEAD during both runs. Request
`gpt-6.1-sol/high`, Codex 0.161.0, common exact-name/envelope/stopping/long-wait
guidance, fresh leases/private caches, one CPU and 4 GiB hard / 3 GiB early-stop
bounds. Charge all discovery, retries, waits and actual model usage. Preserve
native timing variation and incomplete attempts.
## Formats and first-level controllers
References select VM entry `0xea6d0`, rather than same-name stub `0x288f0`.
Open format `0x12c500` is produced by `0xf2381:712c` in block 1142; release
format `0x12c538` by `0xf2437:753c` in block 1158. PHI `0xf238b:ceb7`, output
`v100033f25`, binds slots 0/1 to incoming edges `1142:0`/`1158:0`. Shared CALL
`0xf238b:7130` in block 1159 takes this format at input 2, with eight-byte
`register:0x30` (RSI) passing storage. Target `ram:0x296c0`, native label
`sqlite3VdbeError`, does not establish a complete source signature or runtime
binding.
The complete direct controller set of block 1159 is exactly:
- Block 1141, CBRANCH `0xedc01:7065`: selected `1141:1 -> 1142`, true/ne-zero;
other `1141:0 -> 1143`, false/ne-zero. One-byte condition `v100012864` is
defined by `0xedc01:7064 INT_SLESS`: slot 0 four-byte zero `v30001285f`,
slot 1 four-byte `v100012840` from LOAD `0xedbf8:7056`. Guard: signed loaded32 > 0.
- Block 1157, CBRANCH `0xf0389:71b8`: selected `1157:1 -> 1158`, true/ne-zero;
other `1157:0 -> 1161`, false/ne-zero. One-byte condition `v100012bd9` is
`0xf0384:71b3 INT_EQUAL`: slot 0 four-byte `v10001280a` from LOAD
`0xedbe5:7041`, slot 1 four-byte one `v3000393a3`. Guard: loaded32 == 1.
## Exactly one further level
- The complete direct set for 1141 is block 1140, CBRANCH `0xedbf2:7054`.
Selected `1140:0 -> 1141`, false/ne-zero; other `1140:1 -> 1149`, true/ne-zero.
One-byte `v10001282b` is `0xedbf0:704e INT_NOTEQUAL`: slot 0 four-byte
`v10001280a`, LOAD `0xedbe5:7041`, slot 1 four-byte zero `v10001282d`.
The selected edge negates NOTEQUAL: loaded32 == 0.
- The complete direct set for 1157 is block 1156, CBRANCH `0xf0382:71ab`.
Selected `1156:1 -> 1157`, true/ne-zero; other `1156:0 -> 1161`, false/ne-zero.
One-byte `v100012bc0` is `0xf0382:71aa INT_SLESSEQUAL`: slot 0 four-byte
one `v500038ab1`, slot 1 four-byte `v100012b9e`, LOAD `0xf0378:719d`.
Guard: signed loaded32 >= 1.
Open outer and release inner comparisons share exactly `v10001280a` (P).
Conjoining their selected predicates would require P == 0 and P == 1. These
are alternatives, not simultaneous prerequisites. Locally open combines
P == 0 with signed S > 0; release combines signed T >= 1 with P == 1.
These are not complete VM-entry path conditions or a demonstrated SQL trigger.
P, S (`v100012840`) and T (`v100012b9e`) all have unique-space coordinate
`0x23d00`/4 but are distinct SSA values. S/T have separate LOAD definitions,
even though machine code reads `[R13+0xd8]` in each path. Matching coordinates
or memory expressions do not equate contents across reads/paths or solve aliases.
## Graph witnesses
Accept any edge-valid witnesses with the required endpoints and omitted block,
not only these shortest examples:
- Selected: `1142 -> 1159`, edge `1142:0`; `1158 -> 1159`, edge `1158:0`.
- Open alternative avoiding 1159:
`1143 -> 1144 -> 1201 -> 1204 -> 1205 -> 1207`, edges
`1143:0, 1144:0, 1201:0, 1204:0, 1205:1`.
- Release alternative avoiding 1159:
`1161 -> 1162 -> 1163 -> 1164 -> 1205 -> 1207`, edges
`1161:1, 1162:1, 1163:1, 1164:0, 1205:1`.
1207 has zero successors. Check every edge against the retained graph. These
finite recovered paths establish neither machine paths, feasible predicates nor
termination.
## Independent machine checks and grading
ELF64LE PT_LOAD/file reads verify sixteen instruction sites and eight relative
targets; GNU decoding corroborates them. Receipt: `controller-machine-oracle.json`
locally. Earlier sites are in the [savepoint oracle](savepoint-control-oracle.md).
Additional facts:
- `0xedbf0 85f6` TESTs ESI; `0xedbf2 0f8548270000` is JNE `0xf0340`,
zero falls through to `0xedbf8`. Native successor origins are separate metadata.
- `0xf0378 458b9dd8000000` loads R11D from `[R13+0xd8]`; `0xf037f 4585db`
TESTs it; `0xf0382 7e0b` is signed JLE `0xf038f`, positive falls through
to `0xf0384`. Native true/ne-zero here is not machine JLE-taken.
- Other guards remain signed JG `0xedc01 -> 0xf2372` and equality JE
`0xf0389 -> 0xf242d`; format setups and shared CALL bytes are unchanged.
The full graph has 21,349 operations, 35,755 values, 1,229 blocks and 2,061 edges.
Both actual MCP adapters match all 2,845 control triples against the independent
node-removal/exit-reachability oracle, with source fidelity and exact native edge
metadata. This is not global machine/IR equivalence. Grade the complete answer
and actual calls: both controller levels, all four conditions, shared/distinct
SSA identities, valid witnesses, selected machine corroboration, real source
IDs/digest and explicit recovered/alias/machine/nontermination/runtime limits.
A cheap incomplete/incorrect answer is not an efficiency success. Close the lease.
Loaded 100 of 1053 files, more files were not shown because too many files have changed in this diff. Show more