README.md's packet-summary row says tshark/capinfos support is
Linux-verified, but sixteen translations omitted that caveat.
Fixes#7655
Supersedes #7972
The translated phrases are from #7972, reapplied to the moved pcap
guide links; simplified Chinese, which #7972 did not cover, follows the
traditional Chinese wording.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The client configuration reference had no entries for three clients that
the installation guide lists as supported and sends readers here for.
Add a section for each naming the configuration file setup writes, the
mcpServers.rea entry key, the entry fields, and the shared skill root, as
defined in src/application/SupportedClients.ts and
src/application/ClientConfigurationDocument.ts.
Fixes#7650
Supersedes #7750
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
inspect-native-exports treated any nonzero byte in .dynsym entry 0 as a
malformed table. That is right when the reserved slot holds a real symbol,
which was #7389, but some Android arm64 libraries set only st_name. Those
files were rejected before any export could be read.
Skip that entry, keep the inventory complete, and record the nonzero
st_name in limitations. Any other nonzero field still fails the table.
Fixes#9700
Supersedes #9752
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A base APK whose manifest requires ABI or density splits keeps its native
libraries in those splits, yet inspect_android_jni_bindings reported a
complete library inventory with zero libraries. The bridge's native
declaration inventory now also decodes the root binary manifest without a
session and reports its requiredSplitTypes and isSplitRequired facts, or why
they are unknown (bridge identity 11). When splits are required or unknown,
the library inventory is partial with an unknown that says so, and a binding
without a candidate is unknown instead of unmatched.
The binary manifest fixture from #9769 was used to check the bridge with the
real jadx-headless-mcp 0.7.1 JAR, including stripped attribute names that
resolve through framework resource IDs.
Fixes#9756
Co-Authored-By: 2SinceJuly <202121119+2SinceJuly@users.noreply.github.com>
Co-Authored-By: Phon <twilyt1@proton.me>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
trace_native_values ended at a provider-classified thunk whose model
holds only a synthetic return (an external import) or borrows its
target's operations, without saying the target was never examined, so
a stub's small model read as the end of the call chain. Thunk targets
are now reconciled after traversal: one another path traced, attempted
or queued is left to that path, and the rest are reported in unknowns
with the target in a new optional related_procedure field.
Fixes#8476
Supersedes #8678
Based on #8678 and rebased onto main's separate call-binding module.
related_procedure is exactOptional and set only on the thunk unknown,
so other unknowns and retained traces keep their shape.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A worker heap too small for REA's bridge stops the JVM before the protocol
handshake, so the launcher's retained stderr is the only evidence, and the
failure was reported as capability_unavailable with configuration advice.
When that stderr carries HotSpot's java.lang.OutOfMemoryError heap reasons,
report resource_constraint for memory with observed_max_heap_bytes null and
the same REA_JADX_HEAP_MIB remediation the bridge-reported heap failure uses,
now shared and stating -Xmx precedence. Other launcher stops are unchanged.
Refs #3517
Supersedes #3573
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Desktop capture used XDG_* values without checking that they are
absolute, so a relative XDG_CONFIG_HOME (or data, state, cache) moved
state-directory, desktop-entry and build-secret lookups under the
working directory. The XDG Base Directory Specification says to ignore
a relative value; one xdgBase helper now applies that rule and falls
back to the home default.
Fixes#9702
Squashed from #9705 and rebased onto main. Setup's client registration
paths are left unchanged: each client's own handling of a relative
XDG_CONFIG_HOME has to be verified before REA writes elsewhere.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A successful batch_decompile item carried no item-level provenance:
only the batch Evidence aggregated limitations, so when a provider such
as Kuna answered repeated selectors from different sources, the caveat
did not say which occurrence it applied to. Successful items now keep
their own observation's limitations (exactOptional, so retained records
still parse), and the retained items view projects them.
The batch unavailable item also dropped the provider's typed
pseudocodeAbsence reason; it now carries pseudocode_absence.
Fixes#8350
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
MCP passes progress to observeWebSession, but the CLI did not, so a
caller of `rea observe-web-session` never saw the armed observation
window it must wait for before acting. Three CLI commands also each
wrote their own copy of the same stderr progress line.
One cliProgress module now owns the stderr progress line and reporter.
observe-web-session uses it, as do web runtime, JavaScript application
and desktop capture progress. The CDP session also stops reporting
readiness once collection is no longer active, so a stopped capture does
not invite the external action.
Fixes#8141
Supersedes #8149
Based on #8149; the desktop capture copy now shares the line writer too.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A cursor for another target, profile, pattern, mask, bounds, or document
was reported as invalid input and pointed at schema repair. Name the
binding, attribute the issue to the cursor, and leave the differing
component unknown.
Fixes#8366
Supersedes #8420
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
When the byte reader for inspect_native_dispatch_metadata refuses a target
(for example a 32-bit Mach-O) and the list_names symbol fallback then fails
or returns an invalid inventory, only the fallback's error reached the
caller. Retain the reader failure under diagnostics.binary_metadata_failure.
Fixes#7651.
Carries forward e7884a704 (by @morluto, on @dreinst's #7701).
Signed-off-by: Zhaowei Gu <83746079+zw-g@users.noreply.github.com>
Supersedes #8036
Co-authored-by: morluto <76467478+morluto@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
A hardened-runtime client without the Apple Events automation
entitlement got generic Automation advice, and the projection kept
retryable: true, so agents retried from the same unauthorized client.
The denial is now a typed launch rejection whose message and recovery
name the entitlement and the Automation setting, with retry turned off.
Fixes#9879
Squashed from #9916 and rebased onto main.
Co-Authored-By: morluto <76467478+morluto@users.noreply.github.com>
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Keep magic 3627 (CPython 3.14.6) and 3666 (CPython 3.15.0b3), whose code
layout and inline-cache tables match those interpreters' opcode tables and
whose decoded code objects match marshal.loads across a stdlib sample. Leave
the 3.15.0a8 magic 3663 unpinned, since no 3.15.0a8 interpreter was available
to check it, and regenerate the 3.15 slice fixture with 3.15.0b3.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Every rea process imported and registered all 52 command registrars
(about 1,900 modules) before running any command. A one-shot command
now loads only the registrar that defines its top-level command.
- src/cli/cliCommandRegistrations.ts holds every registrar in one table,
grouped by tool family, with its module loader and its call. The
complete createCli registers the table with static imports, and the
types check that each entry matches its module.
- src/cli/cliShell.ts owns what does not depend on which commands are
registered: identity, globals, argument policy, completions and the
registration builtins. The full and lazy paths share it.
- scripts/record-cli-commands.mjs records, after tsc, which registrar
defines each top-level command, from the same compiled table. The
bundle keeps the record as an external dist module.
- cli/cliLoader.ts selects the recorded registrar when a known top-level
command runs. It loads the complete CLI for help, --schema, --llms,
completions, builtins, unknown names ("did you mean"), or a missing
record.
- Process-owned CLI resources register their closers when their module
loads (cli/cliResources.ts), so the shell no longer imports
JavaScript-analysis and guidance owners just to close them.
Measured on one pinned core (median of 5 warm runs, base main vs this
change):
- guidance: 1.95 s / 253 MB → 0.42 s / 101 MB
- list-cutter-sessions: 1.97 s → 0.49 s
- inspect-go-binary: 1.95 s → 0.95 s
- setup --dry-run: 2.40 s → 1.88 s
- analyze: 2.39 s → 1.78 s
- --help: 1.99 s → 2.04 s (complete CLI, as before)
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
- doctorCancellation measured from the signal, after the probe had
started, so a probe stopped by its own deadline could still pass. The
fake probe now records its start, and the check runs from there.
- rea/project-wait-deadline missed literal computed `timeout` keys and
spread options. It now reports both, as well as computed keys it
cannot read.
- The testing guide notes that a long-running test's expect.poll keeps
its project budget, while waitFor follows the tag's deadline.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Vitest's expect.poll and vi.waitFor stop after one second by default, a
host-speed guess that the project's deadline policy does not see. Under
hosted-CI load, kunaProjectConcurrency failed that way twice on unrelated
PRs. Another 256 waits relied on the default, and 97 passed literals
picked to fit some host.
Waits now take as long as their test may run, less the reporting reserve
that children already keep. Each Vitest project sets expect.poll's
default, and the new waitFor in tests/support/testWait.ts replaces
vi.waitFor. Fixture readiness waits (awaitAcknowledgement and the provider
process waits) default to the same deadline, and their host-speed literal
arguments are removed. One remainingTestDeadline owns the arithmetic for
both children and waits.
Ten waits whose short timeout was the real check now assert it directly
(Kuna version probe, Cutter discovery, doctor and Inspector cancellation,
apktool fixture teardown, JADX disconnect): settlement before the
production deadline that would otherwise also satisfy the wait, or a
deadline pinned beyond every test deadline.
The rea/project-wait-deadline lint rule rejects vi.waitFor and explicit
expect.poll timeouts. The testing guide and the CI tests audit skill now
document the policy.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
`isHostFile` folded every stat failure into "not a file", so a library
candidate under a denied directory became a missing library, and an
unprobeable apt release file or package file read as absent.
`probeHostFile` reports ENOENT/ENOTDIR as absent and every other
failure as unknown. Apt release discovery, the package-file check and
the library walk keep those unknowns: a candidate under a directory the
linker cannot search (EACCES) is kept as a last resort and reported
unreadable rather than missing. Any other failure keeps its search
position, since glibc's open_path continues only past ENOENT and EACCES.
Fixes#9703
Squashed from #9722 and rebased onto main. Adapted on rebase: only
EACCES counts as searched past (checked on glibc 2.36, where a looping
symlink candidate ends the search), the probe reuses the domain
LibraryFileProbe type, and a stray comment is dropped.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
The appended-signature magic `~Module signature appended~\n` is 28
bytes, matching src/domain/native/kernelModule.ts.
Fixes#7324
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The guide listed three `.gnu.linkonce.this_module` statuses, but the
parser and the domain schema also return `unsupported` when the section
is stored SHF_COMPRESSED. Add that status with its condition.
The guide also presented `signature_trailer_truncated` as the result for
an appended magic with fewer than 12 preceding bytes. That branch needs
a file shorter than 40 bytes, and ELF admission requires at least 52
(ELF32) or 64 (ELF64) bytes, so the supported inspection never returns
it. State that the reason is reserved and unreachable for admitted files
without changing the parser or the schema enum.
Fixes#7669Fixes#7670
Supersedes #7758
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The retained-reference example wrote the Evidence id as "ev:<digest>".
Retained ids are "ev_" followed by the digest (prefixedDigestSchema in
src/domain/digests.ts), and inspect_analysis_view rejects the colon form
with invalid_format. Use the same "ev_<digest>" placeholder as the other
guides.
Fixes#7612
Supersedes #7760
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The testing guides stated lane and shard counts in prose. The counts drifted
when the workflow changed: "all eight fast built shards" survived the move to
twelve, "Eight Linux real-system lanes" now covers twelve workflow calls, and
the SQLite guide named a Node 24.15.0 lane that the matrix no longer runs.
Describe each set by its selector and point at the workflow that owns the
exact versions, so later workflow changes cannot make the text wrong.
Fixes#7616Fixes#7617
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor: prune internal seams and preserve configuration ownership
* fix(setup): keep YAML aliases and inherited registration settings on refresh
- Reuse an unchanged YAML collection only while every alias in it still
resolves after the edit; otherwise rebuild it so the alias becomes its
value. A sibling anchor replaced or moved in the same refresh no longer
leaves an unresolved alias in Hermes or Goose output.
- Keep a connection selector whose existing value already chooses stdio
(for example an inherited Hermes transport: stdio) instead of superseding
it; remote selectors are still replaced. Explicit stdio selectors are
therefore no longer rewritten (Kimi expectation updated).
- When the whole Hermes registration is inherited through a merge,
override it with that merge and write only the changed fields.
* fix(setup): edit registration fields whose YAML key is an alias
A key written as an alias to a string scalar (for example *field with
field: &field env) was treated as a source-only key, so any change to
its value was refused in Hermes and Goose. Resolve such keys to their
string, keep the aliased spelling while its anchor survives the edit,
and write the plain key when the same edit rebuilds the anchor.
* test(process): bound cleanup-boundary waits and always release gates
Both cancellation tests awaited a bare started promise and released
their gates only on success, so a missed boundary waited for the outer
deadline and could leave cleanup parked. Use awaitAcknowledgement and
release and join the cleanup in finally.
* fix(setup): repair only aliases an edit leaves unresolved
Replace the pre-edit alias survival guess, which expanded aliases to
sibling anchors that survive unchanged, with an exact repair: record
what each alias in the replaced value resolves to, write the edit, then
replace only aliases left without a preceding anchor by that value.
- Keep an aliased key's source position, so its anchor stays ahead of
later aliases.
- Treat an aliased key as its string only when no other key in the map
resolves to the same string; an ambiguous one stays guarded.
- Override an inherited Hermes registration only when the requested
entry keeps every inherited field, so an explicit replacement can drop
remote selectors.
* fix(setup): repair aliases whose binding an edit changes, keeping comments
An alias whose own anchor was removed could resolve to an earlier anchor
with the same name and silently change value. Record the node each alias
resolved to and repair any alias that no longer resolves to that node.
Carry the alias's comments and spacing onto the repaired value.
* test(setup): split the Hermes anchor and merge refresh cases
* fix(setup): refuse removing an overridden key its merge would restore
The merge-retention check skipped keys the mapping also overrides, so
dropping such a key (for example a remote url during an explicit stdio
replacement) let the retained merge restore it. Check removal before
skipping overridden keys, so the edit is refused with the existing
message instead of producing a registration that cannot be applied.
* fix(ghidra): prevent loader relocations from constant folding
Ghidra imports loader relocation destinations with their file bytes. A
destination in a non-writable loaded block can be populated by the
runtime loader instead, for example a copy-relocated musl `stderr` in
RELRO, so the decompiler folded the on-disk zero and showed
`fprintf(NULL, ...)`.
Before initializing the decompiler, mark each loaded, initialized,
non-writable block containing a relocation destination volatile in the
ephemeral database, and add a limitation to procedures that read such a
destination. ELF shared objects and PIEs are included; relocatable
objects and core files are not. Permissions and source FileBytes are
unchanged.
Sessions without database-mutation authority (Windows P0 and existing
caller projects) record the limitation but do not mark blocks volatile,
and the analysis profile versions the two behaviors separately.
A real Linux Ghidra ELF probe runs in the Ghidra bridge CI lane.
Fixes#4177
Squashed from #4198 and rebased onto main. Rebase adaptations: the
read-only gate, the verifier renamed to verify-ghidra-loader-relocation
so it stays out of the manual-verifier glob, docs moved to
docs/testing-lanes.md and docs/providers/ghidra-provider.md.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ghidra): await installation inspection in the relocation verifier
inspectGhidraInstallation became async on main after #4198's base, so the
verifier asserted on a pending Promise. Also wait for provider output to
close before reading it, like the sibling Ghidra verifiers, and keep the
workflow reference inside the docs site.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ghidra): address relocation review findings
- Version the existing-project analysis profile with the read-only
relocation semantics, since those sessions now add the limitation.
- Inspect the installation through the verifier helper that owns the
file-reader resources.
- Build the fixture with -fPIC: with -fPIE, GCC 12 emits a copy
relocation of rea_external_value into writable .bss, so the probe's
GOT check could not hold.
- Run probe cleanup through withVerifierCleanup so a cleanup failure
does not hide the probe failure, and keep the workspace when owned
Ghidra cleanup is incomplete.
- Link the workflow with a full GitHub URL, per the docs guide.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(ghidra): reach the external data through the GOT with a weak extern
Building the whole fixture with -fPIC also turned the reader's direct
load of rea_loader_pointer into a GOT-relaxed lea plus two loads, and
the real-Ghidra lane then reported that the baseline no longer folds
the file constant. Keep -fPIE and declare only rea_external_value weak:
GCC and clang must reach a possibly absent symbol through a GOT entry,
which lands as R_X86_64_GLOB_DAT inside GNU_RELRO (checked with readelf
for GCC 12.2 and clang/lld).
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ghidra): protect only relocations Ghidra could not apply
Running the real-Ghidra lane locally (Ghidra 12.1.4, JDK 21, GCC 12)
showed that marking every non-writable block that holds a relocation
volatile also marks full-RELRO .got. External calls then decompile as
opaque pointer calls (`(*pcVar2)(param_1)` through
`PTR_rea_external_...` instead of `rea_external(param_1)`), which the
probe's GOT-stability check caught.
Ghidra applies GLOB_DAT and RELATIVE relocations, so those bytes already
hold the loader's value and folding them is correct. The #4177 case is
a copy relocation, which Ghidra imports as UNSUPPORTED with the file's
zero in place. Protect only destinations whose relocation status is not
APPLIED or APPLIED_OTHER.
The fixture now reads a provider `const` object that the linker copies
into .data.rel.ro, the #4177 shape. The probe requires that relocation
to be unapplied and requires applied GOT relocations to stay
non-volatile. Ghidra 12.1.4 already shows this x86-64 read by name
without protection, so the probe records whether the baseline folds and
compares before and after only when it does. The profile value becomes
volatile-unapplied-relocation-blocks-v1.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Arslan Basharat <arslanbasharat414@gmail.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Across 29 successful runs, the slowest of eight shards ran 24% above the
mean shard (797 s against 646 s), with no shard index consistently slow:
duration-balanced shards still vary with hosted runner speed. Resampling
the observed per-shard speed factors predicts the slowest of twelve
shards at about 9.2 minutes instead of 13.2, for roughly 5% more runner
time.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(process)!: retain observed cleanup intervention
Process capture derived `settlement.cleanup_outcome` from the settlement
state alone in three places, so a quiesced capture reported
`not_required` even after final owned-process cleanup SIGKILLed a live
token-owned descendant. `cleanupOwnedProcessGroup` already knew it had
signaled, but the capture lifecycle discarded that fact.
Carry the observed signal out of ownership cleanup (also on failure
paths), accumulate it across cleanup retries as true/false/unknown, and
derive settlement and the intervention residual unknown once in
`processCaptureCleanupFacts` for full, partial and harness results.
BREAKING CHANGE: a quiesced settlement may now report
`cleanup_outcome: "cleaned"`. Saved captures stay valid; readers that
accepted only `not_required` for quiesced settlements must accept
`cleaned`.
Fixes#8032
Squashed from #8043 and rebased onto main (adapted to the resource-scope
release API and the inspection-failure cleanup path).
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(process): keep a sent signal when cleanup throws an inspection failure
Final ownership verification can rethrow a typed inspection failure (for
example cancellation) after SIGKILL succeeded. The capture owner then
recorded the attempt as unknown and dropped the intervention fact.
cleanupOwnedProcessGroup now marks a failure it throws after signaling,
without changing the failure's identity, and the capture owner keeps
the signal for such failures.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: wunianze666-netizen <wunianze666@gmail.com>
Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(cli): run one-shot commands through one shared owner
scripts/rea.mjs and the test CLI session worker each implemented the
one-shot command sequence: argument normalization, output admission,
configuration errors, version documents, the Amp scope refusal, and
result delivery. The worker copy had drifted: it never rendered
formatted version reports or the Amp refusal.
Move the sequence into src/cliOneShot.ts. Both callers supply a host
for their streams, exit and resource ownership. The launcher keeps
closed-pipe status, worker shutdown and process exit; the session
worker captures output per command.
The cliOutput bundle entry is superseded and removed. The dispatcher
test now replaces only the command runtime, so output admission runs
production code. A new parity test compares the file session with a
fresh process.
* test(cli): bundle the one-shot entry in the runtime bundle fixture
* perf(tests): run plain CLI commands on the file's shared process
`cli.run` in `cliTest` files started a fresh compiled CLI for every
command, about 0.45s and 260 MB each before any work. The file-scoped
session already existed, but callers had to opt in through
`runFileCli` or `sharedCliRun`, so 1,300 call sites still spawned.
Make the fixture choose: `cli.run` uses the shared process when it
reports the command exactly as a fresh process would, and starts one
otherwise (stdin, explicit deadlines, MCP and MCP doctor routing,
NODE_OPTIONS, or enabled logging). `freshProcess: true` keeps
explicit process-level checks. The session worker now presents the
launcher's entrypoint, so registration identity matches a fresh
process.
`runFileCli` and `sharedCliRun` are superseded and removed; their
call sites use `cli.run`, and paired fresh/shared checks use
`freshProcess`.
* style(tests): format the managed member summary call site
* test(cli): give each shared-session command an empty stdin
The shared CLI process reads session frames from its own stdin. A
command that reads stdin without supplied input, such as
`compare-wasm-interfaces - --json`, read that pipe and hung, where a
fresh process receives EOF. The worker now presents an ended, empty
stdin to each command and restores its own afterwards.
The parity test compared the routed path with itself after cli.run
began choosing the session. It now compares a fresh process with the
session directly, including the `mcp add` refusal and a command
reading absent stdin.
* test(cli): keep default command logging and launcher checks on fresh processes
environment-serve and environment-build log at info when REA_LOG_LEVEL is
unset, through a logger that writes to stderr directly. The shared CLI
process captures only process.stderr writes, so routed runs lost those
lines. Declare the default-logging commands beside the command names,
have infoLogger read that set, and start a fresh process for them.
The log-level precedence checks compared the shared process with itself
after routing; their fresh side now passes freshProcess: true.
Registries created directly with createTestProcessRegistry did not get the
processTest default, so a hung child there had no deadline once its explicit
value was removed; Vitest's test timeout does not settle the awaited run, so
shutdown was never reached. Derive the default in the registry from the
running test instead, using the real clock.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A processTest child run without its own timeoutMs now gets the test's
remaining deadline less a reporting reserve (at least 5 seconds, or a
tenth of the deadline). A hung child still fails with its captured output,
without a fixed per-call value that assumes a host's speed.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Antigravity keeps its MCP configuration and skills under
~/.gemini/config, and Gemini CLI was detected by the bare ~/.gemini
directory. Setting up Antigravity therefore made broad setup select
Gemini CLI and write a registration nobody asked for.
Gemini CLI's applicability now follows its own evidence: settings.json,
its trusted-folder records (honoring GEMINI_CLI_TRUSTED_FOLDERS_PATH) and
its .gemini/tmp session state, through the existing discoveryPaths
owner that detection, status and uninstall share. Selecting
--client gemini_cli explicitly is unchanged.
Fixes#7567
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The owned transport is the doctor's only cleanup owner, and Client.close
only delegates to it. Close it once and report its typed failure instead
of aggregating a duplicate SDK close and clearing that failure after a
retry. Pass the filtered caller environment as the launcher's base only,
and name the doctor operation in transport cleanup errors.
Cover a descendant in its own session, which only the token sweep can
reach, and a late cleanup denial that keeps the startup diagnostic and
reports the retained run. Bound the fixture descendant's lifetime so a
failing run cannot leak it. Document the doctor's process-family
ownership and output bound.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A terminal call on one branch does not end the whole function: other
branches can still reach the following code, which stays in the body and
pseudocode. The function-level limitation now says Ghidra excluded that
call's fall-through and that code reachable only through it is missing
if the callee returns. It is listed before the call-specific facts so a
bounded composed summary that admits limitations in order keeps it.
The body-coverage tests now check the counted records and their reasons
instead of freezing the explanatory sentence.
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ghidra's Non-Returning Functions - Discovered analyzer can mark a
returning callee, such as an imported operator new thunk, as
non-returning. Ghidra then clears the fallthrough at each call site and
refits the callers, so a constructor decompiles to a few plausible
lines. REA reported the terminal call with the FunctionManager flag but
did not say the result omits the code after it or how to compare.
That analyzer bookmarks each entry it marks with the Analysis comment
"Non-Returning Function Found" (Ghidra 11.0 through 12.1.4 source); the
name-list Known analyzer writes "Non-Returning Function Identified".
When a terminal call's callee, or the function a thunk forwards to,
carries the Discovered bookmark, the call's limitation now says the
flag was inferred, and the function adds one address-free limitation
that its body and pseudocode end at that call and omit the following
code if the callee returns, with the REA_GHIDRA_DISABLED_ANALYZERS
comparison. A flag without the bookmark keeps an unknown origin.
The function-boundary observation contract moves to v5 so snapshots
from earlier bridges are not replayed without the qualification.
Refs #10365
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
decompile_all set its top-level "procedure_info is unavailable" caveat
from a per-call flag that only a newly attempted function could raise.
A resume that skipped every verified file, or selected nothing, rewrote
the manifest and decompile-index.json with an empty limitations list
while every retained record still reported an unavailable body.
The export owner now answers from the records it retains: the summary
counts every non-external record whose body is unavailable, including
records an earlier run wrote, and repeats the reason when all share one.
The per-call flag is removed. A fresh export whose procedure_info works
but leaves some bodies unavailable now reports that caveat too; a later
attempt that records a known body clears it.
Fixes#8351
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(ci): move dated shard measurements into a verification record
The testing guide and testing-lanes guide mixed the October 2026 shard
budget and stale-history measurements into current rules. Move them to
docs/verification/ci-shard-scheduling-2026-10-20.md and link it from
the rules they justify.
* docs(ci): drop dated shard measurements instead of keeping a record
After REA stopped a Rizin debug session (frame or output limit, deadline,
cancellation, protocol failure) or the debugger exited, later commands
returned a generic invalid_request and status gave no reason. GDB
collapsed the same states the same way.
Both managers now keep a published session addressable until
close_*_session releases it, record the first reason it stopped, report
it as closed_reason in session status, and refuse later commands with
capability_unavailable naming that reason and the close-then-restart
recovery. An ID the server never returned, or that close released, still
fails as invalid_request with its own recovery. Retained stopped
sessions keep their slot, which the capacity recovery now says. A GDB
command deadline now records its reason like cancellation already did.
Fixes#8024
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rizin exits 0 when its shell refuses a statement, so execute_rizin_command
reported completion_status complete with exit code 0 and an empty stdout
that read as a genuine empty result.
Rizin 0.6 through 0.9.1 log exactly four refusal lines from
librz/core/cmd/cmd.c: an unknown command, a wrong argument count, an
invalid statement (RZ_CMD_STATUS_INVALID, which also stops the remaining
statements) and a parse error. The Rizin command profile now classifies a
completed process's stderr against those lines; the shared one-shot
service reports completion_status "rejected" and a limitation that names
the refusal and says stdout holds only earlier statements' output. Other
ERROR lines come from commands that ran and stay diagnostics.
Fixes#10364
Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Probes in a source and a built project read each collected test's
deadline, including test, suite, and module long-running tags, so a
change in project inheritance or tag resolution fails directly. Both
the policy and the probes read one set of base deadlines.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Source projects allow 30 seconds and built projects 120 seconds, both
doubled under coverage, and hooks share their project's deadline instead
of Vitest's 10-second default. A long-running tag covers bounded
workloads that need more.
Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>